* Routines for PIM disassembly
* (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org>
*
- * $Id: packet-pim.c,v 1.5 1999/10/15 13:14:43 itojun Exp $
+ * $Id: packet-pim.c,v 1.13 2000/05/11 08:15:33 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#include <glib.h>
#include "packet.h"
+#include "packet-ip.h"
#include "packet-ipv6.h"
#ifndef offsetof
static int hf_pim_type = -1;
static int hf_pim_cksum = -1;
+static gint ett_pim = -1;
+
static const char *
dissect_pim_addr(const u_char *bp, const u_char *ep, enum pimv2_addrtype at,
int *advance) {
return buf;
}
-void
+static void
dissect_pim(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
struct pim pim;
static const value_string type1vals[] = {
col_add_fstr(fd, COL_INFO, "%s", typestr);
if (tree) {
- ti = proto_tree_add_item(tree, proto_pim, offset, END_OF_FRAME, NULL);
- pim_tree = proto_item_add_subtree(ti, ETT_PIM);
+ ti = proto_tree_add_item(tree, proto_pim, NullTVB, offset, END_OF_FRAME, NULL);
+ pim_tree = proto_item_add_subtree(ti, ett_pim);
- proto_tree_add_item(pim_tree, hf_pim_version, offset, 1,
+ proto_tree_add_item(pim_tree, hf_pim_version, NullTVB, offset, 1,
PIM_VER(pim.pim_typever));
- proto_tree_add_item_format(pim_tree, hf_pim_type, offset, 1,
+ proto_tree_add_uint_format(pim_tree, hf_pim_type, NullTVB, offset, 1,
PIM_TYPE(pim.pim_typever),
"Type: %s (%u)", typestr, PIM_TYPE(pim.pim_typever));
- proto_tree_add_item(pim_tree, hf_pim_cksum,
+ proto_tree_add_item(pim_tree, hf_pim_cksum, NullTVB,
offset + offsetof(struct pim, pim_cksum), sizeof(pim.pim_cksum),
ntohs(pim.pim_cksum));
if (sizeof(struct pim) < END_OF_FRAME) {
- tiopt = proto_tree_add_text(pim_tree,
+ tiopt = proto_tree_add_text(pim_tree, NullTVB,
offset + sizeof(struct pim), END_OF_FRAME,
"PIM parameters");
- pimopt_tree = proto_item_add_subtree(tiopt, ETT_PIM);
+ pimopt_tree = proto_item_add_subtree(tiopt, ett_pim);
} else
goto done;
guint16 *w;
w = (guint16 *)&pd[offset + sizeof(struct pim)];
while ((guint8 *)w < &pd[offset + END_OF_FRAME]) {
- if (ntohs(w[0]) == 1 && ntohs(w[1]) == 2
+ if (pntohs(&w[0]) == 1 && pntohs(&w[1]) == 2
&& (guint8 *)&w[3] <= &pd[offset + END_OF_FRAME]) {
- proto_tree_add_text(pimopt_tree, (guint8 *)w - pd, 6,
- "Holdtime: %u%s", ntohs(w[2]),
- ntohs(w[2]) == 0xffff ? " (infty)" : "");
+ proto_tree_add_text(pimopt_tree, NullTVB, (guint8 *)w - pd, 6,
+ "Holdtime: %u%s", pntohs(&w[2]),
+ pntohs(&w[2]) == 0xffff ? " (infty)" : "");
w += 3;
} else
break;
int flagoff;
flagoff = offset + sizeof(struct pim);
- tiflag = proto_tree_add_text(pimopt_tree, flagoff, 4,
- "Flags: 0x%08x", ntohl(*(guint32 *)&pd[flagoff]));
- flag_tree = proto_item_add_subtree(tiflag, ETT_PIM);
- proto_tree_add_text(flag_tree, flagoff, 1, "%s",
+ tiflag = proto_tree_add_text(pimopt_tree, NullTVB, flagoff, 4,
+ "Flags: 0x%08x", pntohl(&pd[flagoff]));
+ flag_tree = proto_item_add_subtree(tiflag, ett_pim);
+ proto_tree_add_text(flag_tree, NullTVB, flagoff, 1, "%s",
decode_boolean_bitfield(pd[flagoff], 0x80000000, 32,
"Border", "Not border"));
- proto_tree_add_text(flag_tree, flagoff, 1, "%s",
+ proto_tree_add_text(flag_tree, NullTVB, flagoff, 1, "%s",
decode_boolean_bitfield(pd[flagoff], 0x40000000, 32,
"Null-Register", "Not Null-Register"));
switch((*ip & 0xf0) >> 4) {
case 4: /* IPv4 */
#if 0
- dissect_ip(pd, ip - pd, fd, pimopt_tree);
-#else
dissect_ip(pd, ip - pd, fd, tree);
+#else
+ dissect_ip(pd, ip - pd, fd, pimopt_tree);
#endif
break;
case 6: /* IPv6 */
#if 0
- dissect_ipv6(pd, ip - pd, fd, pimopt_tree);
-#else
dissect_ipv6(pd, ip - pd, fd, tree);
+#else
+ dissect_ipv6(pd, ip - pd, fd, pimopt_tree);
#endif
break;
default:
- proto_tree_add_text(pimopt_tree,
+ proto_tree_add_text(pimopt_tree, NullTVB,
ip - pd, END_OF_FRAME,
"Unknown IP version %d", (*ip & 0xf0) >> 4);
break;
s = dissect_pim_addr(&pd[offset], ep, pimv2_group, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "Group: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "Group: %s", s);
offset += advance;
s = dissect_pim_addr(&pd[offset], ep, pimv2_unicast, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "Source: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "Source: %s", s);
break;
}
s = dissect_pim_addr(&pd[offset], ep, pimv2_unicast, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance,
"Upstream-neighbor: %s", s);
offset += advance;
}
if (&pd[offset + 2] > ep)
break;
ngroup = pd[offset + 1];
- proto_tree_add_text(pimopt_tree, offset + 1, 1,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset + 1, 1,
"Groups: %u", pd[offset + 1]);
offset += 2;
break;
if (PIM_TYPE(pim.pim_typever) != 7) {
/* not graft-ack */
- proto_tree_add_text(pimopt_tree, offset, 2,
- "Holdtime: %u%s", ntohs(*(guint16 *)&pd[offset]),
- ntohs(*(guint16 *)&pd[offset]) == 0xffff ? " (infty)" : "");
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 2,
+ "Holdtime: %u%s", pntohs(&pd[offset]),
+ pntohs(&pd[offset]) == 0xffff ? " (infty)" : "");
}
offset += 2;
s = dissect_pim_addr(&pd[offset], ep, pimv2_group, &advance);
if (s == NULL)
goto breakbreak3;
- tigroup = proto_tree_add_text(pimopt_tree, offset, advance,
+ tigroup = proto_tree_add_text(pimopt_tree, NullTVB, offset, advance,
"Group %d: %s", i, s);
- grouptree = proto_item_add_subtree(tigroup, ETT_PIM);
+ grouptree = proto_item_add_subtree(tigroup, ett_pim);
offset += advance;
if (&pd[offset + 4] > ep)
goto breakbreak3;
- njoin = ntohs(*(guint16 *)&pd[offset]);
- nprune = ntohs(*(guint16 *)&pd[offset + 2]);
+ njoin = pntohs(&pd[offset]);
+ nprune = pntohs(&pd[offset + 2]);
- tisub = proto_tree_add_text(grouptree, offset, 2,
+ tisub = proto_tree_add_text(grouptree, NullTVB, offset, 2,
"Join: %d", njoin);
- subtree = proto_item_add_subtree(tisub, ETT_PIM);
+ subtree = proto_item_add_subtree(tisub, ett_pim);
off = offset + 4;
for (j = 0; j < nprune; j++) {
s = dissect_pim_addr(&pd[off], ep, pimv2_source,
&advance);
if (s == NULL)
goto breakbreak3;
- proto_tree_add_text(subtree, off, advance,
+ proto_tree_add_text(subtree, NullTVB, off, advance,
"IP address: %s", s);
off += advance;
}
- tisub = proto_tree_add_text(grouptree, offset + 2, 2,
+ tisub = proto_tree_add_text(grouptree, NullTVB, offset + 2, 2,
"Prune: %d", nprune);
- subtree = proto_item_add_subtree(tisub, ETT_PIM);
+ subtree = proto_item_add_subtree(tisub, ett_pim);
for (j = 0; j < nprune; j++) {
s = dissect_pim_addr(&pd[off], ep, pimv2_source,
&advance);
if (s == NULL)
goto breakbreak3;
- proto_tree_add_text(subtree, off, advance,
+ proto_tree_add_text(subtree, NullTVB, off, advance,
"IP address: %s", s);
off += advance;
}
if (END_OF_FRAME < 2)
break;
- proto_tree_add_text(pimopt_tree, offset, 2,
- "Fragment tag: 0x%04x", ntohs(*(guint16 *)&pd[offset]));
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 2,
+ "Fragment tag: 0x%04x", pntohs(&pd[offset]));
offset += 2;
if (END_OF_FRAME < 2)
break;
- proto_tree_add_text(pimopt_tree, offset, 1,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 1,
"Hash mask len: %u", pd[offset]);
- proto_tree_add_text(pimopt_tree, offset + 1, 1,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset + 1, 1,
"BSR priority: %u", pd[offset + 1]);
offset += 2;
pimv2_unicast, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "BSR: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "BSR: %s", s);
offset += advance;
for (i = 0; END_OF_FRAME > 0; i++) {
pimv2_group, &advance);
if (s == NULL)
goto breakbreak4;
- tigroup = proto_tree_add_text(pimopt_tree, offset, advance,
+ tigroup = proto_tree_add_text(pimopt_tree, NullTVB, offset, advance,
"Group %d: %s", i, s);
- grouptree = proto_item_add_subtree(tigroup, ETT_PIM);
+ grouptree = proto_item_add_subtree(tigroup, ett_pim);
offset += advance;
if (END_OF_FRAME < 2)
goto breakbreak4;
- proto_tree_add_text(grouptree, offset, 1,
+ proto_tree_add_text(grouptree, NullTVB, offset, 1,
"RP count: %u", pd[offset]);
- proto_tree_add_text(grouptree, offset + 1, 1,
+ proto_tree_add_text(grouptree, NullTVB, offset + 1, 1,
"FRP count: %u", pd[offset + 1]);
frpcnt = pd[offset + 1];
offset += 4;
&pd[offset + END_OF_FRAME], pimv2_unicast, &advance);
if (s == NULL)
goto breakbreak4;
- proto_tree_add_text(grouptree, offset, advance,
+ proto_tree_add_text(grouptree, NullTVB, offset, advance,
"RP %d: %s", j, s);
offset += advance;
if (END_OF_FRAME < 4)
goto breakbreak4;
- proto_tree_add_text(grouptree, offset, 2,
- "Holdtime: %u%s", ntohs(*(guint16 *)&pd[offset]),
- ntohs(*(guint16 *)&pd[offset]) == 0xffff ? " (infty)" : "");
- proto_tree_add_text(grouptree, offset + 3, 1,
+ proto_tree_add_text(grouptree, NullTVB, offset, 2,
+ "Holdtime: %u%s", pntohs(&pd[offset]),
+ pntohs(&pd[offset]) == 0xffff ? " (infty)" : "");
+ proto_tree_add_text(grouptree, NullTVB, offset + 3, 1,
"Priority: %u", pd[offset + 3]);
offset += 4;
pimv2_group, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "Group: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "Group: %s", s);
offset += advance;
s = dissect_pim_addr(&pd[offset], &pd[offset + END_OF_FRAME],
pimv2_unicast, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "Source: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "Source: %s", s);
offset += advance;
if (END_OF_FRAME < 4)
break;
- proto_tree_add_text(pimopt_tree, offset, 1, "%s",
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 1, "%s",
decode_boolean_bitfield(pd[offset], 0x80, 8,
"RP Tree", "Not RP Tree"));
- proto_tree_add_text(pimopt_tree, offset, 4, "Preference: %u",
- ntohl(*(guint32 *)&pd[offset] & 0x7fffffff));
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 4, "Preference: %u",
+ pntohl(&pd[offset]) & 0x7fffffff);
offset += 4;
if (END_OF_FRAME < 4)
break;
- proto_tree_add_text(pimopt_tree, offset, 4, "Metric: %u",
- ntohl(*(guint32 *)&pd[offset]));
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 4, "Metric: %u",
+ pntohl(&pd[offset]));
break;
}
if (END_OF_FRAME < 4)
break;
pfxcnt = pd[offset];
- proto_tree_add_text(pimopt_tree, offset, 1,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, 1,
"Prefix-count: %u", pd[offset]);
- proto_tree_add_text(pimopt_tree, offset + 1, 1,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset + 1, 1,
"Priority: %u", pd[offset + 1]);
- proto_tree_add_text(pimopt_tree, offset + 2, 2,
- "Holdtime: %u%s", ntohs(*(guint16 *)&pd[offset + 2]),
- ntohs(*(guint16 *)&pd[offset + 2]) == 0xffff ? " (infty)" : "");
+ proto_tree_add_text(pimopt_tree, NullTVB, offset + 2, 2,
+ "Holdtime: %u%s", pntohs(&pd[offset + 2]),
+ pntohs(&pd[offset + 2]) == 0xffff ? " (infty)" : "");
offset += 4;
if (END_OF_FRAME <= 0)
pimv2_unicast, &advance);
if (s == NULL)
break;
- proto_tree_add_text(pimopt_tree, offset, advance, "RP: %s", s);
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance, "RP: %s", s);
offset += advance;
for (i = 0; i < pfxcnt && END_OF_FRAME > 0; i++) {
pimv2_group, &advance);
if (s == NULL)
goto breakbreak8;
- proto_tree_add_text(pimopt_tree, offset, advance,
+ proto_tree_add_text(pimopt_tree, NullTVB, offset, advance,
"Group %d: %s", i, s);
offset += advance;
}
{ "Checksum", "pim.cksum",
FT_UINT16, BASE_HEX, NULL, 0x0, "" }},
};
+ static gint *ett[] = {
+ &ett_pim,
+ };
proto_pim = proto_register_protocol("Protocol Independent Multicast",
"pim");
proto_register_field_array(proto_pim, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
}
+
+void
+proto_reg_handoff_pim(void)
+{
+ dissector_add("ip.proto", IP_PROTO_PIM, dissect_pim);
+}
+