/* packet-icmpv6.c
* Routines for ICMPv6 packet disassembly
*
- * $Id: packet-icmpv6.c,v 1.69 2003/01/20 05:42:30 guy Exp $
+ * $Id: packet-icmpv6.c,v 1.75 2004/01/18 16:15:25 jmayer Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
static gint ett_nodeinfo_node6 = -1;
static gint ett_nodeinfo_nodebitmap = -1;
static gint ett_nodeinfo_nodedns = -1;
+static gint ett_multicastRR = -1;
static dissector_handle_t ipv6_handle;
static dissector_handle_t data_handle;
struct nd_opt_hdr nd_opt_hdr, *opt;
int len;
char *typename;
+ static const guint8 nd_redirect_reserved[6] = {0, 0, 0, 0, 0, 0};
+ guint8 nd_redirect_res[6];
if (!tree)
return;
char *t;
int len, i, p;
len = (opt->nd_opt_len << 3) - sizeof(*opt);
- t = (char *)malloc(len * 3);
+ t = g_malloc(len * 3);
memset(t, 0, len * 3);
p = offset + sizeof(*opt);
for (i = 0; i < len; i++) {
}
proto_tree_add_text(icmp6opt_tree, tvb,
offset + sizeof(*opt), len, "Link-layer address: %s", t);
- free(t);
+ g_free(t);
break;
}
case ND_OPT_PREFIX_INFORMATION:
break;
}
case ND_OPT_REDIRECTED_HEADER:
+ tvb_memcpy(tvb, (guint8 *)&nd_redirect_res, offset + 2, 6);
+ if (memcmp(nd_redirect_res, nd_redirect_reserved, 6) == 0)
+ proto_tree_add_text(icmp6opt_tree, tvb,
+ offset + 2, 6, "Reserved: 0 (correct)");
+ else
+ proto_tree_add_text(icmp6opt_tree, tvb,
+ offset +2, 6, "Reserved: MUST be 0 (incorrect!)");
proto_tree_add_text(icmp6opt_tree, tvb,
offset + 8, (opt->nd_opt_len << 3) - 8, "Redirected packet");
dissect_contained_icmpv6(tvb, offset + 8, pinfo, icmp6opt_tree);
*/
static const char *
-bitrange0(v, s, buf, buflen)
- guint32 v;
- int s;
- char *buf;
- int buflen;
+bitrange0(guint32 v, int s, char *buf, int buflen)
{
guint32 v0;
char *p, *ep;
}
}
+/*
+ * See I-D draft-vida-mld-v2-03
+ */
+static const value_string mldrv2ModesNames[] = {
+ { 1, "Include" },
+ { 2, "Exclude" },
+ { 3, "Changed to include" },
+ { 4, "Changed to exclude" },
+ { 5, "Allow new sources" },
+ { 6, "Block old sources" },
+ { 0, NULL }
+};
+
+static void
+dissect_mldrv2( tvbuff_t *tvb, guint32 offset, guint16 count, proto_tree *tree )
+{
+ proto_tree *sub_tree;
+ proto_item *tf;
+
+ guint8 recordType, auxDataLen;
+ guint32 sourceNb, recordSize, localOffset;
+ struct e_in6_addr addr;
+
+ for( ; count; count--, offset += recordSize ) {
+ localOffset = offset;
+ recordType = tvb_get_guint8( tvb, localOffset );
+ localOffset += 1;
+ auxDataLen = tvb_get_guint8( tvb, localOffset );
+ localOffset += 1;
+ sourceNb = tvb_get_ntohs( tvb, localOffset );
+ localOffset += 2;
+ recordSize = 4 + 16 + (16 * sourceNb) + (auxDataLen * 4);
+
+ tvb_memcpy(tvb, (guint8 *)&addr, localOffset, sizeof(addr) );
+ tf = proto_tree_add_text( tree, tvb, offset, recordSize,
+#ifdef INET6
+ "%s: %s (%s)", val_to_str(recordType, mldrv2ModesNames,"Unknown mode"),
+ get_hostname6(&addr), ip6_to_str(&addr)
+#else
+ "%s: %s", val_to_str(recordType, mldrv2ModesNames,"Unknown mode"),
+ ip6_to_str(&addr)
+#endif
+ );
+ sub_tree = proto_item_add_subtree(tf, ett_multicastRR);
+
+ proto_tree_add_text( sub_tree, tvb, offset, 1, "Mode: %s",
+ val_to_str(recordType, mldrv2ModesNames,"Unknown mode") );
+ proto_tree_add_text( sub_tree, tvb, offset+1, 1, "Aux data len: %u", auxDataLen * 4);
+ proto_tree_add_text( sub_tree, tvb, localOffset, 16, "Multicast Address: %s", ip6_to_str(&addr) );
+ localOffset += 16;
+
+ for( ; sourceNb; sourceNb--, localOffset += 16 ) {
+ tvb_memcpy(tvb, (guint8 *)&addr, localOffset, sizeof(addr) );
+ proto_tree_add_text( sub_tree, tvb, localOffset, 16,
+#ifdef INET6
+ "Source Address: %s (%s)", get_hostname6(&addr), ip6_to_str(&addr) );
+#else
+ "Source Address: %s", ip6_to_str(&addr) );
+#endif
+ }
+ }
+}
+
static void
dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
"Unknown");
len = sizeof(struct icmp6_nodeinfo);
break;
+ case ICMP6_MIP6_DHAAD_REQUEST:
+ typename = coltypename = "Dynamic Home Agent Address Discovery Request";
+ codename = "Should always be zero";
+ colcodename = NULL;
+ break;
+ case ICMP6_MIP6_DHAAD_REPLY:
+ typename = coltypename = "Dynamic Home Agent Address Discovery Reply";
+ codename = "Should always be zero";
+ colcodename = NULL;
+ break;
+ case ICMP6_MIP6_MPS:
+ typename = coltypename = "Mobile Prefix Solicitation";
+ codename = "Should always be zero";
+ colcodename = NULL;
+ break;
+ case ICMP6_MIP6_MPA:
+ typename = coltypename = "Mobile Prefix Advertisement";
+ codename = "Should always be zero";
+ colcodename = NULL;
+ break;
+ case ICMP6_MLDV2_REPORT:
+ typename = coltypename = "Multicast Listener Report Message v2";
+ codename = "Should always be zero";
+ colcodename = NULL;
+ break;
}
if (check_col(pinfo->cinfo, COL_INFO)) {
case ND_ROUTER_SOLICIT:
dissect_icmpv6opt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree);
break;
+ case ICMP6_MLDV2_REPORT: {
+ guint16 nbRecords;
+
+ nbRecords = tvb_get_ntohs( tvb, offset+4+2 );
+ dissect_mldrv2( tvb, offset+4+2+2, nbRecords, icmp6_tree );
+ break;
+ }
case ND_ROUTER_ADVERT:
{
struct nd_router_advert nd_router_advert, *ra;
"Unknown"));
dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree);
break;
+ case ICMP6_MIP6_DHAAD_REQUEST:
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 4, 2, "Identifier: %d (0x%02x)",
+ tvb_get_ntohs(tvb, offset + 4),
+ tvb_get_ntohs(tvb, offset + 4));
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 6, 2, "Reserved: %d",
+ tvb_get_ntohs(tvb, offset + 6));
+ break;
+ case ICMP6_MIP6_DHAAD_REPLY:
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 4, 2, "Identifier: %d (0x%02x)",
+ tvb_get_ntohs(tvb, offset + 4),
+ tvb_get_ntohs(tvb, offset + 4));
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 6, 2, "Reserved: %d",
+ tvb_get_ntohs(tvb, offset + 6));
+ /* TODO Show all Home Agent Addresses */
+ break;
+ case ICMP6_MIP6_MPS:
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 4, 2, "Identifier: %d (0x%02x)",
+ tvb_get_ntohs(tvb, offset + 4),
+ tvb_get_ntohs(tvb, offset + 4));
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 6, 2, "Reserved: %d",
+ tvb_get_ntohs(tvb, offset + 6));
+ break;
+ case ICMP6_MIP6_MPA:
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 4, 2, "Identifier: %d (0x%02x)",
+ tvb_get_ntohs(tvb, offset + 4),
+ tvb_get_ntohs(tvb, offset + 4));
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 6, 2,
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6),
+ 0x8000, 16,
+ "Managed Address Configuration",
+ "No Managed Address Configuration"));
+ proto_tree_add_text(icmp6_tree, tvb,
+ offset + 6, 2,
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6),
+ 0x4000, 16,
+ "Other Stateful Configuration",
+ "No Other Stateful Configuration"));
+ /* TODO Show all options */
+ break;
default:
next_tvb = tvb_new_subset(tvb, offset + sizeof(*dp), -1, -1);
call_dissector(data_handle,next_tvb, pinfo, tree);
&ett_nodeinfo_node6,
&ett_nodeinfo_nodebitmap,
&ett_nodeinfo_nodedns,
+ &ett_multicastRR,
};
proto_icmpv6 = proto_register_protocol("Internet Control Message Protocol v6",