summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-netflow.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2009-07-10 23:39:23 +0000
committerGerald Combs <gerald@wireshark.org>2009-07-10 23:39:23 +0000
commit16c1dd1b2d9df558e86af49ea9be3d927fa6333c (patch)
tree3fbe1ddc45e8d9fd1b6d2bd3d32548cc015dfa75 /epan/dissectors/packet-netflow.c
parent24d2fb512694ceeb9bee5b7d57ad3547d7f67240 (diff)
downloadwireshark-16c1dd1b2d9df558e86af49ea9be3d927fa6333c.tar.gz
Don't use tvb_memcpy to fill in a struct. (Cue Jamie Hyneman saying
"EVER!") Expand the entry/scope struct to include private enterprise numbers instead of casting guint32s to arbritrary chunks of memory. Limit the number of entries and scopes we allocate. Don't allocate memory every time we see a new template. Don't use a C++ keyword for variable names. svn path=/trunk/; revision=29061
Diffstat (limited to 'epan/dissectors/packet-netflow.c')
-rw-r--r--epan/dissectors/packet-netflow.c311
1 files changed, 159 insertions, 152 deletions
diff --git a/epan/dissectors/packet-netflow.c b/epan/dissectors/packet-netflow.c
index 0acce92a9e..c4b69d907b 100644
--- a/epan/dissectors/packet-netflow.c
+++ b/epan/dissectors/packet-netflow.c
@@ -161,16 +161,19 @@ static const value_string v8_agg[] = {
/* Version 9 template cache structures */
#define V9TEMPLATE_CACHE_MAX_ENTRIES 100
+/* Max number of entries/scopes per template */
+#define V9TEMPLATE_MAX_FIELDS 20
struct v9_template_entry {
guint16 type;
guint length;
+ guint32 pen;
};
struct v9_template {
+ guint length;
guint16 id;
guint16 count;
- guint length;
guint32 source_id;
address source_addr;
gboolean option_template; /* FALSE=data template, TRUE=option template */
@@ -493,14 +496,13 @@ static int dissect_v9_flowset(tvbuff_t * tvb, packet_info * pinfo, proto_tree *
static int dissect_v9_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree,
int offset, guint16 id, guint length, hdrinfo_t * hdrinfo);
static guint dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree,
- int offset, struct v9_template * template);
+ int offset, struct v9_template * tplt);
static int dissect_v9_options_template(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree,
int offset, hdrinfo_t *hdrinfo, guint16 flowset_id);
-static int dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb,
+static int dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, packet_info *pinfo,
int offset, int len, hdrinfo_t * hdrinfo);
static int v9_template_hash(guint16 id, const address * net_src,
guint32 src_id);
-static void v9_template_add(struct v9_template * template);
static struct v9_template *v9_template_get(guint16 id, address * net_src,
guint32 src_id);
static const char * decode_v9_template_types(int type);
@@ -1140,25 +1142,31 @@ dissect_v9_flowset(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, in
return (0);
flowset_id = tvb_get_ntohs(tvb, offset);
+ length = tvb_get_ntohs(tvb, offset + 2);
+
+ if (length < 4) {
+ expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN,
+ "Length (%u) too short", length);
+ return tvb_length_remaining(tvb, offset);
+ }
+
if ((flowset_id == 0) || (flowset_id == 2)) {
/* Template */
proto_tree_add_item(pdutree, hf_cflow_template_flowset_id, tvb,
- offset, 2, FALSE);
+ offset, 2, FALSE);
offset += 2;
- length = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
- offset, 2, FALSE);
+ offset, 2, FALSE);
offset += 2;
- dissect_v9_template(pdutree, tvb, offset, length - 4, hdrinfo);
+ dissect_v9_template(pdutree, tvb, pinfo, offset, length - 4, hdrinfo);
} else if ((flowset_id == 1) || (flowset_id == 3)) {
/* Option Template */
proto_tree_add_item(pdutree, hf_cflow_options_flowset_id, tvb,
offset, 2, FALSE);
offset += 2;
- length = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
offset, 2, FALSE);
offset += 2;
@@ -1170,7 +1178,6 @@ dissect_v9_flowset(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, in
offset, 2, FALSE);
offset += 2;
- length = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
offset, 2, FALSE);
offset += 2;
@@ -1180,20 +1187,12 @@ dissect_v9_flowset(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, in
offset, 2, FALSE);
offset += 2;
- length = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, (ver == 9) ? hf_cflow_flowset_length : hf_cflow_datarecord_length, tvb,
offset, 2, FALSE);
offset += 2;
- /*
- * The length includes the length of the FlowSet ID and
- * the length field itself.
- */
- length -= 4;
- if (length > 0) {
- dissect_v9_data(tvb, pinfo, pdutree, offset, flowset_id,
- (guint)length, hdrinfo);
- }
+ dissect_v9_data(tvb, pinfo, pdutree, offset, flowset_id,
+ (guint)length - 4, hdrinfo);
}
return (length);
@@ -1203,24 +1202,24 @@ static int
dissect_v9_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int offset,
guint16 id, guint length, hdrinfo_t * hdrinfo)
{
- struct v9_template *template;
+ struct v9_template *tplt;
proto_tree *data_tree;
proto_item *data_item;
guint pdu_len;
- template = v9_template_get(id, &hdrinfo->net_src, hdrinfo->src_id);
- if (template != NULL && template->length != 0) {
+ tplt = v9_template_get(id, &hdrinfo->net_src, hdrinfo->src_id);
+ if (tplt != NULL && tplt->length != 0) {
int count = 1;
- while (length >= template->length) {
+ while (length >= tplt->length) {
data_item = proto_tree_add_text(pdutree, tvb,
- offset, template->length, "Flow %d", count++);
+ offset, tplt->length, "Flow %d", count++);
data_tree = proto_item_add_subtree(data_item,
ett_dataflowset);
- pdu_len = dissect_v9_pdu(tvb, pinfo, data_tree, offset, template);
+ pdu_len = dissect_v9_pdu(tvb, pinfo, data_tree, offset, tplt);
- offset += template->length;
+ offset += tplt->length;
/* XXX - Throw an exception */
length -= pdu_len < length ? pdu_len : length;
}
@@ -1263,7 +1262,7 @@ dissect_v9_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int o
static guint
dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int offset,
- struct v9_template * template)
+ struct v9_template * tplt)
{
int orig_offset = offset;
int i;
@@ -1275,7 +1274,6 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
guint32 msec_delta;
proto_tree * timetree = 0;
proto_item * timeitem = 0;
- guint16 pen_count = 0;
address local_addr, remote_addr;
guint16 local_port = 0, remote_port = 0, ipv4_id = 0, icmp_id = 0;
guint32 uid = 0, pid = 0;
@@ -1284,33 +1282,30 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
int cmd_len;
gchar * cmd_str = NULL;
guint16 got_flags = 0;
+ proto_item * ti;
offset_s[0] = offset_s[1] = offset_e[0] = offset_e[1] = 0;
msec_start[0] = msec_start[1] = msec_end[0] = msec_end[1] = 0;
- if( (template->count_scopes > 0) && (template->scopes != NULL)) {
- for(i = 0; i < template->count_scopes; i++) {
- guint16 type = template->scopes[i].type;
- guint16 length = template->scopes[i].length;
+ if(tplt->scopes != NULL) {
+ for(i = 0; i < tplt->count_scopes; i++) {
+ guint16 type = tplt->scopes[i].type;
+ guint16 length = tplt->scopes[i].length;
switch( type ) {
case 1: /* system */
- if( length == 4) {
- proto_tree_add_item(pdutree, hf_cflow_scope_system,
- tvb, offset, length, FALSE);
- } else if (length > 0) {
- proto_tree_add_text(pdutree,
- tvb, offset, length,
- "ScopeSystem: invalid size %d", length );
+ ti = proto_tree_add_item(pdutree, hf_cflow_scope_system,
+ tvb, offset, length, FALSE);
+ if (length > 0 && length != 4) {
+ expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN,
+ "ScopeSystem: invalid size %u", length);
} /* zero-length system scope is valid */
break;
case 2: /* interface */
- if( length == 4) {
- proto_tree_add_item(pdutree, hf_cflow_scope_interface,
- tvb, offset, length, FALSE);
- } else {
- proto_tree_add_text(pdutree,
- tvb, offset, length,
- "ScopeInterface: invalid size %d", length );
+ ti = proto_tree_add_item(pdutree, hf_cflow_scope_interface,
+ tvb, offset, length, FALSE);
+ if (length != 4) {
+ expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN,
+ "ScopeInterface: invalid size %u", length);
}
break;
case 3: /* linecard */
@@ -1321,7 +1316,7 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
proto_tree_add_item(pdutree, hf_cflow_scope_cache,
tvb, offset, length, FALSE);
break;
- case 5: /* template */
+ case 5: /* tplt */
proto_tree_add_item(pdutree, hf_cflow_scope_template,
tvb, offset, length, FALSE);
break;
@@ -1334,17 +1329,16 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
}
}
- for (i = 0; i < template->count; i++) {
+ for (i = 0; i < tplt->count; i++) {
guint64 pen_type;
guint16 type, length;
guint32 pen = 0;
rev = 0;
- type = template->entries[i + pen_count].type;
- length = template->entries[i + pen_count].length;
+ type = tplt->entries[i].type;
+ length = tplt->entries[i].length;
if (type & 0x8000) {
- pen_count++;
- pen = *(guint32 *)&template->entries[i + pen_count];
+ pen = tplt->entries[i].pen;
if (pen == REVPEN) { /* reverse PEN */
type &= 0x7fff;
rev = 1;
@@ -2693,10 +2687,10 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
}
/* XXX - These IDs are currently hard-coded in procflow.py. */
- if (got_flags == GOT_TCP_UDP && (template->id == 256 || template->id == 258)) {
+ if (got_flags == GOT_TCP_UDP && (tplt->id == 256 || tplt->id == 258)) {
add_tcp_process_info(pinfo->fd->num, &local_addr, &remote_addr, local_port, remote_port, uid, pid, uname_str, cmd_str);
}
- if (got_flags == GOT_TCP_UDP && (template->id == 257 || template->id == 259)) {
+ if (got_flags == GOT_TCP_UDP && (tplt->id == 257 || tplt->id == 259)) {
add_udp_process_info(pinfo->fd->num, &local_addr, &remote_addr, local_port, remote_port, uid, pid, uname_str, cmd_str);
}
@@ -2707,10 +2701,10 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
static int
dissect_v9_options_template(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree, int offset, hdrinfo_t *hdrinfo, guint16 flowset_id)
{
- guint16 option_scope_len, option_len, i, id, size;
- guint16 type, scope_pen_count = 0, pen_count = 0;
- struct v9_template template;
- int template_offset;
+ guint16 option_scope_len, option_len, i, id;
+ guint16 type;
+ struct v9_template tplt;
+ int tplt_offset;
int scopes_offset;
proto_item *ti;
@@ -2747,126 +2741,174 @@ dissect_v9_options_template(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutr
option_scope_len -= option_len;
}
+
+ if (option_len > V9TEMPLATE_MAX_FIELDS) {
+ expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
+ "More options (%u) than we can handle",
+ option_len);
+ }
+
+ if (option_scope_len > V9TEMPLATE_MAX_FIELDS) {
+ expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
+ "More scopes (%u) than we can handle",
+ option_scope_len);
+ }
scopes_offset = offset;
+ /* Cache template */
+ memset(&tplt, 0, sizeof(tplt));
+ tplt.id = id;
+ tplt.count = option_len;
+ SE_COPY_ADDRESS(&tplt.source_addr, &hdrinfo->net_src);
+ tplt.source_id = hdrinfo->src_id;
+ /* Option scopes */
+ tplt.option_template = TRUE; /* Option template */
+ tplt.count_scopes = option_scope_len;
+ if (v9_template_get(id, &hdrinfo->net_src, hdrinfo->src_id) && option_len && option_scope_len && option_len <= V9TEMPLATE_MAX_FIELDS && option_scope_len <= V9TEMPLATE_MAX_FIELDS) {
+ tplt.scopes = se_alloc0(option_scope_len * sizeof(struct v9_template_entry));
+ tplt.entries = se_alloc0(option_len * sizeof(struct v9_template_entry));
+ }
+
for(i=0; i<option_scope_len; i++) {
+ guint16 scope_length;
+
type = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, hf_cflow_template_scope_field_type, tvb,
offset, 2, FALSE);
offset += 2; i += 2;
+ scope_length = tvb_get_ntohs(tvb,offset);
+ if (tplt.scopes) {
+ tplt.scopes[i].type = type;
+ tplt.scopes[i].length = scope_length == VARIABLE_LENGTH ? 0 : scope_length;
+ tplt.length += tplt.scopes[i].length;
+ }
proto_tree_add_item(pdutree, hf_cflow_template_scope_field_length, tvb,
offset, 2, FALSE);
offset += 2; i += 2;
if (type & 0x8000) { /* Private Enterprise Number (IPFIX only) */
+ if (tplt.scopes) {
+ tplt.scopes[i].pen = tvb_get_ntohl(tvb,offset);
+ }
proto_tree_add_item(pdutree,
hf_cflow_template_field_pen, tvb, offset, 4, FALSE);
- scope_pen_count++;
offset += 4; i += 4;
}
}
- template_offset = offset;
+ tplt_offset = offset;
for(i=0; i<option_len;) {
+ guint16 entry_length;
+
type = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(pdutree, hf_cflow_template_field_type, tvb,
offset, 2, FALSE);
offset += 2; i += 2;
+ entry_length = tvb_get_ntohs(tvb, offset);
+ if (tplt.entries) {
+ tplt.entries[i].type = type;
+ tplt.entries[i].length = entry_length == VARIABLE_LENGTH ? 0 : entry_length;
+ tplt.length += tplt.entries[i].length;
+ }
proto_tree_add_item(pdutree, hf_cflow_template_field_length, tvb,
offset, 2, FALSE);
offset += 2; i += 2;
if (type & 0x8000) { /* Private Enterprise Number (IPFIX only) */
+ if (tplt.entries) {
+ tplt.entries[i].pen = tvb_get_ntohl(tvb,offset);
+ }
proto_tree_add_item(pdutree,
hf_cflow_template_field_pen, tvb, offset, 4, FALSE);
- pen_count++;
offset += 4; i += 4;
}
}
- /* Cache template */
- memset(&template, 0, sizeof(template));
- template.id = id;
- template.count = option_len;
- SE_COPY_ADDRESS(&template.source_addr, &hdrinfo->net_src);
- template.source_id = hdrinfo->src_id;
- /* Option scopes */
- template.count_scopes = option_scope_len;
- size = (template.count_scopes + scope_pen_count) * sizeof(struct v9_template_entry);
- template.scopes = se_alloc( size );
- tvb_memcpy(tvb, (guint8 *)template.scopes, scopes_offset, size);
-
- template.option_template = TRUE; /* Option template */
- size = (template.count + pen_count) * sizeof(struct v9_template_entry);
- template.entries = se_alloc(size);
- tvb_memcpy(tvb, (guint8 *)template.entries, template_offset, size);
-
- v9_template_add(&template);
+ if (tplt.scopes || tplt.entries) {
+ memcpy(&v9_template_cache[v9_template_hash(tplt.id,
+ &tplt.source_addr, tplt.source_id)],
+ &tplt, sizeof(tplt));
+ }
return (0);
}
static int
-dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, int offset, int len, hdrinfo_t * hdrinfo)
+dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, packet_info *pinfo, int offset, int length, hdrinfo_t * hdrinfo)
{
- struct v9_template template;
- proto_tree *template_tree;
- proto_item *template_item;
+ struct v9_template tplt;
+ proto_tree *tplt_tree;
+ proto_item *tplt_item;
proto_tree *field_tree;
- proto_item *field_item;
+ proto_item *field_item, *ti;
guint16 id, count;
- int remaining = len;
+ int remaining = length;
gint32 i;
- guint16 pen_count = 0;
int field_start_offset;
+ int orig_offset;
while (remaining > 0) {
+ orig_offset = offset;
id = tvb_get_ntohs(tvb, offset);
count = tvb_get_ntohs(tvb, offset + 2);
- template_item = proto_tree_add_text(pdutree, tvb, offset,
+ tplt_item = proto_tree_add_text(pdutree, tvb, offset,
4 + sizeof(struct v9_template_entry) * count,
"Template (Id = %u, Count = %u)", id, count);
- template_tree = proto_item_add_subtree(template_item, ett_template);
+ tplt_tree = proto_item_add_subtree(tplt_item, ett_template);
- proto_tree_add_item(template_tree, hf_cflow_template_id, tvb,
+ proto_tree_add_item(tplt_tree, hf_cflow_template_id, tvb,
offset, 2, FALSE);
offset += 2;
- proto_tree_add_item(template_tree, hf_cflow_template_field_count,
+ ti = proto_tree_add_item(tplt_tree, hf_cflow_template_field_count,
tvb, offset, 2, FALSE);
offset += 2;
+ if (count > V9TEMPLATE_MAX_FIELDS) {
+ expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE,
+ "More entries (%u) than we can handle",
+ count);
+ }
+
/* Cache template */
- memset(&template, 0, sizeof(template));
- template.id = id;
- template.count = count;
- SE_COPY_ADDRESS(&template.source_addr, &hdrinfo->net_src);
- template.source_id = hdrinfo->src_id;
- template.count_scopes = 0;
- template.scopes = NULL;
- template.option_template = FALSE; /* Data template */
+ memset(&tplt, 0, sizeof(tplt));
+ tplt.id = id;
+ tplt.count = count;
+ SE_COPY_ADDRESS(&tplt.source_addr, &hdrinfo->net_src);
+ tplt.source_id = hdrinfo->src_id;
field_start_offset = offset;
+ if (!v9_template_get(id, &hdrinfo->net_src, hdrinfo->src_id) && count && count <= V9TEMPLATE_MAX_FIELDS) {
+ tplt.entries = se_alloc0(count * sizeof(struct v9_template_entry));
+ }
- for (i = 1; i <= count; i++) {
- guint16 type, length;
- guint32 pen = 0;
+ for (i = 0; i < count; i++) {
+ guint16 type, entry_length;
+ guint32 pen;
- field_item = proto_tree_add_text(template_tree, tvb,
+ pen = 0;
+ field_item = proto_tree_add_text(tplt_tree, tvb,
offset, 4, "Field (%u/%u)", i, count);
field_tree = proto_item_add_subtree(field_item, ett_field);
type = tvb_get_ntohs(tvb, offset);
- length = tvb_get_ntohs(tvb, offset + 2);
+ entry_length = tvb_get_ntohs(tvb, offset + 2);
if (type & 0x8000) {
pen = tvb_get_ntohl(tvb, offset + 4);
}
+ if (tplt.entries) {
+ tplt.entries[i].type = type;
+ tplt.entries[i].length = entry_length == VARIABLE_LENGTH ? 0 : entry_length;
+ tplt.length += tplt.entries[i].length;
+ tplt.entries[i].pen = pen;
+ }
+
if ((type & 0x8000) && (pen != REVPEN)) { /* except reverse pen */
proto_tree_add_text(field_tree,
tvb, offset, 2,
@@ -2883,18 +2925,16 @@ dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, int offset, int len, h
if (type & 0x8000) { /* Private Enterprise Number (IPFIX only) */
proto_tree_add_item(field_tree,
hf_cflow_template_field_pen, tvb, offset, 4, FALSE);
- pen_count++;
offset += 4;
}
}
- template.entries = se_alloc((count + pen_count) * sizeof(struct v9_template_entry));
- tvb_memcpy(tvb, (guint8 *)template.entries, field_start_offset,
- (count + pen_count) * sizeof(struct v9_template_entry));
- v9_template_add(&template);
- remaining -= 4 + sizeof(struct v9_template_entry) * count;
- if (pen_count > 0) {
- remaining -= 4 * pen_count;
+
+ if (tplt.entries) {
+ memcpy(&v9_template_cache[v9_template_hash(tplt.id,
+ &tplt.source_addr, tplt.source_id)],
+ &tplt, sizeof(tplt));
}
+ remaining -= offset - orig_offset;
}
return (0);
@@ -3161,53 +3201,20 @@ v9_template_hash(guint16 id, const address * net_src, guint32 src_id)
return val % V9TEMPLATE_CACHE_MAX_ENTRIES;
}
-static void
-v9_template_add(struct v9_template *template)
-{
- int i;
- int pen_count = 0;
- guint tmp_length;
- /* Add up the actual length of the data and store in proper byte order */
- template->length = 0;
- /* Options scope */
- for(i = 0; i < template->count_scopes; i++) {
- template->scopes[i].type = g_ntohs(template->scopes[i].type);
- tmp_length = g_ntohs(template->scopes[i].length);
- template->scopes[i].length = tmp_length == VARIABLE_LENGTH ? 0 : tmp_length;
- template->length += template->scopes[i].length;
- }
-
- for (i = 0; i < template->count; i++) {
- template->entries[i + pen_count].type = g_ntohs(template->entries[i + pen_count].type);
- tmp_length = g_ntohs(template->entries[i + pen_count].length);
- template->entries[i + pen_count].length = tmp_length == VARIABLE_LENGTH ? 0 : tmp_length;
- template->length += template->entries[i + pen_count].length;
- if (template->entries[i + pen_count].type & 0x8000) {
- pen_count++;
- *(guint32 *)&template->entries[i + pen_count] =
- g_ntohl(*(guint32 *)&template->entries[i + pen_count]);
- }
- }
-
- memcpy(&v9_template_cache[v9_template_hash(template->id,
- &template->source_addr, template->source_id)],
- template, sizeof(*template));
-}
-
static struct v9_template *
v9_template_get(guint16 id, address * net_src, guint32 src_id)
{
- struct v9_template *template;
+ struct v9_template *tplt;
- template = &v9_template_cache[v9_template_hash(id, net_src, src_id)];
+ tplt = &v9_template_cache[v9_template_hash(id, net_src, src_id)];
- if (template->id != id ||
- !ADDRESSES_EQUAL(&template->source_addr, net_src) ||
- template->source_id != src_id) {
- template = NULL;
+ if (tplt->id != id ||
+ !ADDRESSES_EQUAL(&tplt->source_addr, net_src) ||
+ tplt->source_id != src_id) {
+ tplt = NULL;
}
- return (template);
+ return (tplt);
}
/*