*
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
#include <string.h>
#include <glib.h>
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
#include <epan/packet.h>
#include <epan/ipproto.h>
#include <epan/afn.h>
#include "packet-ipv6.h"
#include <epan/in_cksum.h>
+#include "packet-pim.h"
#define PIM_TYPE(x) ((x) & 0x0f)
#define PIM_VER(x) (((x) & 0xf0) >> 4)
*/
static const char *
dissect_pimv1_addr(tvbuff_t *tvb, int offset) {
- static char buf[512];
guint16 flags_masklen;
flags_masklen = tvb_get_ntohs(tvb, offset);
if (flags_masklen & 0x0180) {
- (void)snprintf(buf, sizeof(buf),
- "(%s%s%s) ",
+ return ep_strdup_printf("(%s%s%s) ",
flags_masklen & 0x0100 ? "S" : "",
flags_masklen & 0x0080 ? "W" : "",
flags_masklen & 0x0040 ? "R" : "");
- } else
- buf[0] = '\0';
- (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s/%u",
- ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)), flags_masklen & 0x3f);
-
- return buf;
+ } else {
+ return ep_strdup_printf("%s/%u",
+ ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)), flags_masklen & 0x3f);
+ }
}
static const value_string type1vals[] = {
return offset+tvb_length_remaining(tvb, offset);
}
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIMv1");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIMv1");
+ col_clear(pinfo->cinfo, COL_INFO);
if (tree) {
ti = proto_tree_add_item(tree, proto_pim, tvb, offset, -1, FALSE);
offset += 3; /* skip reserved stuff */
- if (tree) {
if (tvb_reported_length_remaining(tvb, offset) > 0) {
tiopt = proto_tree_add_text(pim_tree, tvb, offset, -1,
"PIM parameters");
/*
* The rest of the packet is a multicast data packet.
*/
- next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
/*
* It's an IP packet - determine whether it's IPv4 or IPv6.
default:
break;
}
- }
done:;
return offset+tvb_length_remaining(tvb, offset);
static const char *
dissect_pim_addr(tvbuff_t *tvb, int offset, enum pimv2_addrtype at,
int *advance) {
- static char buf[512];
+ emem_strbuf_t *strbuf;
guint8 af;
guint8 et;
guint8 flags;
return NULL;
}
+ strbuf = ep_strbuf_new_label(NULL);
switch (at) {
case pimv2_unicast:
switch (af) {
case AFNUM_INET:
len = 4;
- (void)snprintf(buf, sizeof(buf), "%s",
- ip_to_str(tvb_get_ptr(tvb, offset + 2, len)));
+ ep_strbuf_printf(strbuf, "%s", ip_to_str(tvb_get_ptr(tvb, offset + 2, len)));
break;
case AFNUM_INET6:
len = 16;
- (void)snprintf(buf, sizeof(buf), "%s",
- ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 2, len)));
+ ep_strbuf_printf(strbuf, "%s", ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 2, len)));
break;
}
if (advance)
switch (af) {
case AFNUM_INET:
len = 4;
- (void)snprintf(buf, sizeof(buf), "%s/%u",
+ ep_strbuf_printf(strbuf, "%s/%u",
ip_to_str(tvb_get_ptr(tvb, offset + 4, len)), mask_len);
break;
case AFNUM_INET6:
len = 16;
- (void)snprintf(buf, sizeof(buf), "%s/%u",
+ ep_strbuf_printf(strbuf, "%s/%u",
ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, len)), mask_len);
break;
}
switch (af) {
case AFNUM_INET:
len = 4;
- (void)snprintf(buf, sizeof(buf), "%s/%u",
+ ep_strbuf_printf(strbuf, "%s/%u",
ip_to_str(tvb_get_ptr(tvb, offset + 4, len)), mask_len);
break;
case AFNUM_INET6:
len = 16;
- (void)snprintf(buf, sizeof(buf), "%s/%u",
+ ep_strbuf_printf(strbuf, "%s/%u",
ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, len)), mask_len);
break;
}
if (flags) {
- (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ ep_strbuf_append_printf(strbuf,
" (%s%s%s)",
flags & 0x04 ? "S" : "",
flags & 0x02 ? "W" : "",
return NULL;
}
- return buf;
+ return strbuf->str;
}
static const value_string type2vals[] = {
{ 6, "Graft" },
{ 7, "Graft-Ack" },
{ 8, "Candidate-RP-Advertisement" },
- { 0, NULL },
+ { 9, "State-Refresh" },
+ { 0, NULL }
};
/*
- * For PIM v2, see RFC 2362, and draft-ietf-pim-sm-v2-new-03 (when PIM
- * is run over IPv6, the rules for computing the PIM checksum from the
- * draft in question, not from RFC 2362, should be used).
+ * For PIM v2, see RFC 4601, RFC 3973 and draft-ietf-pim-sm-v2-new-03
+ * (when PIM is run over IPv6, the rules for computing the PIM checksum
+ * from the draft in question, not from RFC 2362, should be used).
*/
static void
dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
proto_tree *pimopt_tree = NULL;
proto_item *tiopt;
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIM");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIM");
+ col_clear(pinfo->cinfo, COL_INFO);
pim_typever = tvb_get_guint8(tvb, 0);
override_interval = opt_value & 0x0000ffff;
proto_tree_add_text(sub_tree, tvb, offset + 4, 1,
"T bit is %s",
- opt_value & 0x8000 ? "set" : "not set");
+ (opt_value & 0x80000000) ? "set" : "not set");
proto_tree_add_text(sub_tree, tvb, offset + 4, 2,
"LAN Delay: %ums", lan_delay);
proto_tree_add_text(sub_tree, tvb, offset + 6, 2,
/*
* The rest of the packet is a multicast data packet.
*/
- next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
/*
* It's an IP packet - determine whether it's IPv4 or IPv6.
break;
}
+ case 9: /* State-Refresh */
+ {
+ const char *s;
+ int advance;
+
+ s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
+ if (s == NULL)
+ break;
+ proto_tree_add_text(pimopt_tree, tvb, offset, advance,
+ "Group: %s", s);
+ offset += advance;
+
+ s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
+ if (s == NULL)
+ break;
+ proto_tree_add_text(pimopt_tree, tvb, offset, advance,
+ "Source: %s", s);
+ offset += advance;
+
+ s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
+ if (s == NULL)
+ break;
+ proto_tree_add_text(pimopt_tree, tvb, offset, advance,
+ "Originator: %s", s);
+ offset += advance;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Rendezvous Point Tree %s",
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 1, 1,
+ "set", "clear"));
+ proto_tree_add_text(pimopt_tree, tvb, offset, 4,
+ "Metric Preference: %u", tvb_get_ntohl(tvb, offset) & 0x7FFFFFFF);
+ offset += 4;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 4,
+ "Metric: %u", tvb_get_ntohl(tvb, offset));
+ offset += 4;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1,
+ "Masklen: %u", tvb_get_guint8(tvb, offset));
+ offset += 1;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1,
+ "TTL: %u", tvb_get_guint8(tvb, offset));
+ offset += 1;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Prune indicator %s",
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x80, 8,
+ "set", "clear"));
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Prune now %s",
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x40, 8,
+ "set", "clear"));
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1, "Assert override %s",
+ decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x20, 8,
+ "set", "clear"));
+ offset += 1;
+
+ proto_tree_add_text(pimopt_tree, tvb, offset, 1,
+ "Interval: %u", tvb_get_guint8(tvb, offset));
+ offset += 1;
+
+ break;
+ }
+
default:
break;
}
static hf_register_info hf[] = {
{ &hf_pim_version,
{ "Version", "pim.version",
- FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_pim_type,
{ "Type", "pim.type",
- FT_UINT8, BASE_DEC, VALS(type2vals), 0x0, "", HFILL }},
+ FT_UINT8, BASE_DEC, VALS(type2vals), 0x0, NULL, HFILL }},
{ &hf_pim_code,
{ "Code", "pim.code",
- FT_UINT8, BASE_DEC, VALS(type1vals), 0x0, "", HFILL }},
+ FT_UINT8, BASE_DEC, VALS(type1vals), 0x0, NULL, HFILL }},
{ &hf_pim_cksum,
{ "Checksum", "pim.cksum",
- FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
};
static gint *ett[] = {
&ett_pim,