/* packet-icmpv6.c
* Routines for ICMPv6 packet disassembly
*
- * $Id: packet-icmpv6.c,v 1.5 1999/07/28 02:14:14 gerald Exp $
+ * $Id: packet-icmpv6.c,v 1.14 2000/03/12 04:47:38 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#include "packet.h"
#include "packet-ipv6.h"
#include "resolv.h"
-#include "util.h"
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
#endif
+static int proto_icmpv6 = -1;
+static int hf_icmpv6_type = -1;
+static int hf_icmpv6_code = -1;
+static int hf_icmpv6_checksum = -1;
+
+static gint ett_icmpv6 = -1;
+static gint ett_icmpv6opt = -1;
+static gint ett_icmpv6flag = -1;
+
static void
dissect_icmpv6opt(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
return;
again:
- if (!(fd->cap_len > offset))
+ if (!IS_DATA_IN_FRAME(offset))
return;
opt = (struct nd_opt_hdr *)&pd[offset];
/* !!! specify length */
ti = proto_tree_add_text(tree, offset, len, "ICMPv6 options");
- icmp6opt_tree = proto_item_add_subtree(ti, ETT_ICMPv6OPT);
+ icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6opt);
switch (opt->nd_opt_type) {
case ND_OPT_SOURCE_LINKADDR:
flagoff = offsetof(struct nd_opt_prefix_info, nd_opt_pi_flags_reserved);
tf = proto_tree_add_text(icmp6opt_tree, flagoff, 1, "Flags: 0x%02x",
pntohl(&pi->nd_opt_pi_flags_reserved));
- field_tree = proto_item_add_subtree(tf, ETT_ICMPv6FLAG);
+ field_tree = proto_item_add_subtree(tf, ett_icmpv6flag);
proto_tree_add_text(field_tree, flagoff, 1, "%s",
decode_boolean_bitfield(pi->nd_opt_pi_flags_reserved,
0x80, 8, "Onlink", "Not onlink"));
codename = "Reassembly";
break;
}
+ break;
case ICMP6_PARAM_PROB:
typename = "Parameter problem";
switch (dp->icmp6_code) {
codename = "Option";
break;
}
+ break;
case ICMP6_ECHO_REQUEST:
typename = "Echo request";
codename = NULL;
if (tree) {
/* !!! specify length */
- ti = proto_tree_add_text(tree, offset, len,
- "ICMPv6");
- icmp6_tree = proto_item_add_subtree(ti, ETT_ICMPv6);
+ ti = proto_tree_add_item(tree, proto_icmpv6, offset, len, NULL);
+ icmp6_tree = proto_item_add_subtree(ti, ett_icmpv6);
- proto_tree_add_text(icmp6_tree,
+ proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_type,
offset + offsetof(struct icmp6_hdr, icmp6_type), 1,
+ dp->icmp6_type,
"Type: 0x%02x (%s)", dp->icmp6_type, typename);
if (codename) {
- proto_tree_add_text(icmp6_tree,
+ proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_code,
offset + offsetof(struct icmp6_hdr, icmp6_code), 1,
+ dp->icmp6_code,
"Code: 0x%02x (%s)", dp->icmp6_code, codename);
}
- proto_tree_add_text(icmp6_tree,
+ proto_tree_add_item(icmp6_tree, hf_icmpv6_checksum,
offset + offsetof(struct icmp6_hdr, icmp6_cksum), 2,
- "Checksum: 0x%04x", (guint16)htons(dp->icmp6_cksum));
+ (guint16)htons(dp->icmp6_cksum));
/* decode... */
switch (dp->icmp6_type) {
flagoff = offset + offsetof(struct nd_router_advert, nd_ra_flags_reserved);
ra_flags = pntohl(&pd[flagoff]);
tf = proto_tree_add_text(icmp6_tree, flagoff, 4, "Flags: 0x%08x", ra_flags);
- field_tree = proto_item_add_subtree(tf, ETT_ICMPv6FLAG);
+ field_tree = proto_item_add_subtree(tf, ett_icmpv6flag);
proto_tree_add_text(field_tree, flagoff, 4, "%s",
decode_boolean_bitfield(ra_flags,
0x80000000, 32, "Managed", "Not managed"));
na_flags = pntohl(&pd[flagoff]);
tf = proto_tree_add_text(icmp6_tree, flagoff, 4, "Flags: 0x%08x", na_flags);
- field_tree = proto_item_add_subtree(tf, ETT_ICMPv6FLAG);
+ field_tree = proto_item_add_subtree(tf, ett_icmpv6flag);
proto_tree_add_text(field_tree, flagoff, 4, "%s",
decode_boolean_bitfield(na_flags,
0x80000000, 32, "Router", "Not router"));
flagoff = offset + offsetof(struct icmp6_router_renum, rr_segnum) + 1;
tf = proto_tree_add_text(icmp6_tree, flagoff, 4, "Flags: 0x%08x",
pd[flagoff]);
- field_tree = proto_item_add_subtree(tf, ETT_ICMPv6FLAG);
+ field_tree = proto_item_add_subtree(tf, ett_icmpv6flag);
proto_tree_add_text(field_tree, flagoff, 1, "%s",
decode_boolean_bitfield(pd[flagoff], 0x80, 8,
"Test command", "Not test command"));
}
}
}
+
+void
+proto_register_icmpv6(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_icmpv6_type,
+ { "Type", "icmpv6.type", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "" }},
+ { &hf_icmpv6_code,
+ { "Code", "icmpv6.code", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "" }},
+ { &hf_icmpv6_checksum,
+ { "Checksum", "icmpv6.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
+ "" }}
+ };
+ static gint *ett[] = {
+ &ett_icmpv6,
+ &ett_icmpv6opt,
+ &ett_icmpv6flag,
+ };
+
+ proto_icmpv6 = proto_register_protocol("Internet Control Message Protocol v6",
+ "icmpv6");
+ proto_register_field_array(proto_icmpv6, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}