aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ip.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-06-29 19:59:08 +0000
committerMichael Mann <mmann78@netscape.net>2013-06-29 19:59:08 +0000
commite5af2f55ee08b521dee843fa2e030714045ce061 (patch)
tree7a840aeeff0ffb89b11a2cf20881748a773e10e6 /epan/dissectors/packet-ip.c
parent04f8906be3d59cf3c33c0302adfef8bd184abb99 (diff)
Separate IP option header fields for each dissector that uses dissect_ip_tcp_options(). Bug 8823 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8823)
svn path=/trunk/; revision=50230
Diffstat (limited to 'epan/dissectors/packet-ip.c')
-rw-r--r--epan/dissectors/packet-ip.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 845b62e7bf..0eeef31f9c 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -360,17 +360,13 @@ static dissector_handle_t tapa_handle;
#define IPTOS_PREC_ROUTINE 0
/* IP options */
-#define IPOPT_COPY_MASK 0x80
#define IPOPT_COPY 0x80
-#define IPOPT_CLASS_MASK 0x60
#define IPOPT_CONTROL 0x00
#define IPOPT_RESERVED1 0x20
#define IPOPT_MEASUREMENT 0x40
#define IPOPT_RESERVED2 0x60
-#define IPOPT_NUMBER_MASK 0x1F
-
/* REF: http://www.iana.org/assignments/ip-parameters */
/* TODO: Not all of these are implemented. */
#define IPOPT_EOOL (0 |IPOPT_CONTROL)
@@ -623,7 +619,7 @@ add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, guint32 src32,
}
#endif /* HAVE_GEOIP */
-static const value_string ipopt_type_class_vals[] = {
+const value_string ipopt_type_class_vals[] = {
{(IPOPT_CONTROL & IPOPT_CLASS_MASK) >> 5, "Control"},
{(IPOPT_RESERVED1 & IPOPT_CLASS_MASK) >> 5, "Reserved for future use"},
{(IPOPT_MEASUREMENT & IPOPT_CLASS_MASK) >> 5, "Debugging and measurement"},
@@ -631,7 +627,7 @@ static const value_string ipopt_type_class_vals[] = {
{0, NULL}
};
-static const value_string ipopt_type_number_vals[] = {
+const value_string ipopt_type_number_vals[] = {
{IPOPT_EOOL & IPOPT_NUMBER_MASK, "End of Option List (EOL)"},
{IPOPT_NOP & IPOPT_NUMBER_MASK, "No-Operation (NOP)"},
{IPOPT_SEC & IPOPT_NUMBER_MASK, "Security"},
@@ -662,17 +658,20 @@ static const value_string ipopt_type_number_vals[] = {
{0, NULL}
};
+static ip_tcp_opt_type IP_OPT_TYPES = {&hf_ip_opt_type, &ett_ip_opt_type,
+ &hf_ip_opt_type_copy, &hf_ip_opt_type_class, &hf_ip_opt_type_number};
+
static void
-dissect_ipopt_type(tvbuff_t *tvb, int offset, proto_tree *tree)
+dissect_ipopt_type(tvbuff_t *tvb, int offset, proto_tree *tree, ip_tcp_opt_type* opttypes)
{
proto_tree *type_tree;
proto_item *ti;
- ti = proto_tree_add_item(tree, hf_ip_opt_type, tvb, offset, 1, ENC_NA);
- type_tree = proto_item_add_subtree(ti, ett_ip_opt_type);
- proto_tree_add_item(type_tree, hf_ip_opt_type_copy, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(type_tree, hf_ip_opt_type_class, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(type_tree, hf_ip_opt_type_number, tvb, offset, 1, ENC_NA);
+ ti = proto_tree_add_item(tree, *opttypes->phf_opt_type, tvb, offset, 1, ENC_NA);
+ type_tree = proto_item_add_subtree(ti, *opttypes->pett_opt_type);
+ proto_tree_add_item(type_tree, *opttypes->phf_opt_type_copy, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(type_tree, *opttypes->phf_opt_type_class, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(type_tree, *opttypes->phf_opt_type_number, tvb, offset, 1, ENC_NA);
}
static void
@@ -685,7 +684,7 @@ dissect_ipopt_eool(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", optp->name);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
}
#define dissect_ipopt_nop dissect_ipopt_eool
@@ -762,7 +761,7 @@ dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, curr_offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, curr_offset, field_tree);
+ dissect_ipopt_type(tvb, curr_offset, field_tree, &IP_OPT_TYPES);
curr_offset++;
tf_sub = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, curr_offset, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
@@ -831,7 +830,7 @@ dissect_ipopt_ext_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, curr_offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, curr_offset, field_tree);
+ dissect_ipopt_type(tvb, curr_offset, field_tree, &IP_OPT_TYPES);
curr_offset++;
tf_sub = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, curr_offset, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
@@ -869,7 +868,7 @@ dissect_ipopt_cipso(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1130,7 +1129,7 @@ dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1210,7 +1209,7 @@ dissect_ipopt_record_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1269,7 +1268,7 @@ dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes): %u",
optp->name, optlen, tvb_get_ntohs(tvb, offset + 2));
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen != (guint)optp->optlen)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1288,7 +1287,7 @@ dissect_ipopt_mtu(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes): %u",
optp->name, optlen, tvb_get_ntohs(tvb, offset + 2));
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen != (guint)optp->optlen)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1307,7 +1306,7 @@ dissect_ipopt_tr(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen != (guint)optp->optlen)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1339,7 +1338,7 @@ dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1416,7 +1415,7 @@ dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
rval_to_str(value, ra_rvals, "Unknown (%u)"),
value);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen != (guint)optp->optlen)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1435,7 +1434,7 @@ dissect_ipopt_sdb(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
optp->name, optlen);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen > IPOLEN_MAX)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1492,7 +1491,7 @@ dissect_ipopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
val_to_str(function, qs_func_vals, "Unknown (%u)"),
function);
field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
ti = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
if (optlen != (guint)optp->optlen)
expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
@@ -1594,7 +1593,7 @@ static const ip_tcp_opt ipopts[] = {
* options in a packet. */
void
dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
- const ip_tcp_opt *opttab, int nopts, int eol,
+ const ip_tcp_opt *opttab, int nopts, int eol, ip_tcp_opt_type* opttypes,
packet_info *pinfo, proto_tree *opt_tree,
proto_item *opt_item, void * data)
{
@@ -1698,7 +1697,7 @@ dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
name);
tf = proto_tree_add_text(opt_tree, tvb, offset, len, "%s", name);
field_tree = proto_item_add_subtree(tf, ett_ip_option_other);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, opttypes);
}
}
len -= 2; /* subtract size of type and length */
@@ -1718,7 +1717,7 @@ dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s", name);
tf = proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
field_tree = proto_item_add_subtree(tf, ett_ip_option_other);
- dissect_ipopt_type(tvb, offset, field_tree);
+ dissect_ipopt_type(tvb, offset, field_tree, opttypes);
}
offset += 1;
@@ -2317,7 +2316,7 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
"Options: (%u bytes)", optlen);
field_tree = proto_item_add_subtree(tf, ett_ip_options);
dissect_ip_tcp_options(tvb, offset + 20, optlen, ipopts, N_IP_OPTS,
- IPOPT_EOOL, pinfo, field_tree, tf, NULL);
+ IPOPT_EOOL, &IP_OPT_TYPES, pinfo, field_tree, tf, NULL);
}
pinfo->ipproto = iph->ip_p;