1999-10-13 06:47:49 +00:00
|
|
|
/* packet-pim.c
|
|
|
|
* Routines for PIM disassembly
|
|
|
|
* (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org>
|
|
|
|
*
|
2001-05-07 20:26:25 +00:00
|
|
|
* $Id: packet-pim.c,v 1.28 2001/05/07 20:26:25 guy Exp $
|
1999-10-13 06:47:49 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
2001-04-23 17:51:37 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
1999-10-13 06:47:49 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
2000-08-11 13:37:21 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
1999-10-13 06:47:49 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
2001-05-07 20:26:25 +00:00
|
|
|
#include <stddef.h> /* For offsetof */
|
2000-11-17 21:00:40 +00:00
|
|
|
#include <string.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
#include <glib.h>
|
|
|
|
|
1999-10-14 01:39:47 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
1999-10-13 06:47:49 +00:00
|
|
|
#include "packet.h"
|
2001-04-23 17:51:37 +00:00
|
|
|
#include "ipproto.h"
|
2001-05-07 20:26:25 +00:00
|
|
|
#include "packet-ipv6.h"
|
2001-02-08 08:38:58 +00:00
|
|
|
#include "in_cksum.h"
|
1999-10-13 06:47:49 +00:00
|
|
|
|
|
|
|
#define PIM_TYPE(x) ((x) & 0x0f)
|
|
|
|
#define PIM_VER(x) (((x) & 0xf0) >> 4)
|
|
|
|
|
|
|
|
enum pimv2_addrtype {
|
|
|
|
pimv2_unicast, pimv2_group, pimv2_source
|
|
|
|
};
|
|
|
|
|
|
|
|
static int proto_pim = -1;
|
1999-10-15 13:14:43 +00:00
|
|
|
static int hf_pim_version = -1;
|
|
|
|
static int hf_pim_type = -1;
|
|
|
|
static int hf_pim_cksum = -1;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint ett_pim = -1;
|
|
|
|
|
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors.
Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.
Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate). Then use it in IP.
Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.
svn path=/trunk/; revision=2658
2000-11-18 10:38:33 +00:00
|
|
|
static dissector_handle_t ip_handle;
|
2001-04-23 03:56:57 +00:00
|
|
|
static dissector_handle_t ipv6_handle;
|
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors.
Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.
Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate). Then use it in IP.
Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.
svn path=/trunk/; revision=2658
2000-11-18 10:38:33 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
/*
|
|
|
|
* Address family values.
|
|
|
|
*/
|
|
|
|
#define PIM_AF_RESERVED 0
|
|
|
|
#define PIM_AF_IP 1 /* IPv4 */
|
|
|
|
#define PIM_AF_IPV6 2 /* IPv6 */
|
|
|
|
#define PIM_AF_NSAP 3 /* NSAP */
|
|
|
|
#define PIM_AF_HDLC 4 /* HDLC (8-bit multidrop) */
|
|
|
|
#define PIM_AF_BBN_1822 5 /* BBN 1822 */
|
|
|
|
#define PIM_AF_802 6 /* 802 (D/I/X Ethernet, 802.x, FDDI) */
|
|
|
|
#define PIM_AF_E_163 7 /* E.163 */
|
|
|
|
#define PIM_AF_E_164 8 /* E.164 (SMDS, Frame Relay, ATM) */
|
|
|
|
#define PIM_AF_F_69 9 /* F.69 (Telex) */
|
|
|
|
#define PIM_AF_X_121 10 /* X.121 (X.25, Frame Relay) */
|
|
|
|
#define PIM_AF_IPX 11 /* IPX */
|
|
|
|
#define PIM_AF_ATALK 12 /* Appletalk */
|
|
|
|
#define PIM_AF_DECNET_IV 13 /* DECnet Phase IV */
|
|
|
|
#define PIM_AF_VINES 14 /* Banyan Vines */
|
|
|
|
#define PIM_AF_E_164_NSAP 15 /* E.164 with NSAP format subaddress */
|
|
|
|
|
1999-10-13 06:47:49 +00:00
|
|
|
static const char *
|
2001-01-13 06:34:35 +00:00
|
|
|
dissect_pim_addr(tvbuff_t *tvb, int offset, enum pimv2_addrtype at,
|
1999-10-13 06:47:49 +00:00
|
|
|
int *advance) {
|
|
|
|
static char buf[512];
|
2001-01-13 06:34:35 +00:00
|
|
|
guint8 af;
|
|
|
|
guint8 et;
|
|
|
|
guint8 flags;
|
|
|
|
guint8 mask_len;
|
1999-10-13 06:47:49 +00:00
|
|
|
int len = 0;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
af = tvb_get_guint8(tvb, offset);
|
|
|
|
if (af != PIM_AF_IP && af != PIM_AF_IPV6) {
|
|
|
|
/*
|
|
|
|
* We don't handle the other formats, and addresses don't include
|
|
|
|
* a length field, so we can't even show them as raw bytes.
|
|
|
|
*/
|
1999-10-13 06:47:49 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
et = tvb_get_guint8(tvb, offset + 1);
|
|
|
|
if (et != 0) {
|
|
|
|
/*
|
|
|
|
* The only defined encoding type is 0, for the native encoding;
|
|
|
|
* again, as addresses don't include a length field, we can't
|
|
|
|
* even show addresses with a different encoding type as raw
|
|
|
|
* bytes.
|
|
|
|
*/
|
1999-10-13 06:47:49 +00:00
|
|
|
return NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
}
|
1999-10-13 06:47:49 +00:00
|
|
|
|
|
|
|
switch (at) {
|
|
|
|
case pimv2_unicast:
|
2001-01-13 06:34:35 +00:00
|
|
|
switch (af) {
|
|
|
|
case PIM_AF_IP:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 4;
|
2001-01-13 06:34:35 +00:00
|
|
|
(void)snprintf(buf, sizeof(buf), "%s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, offset + 2, len)));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PIM_AF_IPV6:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 16;
|
|
|
|
(void)snprintf(buf, sizeof(buf), "%s",
|
2001-01-13 06:34:35 +00:00
|
|
|
ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset + 2, len)));
|
|
|
|
break;
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
|
|
|
if (advance)
|
|
|
|
*advance = 2 + len;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case pimv2_group:
|
2001-01-13 06:34:35 +00:00
|
|
|
mask_len = tvb_get_guint8(tvb, offset + 3);
|
|
|
|
switch (af) {
|
|
|
|
case PIM_AF_IP:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 4;
|
2001-01-13 06:34:35 +00:00
|
|
|
(void)snprintf(buf, sizeof(buf), "%s/%u",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, offset + 4, len)), mask_len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PIM_AF_IPV6:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 16;
|
|
|
|
(void)snprintf(buf, sizeof(buf), "%s/%u",
|
2001-01-13 06:34:35 +00:00
|
|
|
ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, len)), mask_len);
|
|
|
|
break;
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
|
|
|
if (advance)
|
|
|
|
*advance = 4 + len;
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
|
1999-10-13 06:47:49 +00:00
|
|
|
case pimv2_source:
|
2001-01-13 06:34:35 +00:00
|
|
|
flags = tvb_get_guint8(tvb, offset + 2);
|
|
|
|
mask_len = tvb_get_guint8(tvb, offset + 3);
|
|
|
|
switch (af) {
|
|
|
|
case PIM_AF_IP:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 4;
|
2001-01-13 06:34:35 +00:00
|
|
|
(void)snprintf(buf, sizeof(buf), "%s/%u",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, offset + 4, len)), mask_len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PIM_AF_IPV6:
|
1999-10-13 06:47:49 +00:00
|
|
|
len = 16;
|
|
|
|
(void)snprintf(buf, sizeof(buf), "%s/%u",
|
2001-01-13 06:34:35 +00:00
|
|
|
ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset + 4, len)), mask_len);
|
|
|
|
break;
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
2001-01-13 06:34:35 +00:00
|
|
|
if (flags) {
|
1999-10-13 06:47:49 +00:00
|
|
|
(void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
|
|
|
|
" (%s%s%s)",
|
2001-01-13 06:34:35 +00:00
|
|
|
flags & 0x04 ? "S" : "",
|
|
|
|
flags & 0x02 ? "W" : "",
|
|
|
|
flags & 0x01 ? "R" : "");
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
|
|
|
if (advance)
|
|
|
|
*advance = 4 + len;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2000-04-20 07:05:58 +00:00
|
|
|
static void
|
2001-01-13 06:34:35 +00:00
|
|
|
dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
|
|
int offset = 0;
|
|
|
|
guint8 pim_typever;
|
2001-02-08 08:38:58 +00:00
|
|
|
guint length, pim_length;
|
|
|
|
guint16 pim_cksum, computed_cksum;
|
|
|
|
vec_t cksum_vec[1];
|
1999-10-14 03:50:51 +00:00
|
|
|
static const value_string type1vals[] = {
|
|
|
|
{ 0, "Query" },
|
|
|
|
{ 1, "Register" },
|
|
|
|
{ 2, "Register-stop" },
|
|
|
|
{ 3, "Join/Prune" },
|
|
|
|
{ 4, "RP-Reachable" },
|
|
|
|
{ 5, "Assert" },
|
|
|
|
{ 6, "Graft" },
|
|
|
|
{ 7, "Graft-Ack" },
|
|
|
|
{ 8, "Mode" },
|
|
|
|
{ 0, NULL },
|
1999-10-13 06:47:49 +00:00
|
|
|
};
|
1999-10-14 03:50:51 +00:00
|
|
|
static const value_string type2vals[] = {
|
|
|
|
{ 0, "Hello" },
|
|
|
|
{ 1, "Register" },
|
|
|
|
{ 2, "Register-stop" },
|
|
|
|
{ 3, "Join/Prune" },
|
|
|
|
{ 4, "Bootstrap" },
|
|
|
|
{ 5, "Assert" },
|
|
|
|
{ 6, "Graft" },
|
|
|
|
{ 7, "Graft-Ack" },
|
|
|
|
{ 8, "Candidate-RP-Advertisement" },
|
|
|
|
{ 0, NULL },
|
1999-10-13 06:47:49 +00:00
|
|
|
};
|
|
|
|
char *typestr;
|
|
|
|
proto_tree *pim_tree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *ti;
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_tree *pimopt_tree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *tiopt;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
if (check_col(pinfo->fd, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->fd, COL_PROTOCOL, "PIM");
|
|
|
|
if (check_col(pinfo->fd, COL_INFO))
|
|
|
|
col_clear(pinfo->fd, COL_INFO);
|
|
|
|
|
|
|
|
pim_typever = tvb_get_guint8(tvb, 0);
|
|
|
|
|
|
|
|
switch (PIM_VER(pim_typever)) {
|
1999-10-13 06:47:49 +00:00
|
|
|
case 1:
|
2001-01-13 06:34:35 +00:00
|
|
|
typestr = val_to_str(PIM_TYPE(pim_typever), type1vals, "Unknown");
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2001-01-13 06:34:35 +00:00
|
|
|
typestr = val_to_str(PIM_TYPE(pim_typever), type2vals, "Unknown");
|
1999-10-14 03:50:51 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
typestr = "Unknown";
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
if (check_col(pinfo->fd, COL_PROTOCOL)) {
|
|
|
|
col_add_fstr(pinfo->fd, COL_PROTOCOL, "PIM version %d",
|
|
|
|
PIM_VER(pim_typever));
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
2001-01-13 06:34:35 +00:00
|
|
|
if (check_col(pinfo->fd, COL_INFO))
|
|
|
|
col_add_fstr(pinfo->fd, COL_INFO, "%s", typestr);
|
1999-10-13 06:47:49 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2001-01-13 06:34:35 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_pim, tvb, offset,
|
|
|
|
tvb_length_remaining(tvb, offset), FALSE);
|
1999-11-16 11:44:20 +00:00
|
|
|
pim_tree = proto_item_add_subtree(ti, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_uint(pim_tree, hf_pim_version, tvb, offset, 1,
|
|
|
|
PIM_VER(pim_typever));
|
|
|
|
proto_tree_add_uint_format(pim_tree, hf_pim_type, tvb, offset, 1,
|
|
|
|
PIM_TYPE(pim_typever),
|
|
|
|
"Type: %s (%u)", typestr, PIM_TYPE(pim_typever));
|
|
|
|
|
|
|
|
pim_cksum = tvb_get_ntohs(tvb, offset + 2);
|
2001-02-08 08:38:58 +00:00
|
|
|
length = tvb_length(tvb);
|
|
|
|
if (PIM_VER(pim_typever) == 2) {
|
|
|
|
/*
|
|
|
|
* Well, it's PIM v2, so we can check whether this is a Register
|
2001-05-07 20:26:25 +00:00
|
|
|
* message, and thus can figure out how much to checksum and
|
|
|
|
* whether to make the columns read-only.
|
2001-02-08 08:38:58 +00:00
|
|
|
*/
|
|
|
|
if (PIM_TYPE(pim_typever) == 1) {
|
|
|
|
/*
|
|
|
|
* Register message - the PIM header is 8 bytes long.
|
2001-05-07 20:26:25 +00:00
|
|
|
* Also set the columns non-writable. Otherwise the IPv4 or
|
|
|
|
* IPv6 dissector for the encapsulated packet that caused
|
|
|
|
* this register will overwrite the PIM info in the columns.
|
2001-02-08 08:38:58 +00:00
|
|
|
*/
|
|
|
|
pim_length = 8;
|
2001-05-07 20:26:25 +00:00
|
|
|
col_set_writable(pinfo->fd, FALSE);
|
2001-02-08 08:38:58 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Other message - checksum the entire packet.
|
|
|
|
*/
|
|
|
|
pim_length = tvb_reported_length(tvb);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* We don't know what type of message this is, so say that
|
|
|
|
* the length is 0, to force it not to be checksummed.
|
|
|
|
*/
|
|
|
|
pim_length = 0;
|
|
|
|
}
|
|
|
|
if (!pinfo->fragmented && length >= pim_length) {
|
|
|
|
/*
|
|
|
|
* The packet isn't part of a fragmented datagram and isn't
|
|
|
|
* truncated, so we can checksum it.
|
|
|
|
*/
|
|
|
|
cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pim_length);
|
|
|
|
cksum_vec[0].len = pim_length;
|
|
|
|
computed_cksum = in_cksum(&cksum_vec[0], 1);
|
|
|
|
if (computed_cksum == 0) {
|
|
|
|
proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
|
|
|
|
offset + 2, 2, pim_cksum,
|
|
|
|
"Checksum: 0x%04x (correct)",
|
|
|
|
pim_cksum);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb,
|
|
|
|
offset + 2, 2, pim_cksum,
|
|
|
|
"Checksum: 0x%04x (incorrect, should be 0x%04x)",
|
|
|
|
pim_cksum, in_cksum_shouldbe(pim_cksum, computed_cksum));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
proto_tree_add_uint(pim_tree, hf_pim_cksum, tvb,
|
|
|
|
offset + 2, 2, pim_cksum);
|
|
|
|
}
|
2001-01-13 06:34:35 +00:00
|
|
|
|
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
if (tvb_reported_length_remaining(tvb, offset) > 0) {
|
|
|
|
tiopt = proto_tree_add_text(pim_tree, tvb, offset,
|
|
|
|
tvb_length_remaining(tvb, offset), "PIM parameters");
|
1999-11-16 11:44:20 +00:00
|
|
|
pimopt_tree = proto_item_add_subtree(tiopt, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
} else
|
|
|
|
goto done;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
if (PIM_VER(pim_typever) != 2)
|
1999-10-13 06:47:49 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* version 2 decoder */
|
2001-01-13 06:34:35 +00:00
|
|
|
switch (PIM_TYPE(pim_typever)) {
|
1999-10-13 06:47:49 +00:00
|
|
|
case 0: /*hello*/
|
|
|
|
{
|
2001-01-13 06:34:35 +00:00
|
|
|
while (tvb_reported_length_remaining(tvb, offset) >= 2) {
|
|
|
|
if (tvb_get_ntohs(tvb, offset) == 1 &&
|
|
|
|
tvb_get_ntohs(tvb, offset + 2) == 2) {
|
|
|
|
guint16 holdtime;
|
|
|
|
|
|
|
|
holdtime = tvb_get_ntohs(tvb, offset + 4);
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 6,
|
|
|
|
"Holdtime: %u%s", holdtime,
|
|
|
|
holdtime == 0xffff ? " (infty)" : "");
|
|
|
|
offset += 6;
|
1999-10-13 06:47:49 +00:00
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 1: /* register */
|
|
|
|
{
|
2001-01-13 06:34:35 +00:00
|
|
|
guint32 flags;
|
|
|
|
guint8 v_hl;
|
|
|
|
tvbuff_t *next_tvb;
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_tree *flag_tree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *tiflag;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
flags = tvb_get_ntohl(tvb, offset);
|
|
|
|
tiflag = proto_tree_add_text(pimopt_tree, tvb, offset, 4,
|
|
|
|
"Flags: 0x%08x", flags);
|
1999-11-16 11:44:20 +00:00
|
|
|
flag_tree = proto_item_add_subtree(tiflag, ett_pim);
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(flag_tree, tvb, offset, 1, "%s",
|
|
|
|
decode_boolean_bitfield(flags, 0x80000000, 32,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Border", "Not border"));
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(flag_tree, tvb, offset, 1, "%s",
|
|
|
|
decode_boolean_bitfield(flags, 0x40000000, 32,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Null-Register", "Not Null-Register"));
|
2001-01-13 06:34:35 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The rest of the packet is a multicast data packet.
|
|
|
|
*/
|
|
|
|
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It's an IP packet - determine whether it's IPv4 or IPv6.
|
|
|
|
*/
|
|
|
|
v_hl = tvb_get_guint8(tvb, offset);
|
|
|
|
switch((v_hl & 0xf0) >> 4) {
|
2001-05-07 20:26:25 +00:00
|
|
|
case 0: /* Null-Register dummy header.
|
|
|
|
* Has the same address family as the encapsulating PIM packet,
|
|
|
|
* e.g. an IPv6 data packet is encapsulated in IPv6 PIM packet.
|
|
|
|
*/
|
|
|
|
if (pinfo->src.type == AT_IPv4) {
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset,
|
|
|
|
tvb_length_remaining(tvb, offset),
|
|
|
|
"IPv4 dummy header");
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset + 12, 4,
|
|
|
|
"Source: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, offset + 12, 4)));
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset + 16, 4,
|
|
|
|
"Group: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, offset + 16, 4)));
|
|
|
|
} else if (pinfo->src.type == AT_IPv6) {
|
|
|
|
struct ip6_hdr ip6_hdr;
|
|
|
|
tvb_memcpy(tvb, (guint8 *)&ip6_hdr, offset,
|
|
|
|
tvb_length_remaining(tvb, offset));
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset,
|
|
|
|
tvb_length_remaining(tvb, offset),
|
|
|
|
"IPv6 dummy header");
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb,
|
|
|
|
offset + offsetof(struct ip6_hdr, ip6_src), 16,
|
|
|
|
"Source: %s",
|
|
|
|
ip6_to_str(&ip6_hdr.ip6_src));
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb,
|
|
|
|
offset + offsetof(struct ip6_hdr, ip6_dst), 16,
|
|
|
|
"Group: %s",
|
|
|
|
ip6_to_str(&ip6_hdr.ip6_dst));
|
|
|
|
} else
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset,
|
|
|
|
tvb_length_remaining(tvb, offset),
|
|
|
|
"Dummy header for an unknown protocol");
|
|
|
|
break;
|
1999-10-13 06:47:49 +00:00
|
|
|
case 4: /* IPv4 */
|
1999-10-15 13:14:43 +00:00
|
|
|
#if 0
|
2001-01-13 06:34:35 +00:00
|
|
|
call_dissector(ip_handle, next_tvb, pinfo, tree);
|
1999-10-21 15:06:02 +00:00
|
|
|
#else
|
2001-01-13 06:34:35 +00:00
|
|
|
call_dissector(ip_handle, next_tvb, pinfo, pimopt_tree);
|
1999-10-15 13:14:43 +00:00
|
|
|
#endif
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
case 6: /* IPv6 */
|
1999-10-15 13:14:43 +00:00
|
|
|
#if 0
|
2001-04-23 03:56:57 +00:00
|
|
|
call_dissector(ipv6_handle, next_tvb, pinfo, tree);
|
1999-10-21 15:06:02 +00:00
|
|
|
#else
|
2001-04-23 03:56:57 +00:00
|
|
|
call_dissector(ipv6_handle, next_tvb, pinfo, pimopt_tree);
|
1999-10-15 13:14:43 +00:00
|
|
|
#endif
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb,
|
|
|
|
offset, tvb_length_remaining(tvb, offset),
|
|
|
|
"Unknown IP version %d", (v_hl & 0xf0) >> 4);
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 2: /* register-stop */
|
|
|
|
{
|
|
|
|
int advance;
|
|
|
|
const char *s;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Group: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Source: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 3: /* join/prune */
|
|
|
|
case 6: /* graft */
|
|
|
|
case 7: /* graft-ack */
|
|
|
|
{
|
|
|
|
int advance;
|
|
|
|
int off;
|
|
|
|
const char *s;
|
|
|
|
int ngroup, i, njoin, nprune, j;
|
2001-01-13 06:34:35 +00:00
|
|
|
guint16 holdtime;
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_tree *grouptree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *tigroup;
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_tree *subtree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *tisub;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
if (PIM_TYPE(pim_typever) != 7) {
|
1999-10-13 06:47:49 +00:00
|
|
|
/* not graft-ack */
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Upstream-neighbor: %s", s);
|
|
|
|
offset += advance;
|
|
|
|
}
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
offset += 1; /* skip reserved field */
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
ngroup = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1,
|
|
|
|
"Groups: %u", ngroup);
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
if (PIM_TYPE(pim_typever) != 7) {
|
1999-10-13 06:47:49 +00:00
|
|
|
/* not graft-ack */
|
2001-01-13 06:34:35 +00:00
|
|
|
holdtime = tvb_get_ntohs(tvb, offset);
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 2,
|
|
|
|
"Holdtime: %u%s", holdtime,
|
|
|
|
holdtime == 0xffff ? " (infty)" : "");
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
for (i = 0; i < ngroup; i++) {
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak3;
|
2001-01-13 06:34:35 +00:00
|
|
|
tigroup = proto_tree_add_text(pimopt_tree, tvb, offset, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Group %d: %s", i, s);
|
1999-11-16 11:44:20 +00:00
|
|
|
grouptree = proto_item_add_subtree(tigroup, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
njoin = tvb_get_ntohs(tvb, offset);
|
|
|
|
nprune = tvb_get_ntohs(tvb, offset + 2);
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
tisub = proto_tree_add_text(grouptree, tvb, offset, 2,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Join: %d", njoin);
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(tisub, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
off = offset + 4;
|
2001-05-07 20:26:25 +00:00
|
|
|
for (j = 0; j < njoin; j++) {
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, off, pimv2_source,
|
1999-10-13 06:47:49 +00:00
|
|
|
&advance);
|
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak3;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(subtree, tvb, off, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"IP address: %s", s);
|
|
|
|
off += advance;
|
|
|
|
}
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
tisub = proto_tree_add_text(grouptree, tvb, offset + 2, 2,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Prune: %d", nprune);
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(tisub, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
for (j = 0; j < nprune; j++) {
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, off, pimv2_source,
|
1999-10-13 06:47:49 +00:00
|
|
|
&advance);
|
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak3;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(subtree, tvb, off, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"IP address: %s", s);
|
|
|
|
off += advance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
breakbreak3:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 4: /* bootstrap */
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int advance;
|
|
|
|
int i, j;
|
|
|
|
int frpcnt;
|
2001-01-13 06:34:35 +00:00
|
|
|
guint16 holdtime;
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_tree *grouptree = NULL;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_item *tigroup;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 2,
|
|
|
|
"Fragment tag: 0x%04x", tvb_get_ntohs(tvb, offset));
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += 2;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1,
|
|
|
|
"Hash mask len: %u", tvb_get_guint8(tvb, offset));
|
|
|
|
offset += 1;
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1,
|
|
|
|
"BSR priority: %u", tvb_get_guint8(tvb, offset));
|
|
|
|
offset += 1;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "BSR: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
for (i = 0; tvb_reported_length_remaining(tvb, offset) > 0; i++) {
|
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak4;
|
2001-01-13 06:34:35 +00:00
|
|
|
tigroup = proto_tree_add_text(pimopt_tree, tvb, offset, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Group %d: %s", i, s);
|
1999-11-16 11:44:20 +00:00
|
|
|
grouptree = proto_item_add_subtree(tigroup, ett_pim);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(grouptree, tvb, offset, 1,
|
|
|
|
"RP count: %u", tvb_get_guint8(tvb, offset));
|
|
|
|
offset += 1;
|
|
|
|
frpcnt = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(grouptree, tvb, offset, 1,
|
|
|
|
"FRP count: %u", frpcnt);
|
|
|
|
offset += 3;
|
|
|
|
|
|
|
|
for (j = 0; j < frpcnt; j++) {
|
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak4;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(grouptree, tvb, offset, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"RP %d: %s", j, s);
|
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
holdtime = tvb_get_ntohs(tvb, offset);
|
|
|
|
proto_tree_add_text(grouptree, tvb, offset, 2,
|
|
|
|
"Holdtime: %u%s", holdtime,
|
|
|
|
holdtime == 0xffff ? " (infty)" : "");
|
|
|
|
offset += 2;
|
|
|
|
proto_tree_add_text(grouptree, tvb, offset, 1,
|
|
|
|
"Priority: %u", tvb_get_guint8(tvb, offset));
|
|
|
|
offset += 2; /* also skips reserved field */
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
breakbreak4:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 5: /* assert */
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Group: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "Source: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1, "%s",
|
|
|
|
decode_boolean_bitfield(tvb_get_guint8(tvb, offset), 0x80, 8,
|
1999-10-13 06:47:49 +00:00
|
|
|
"RP Tree", "Not RP Tree"));
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 4, "Preference: %u",
|
|
|
|
tvb_get_ntohl(tvb, offset) & 0x7fffffff);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += 4;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 4, "Metric: %u",
|
|
|
|
tvb_get_ntohl(tvb, offset));
|
1999-10-13 06:47:49 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 8: /* Candidate-RP-Advertisement */
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int advance;
|
|
|
|
int pfxcnt;
|
2001-01-13 06:34:35 +00:00
|
|
|
guint16 holdtime;
|
1999-10-13 06:47:49 +00:00
|
|
|
int i;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
pfxcnt = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1,
|
|
|
|
"Prefix-count: %u", pfxcnt);
|
|
|
|
offset += 1;
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 1,
|
|
|
|
"Priority: %u", tvb_get_guint8(tvb, offset));
|
|
|
|
offset += 1;
|
|
|
|
holdtime = tvb_get_ntohs(tvb, offset);
|
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, 2,
|
|
|
|
"Holdtime: %u%s", holdtime,
|
|
|
|
holdtime == 0xffff ? " (infty)" : "");
|
|
|
|
offset += 2;
|
1999-10-13 06:47:49 +00:00
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_unicast, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
break;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance, "RP: %s", s);
|
1999-10-13 06:47:49 +00:00
|
|
|
offset += advance;
|
|
|
|
|
2001-01-13 06:34:35 +00:00
|
|
|
for (i = 0; i < pfxcnt; i++) {
|
|
|
|
s = dissect_pim_addr(tvb, offset, pimv2_group, &advance);
|
1999-10-13 06:47:49 +00:00
|
|
|
if (s == NULL)
|
|
|
|
goto breakbreak8;
|
2001-01-13 06:34:35 +00:00
|
|
|
proto_tree_add_text(pimopt_tree, tvb, offset, advance,
|
1999-10-13 06:47:49 +00:00
|
|
|
"Group %d: %s", i, s);
|
|
|
|
offset += advance;
|
|
|
|
}
|
|
|
|
breakbreak8:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done:;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_pim(void)
|
|
|
|
{
|
1999-10-15 13:14:43 +00:00
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_pim_version,
|
|
|
|
{ "Version", "pim.version",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
|
|
|
|
{ &hf_pim_type,
|
|
|
|
{ "Type", "pim.type",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
|
|
|
|
{ &hf_pim_cksum,
|
|
|
|
{ "Checksum", "pim.cksum",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x0, "" }},
|
|
|
|
};
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_pim,
|
|
|
|
};
|
1999-10-15 13:14:43 +00:00
|
|
|
|
1999-10-13 06:47:49 +00:00
|
|
|
proto_pim = proto_register_protocol("Protocol Independent Multicast",
|
2001-01-03 06:56:03 +00:00
|
|
|
"PIM", "pim");
|
1999-10-15 13:14:43 +00:00
|
|
|
proto_register_field_array(proto_pim, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
1999-10-13 06:47:49 +00:00
|
|
|
}
|
2000-04-16 22:46:25 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_pim(void)
|
|
|
|
{
|
2001-01-13 06:34:35 +00:00
|
|
|
dissector_add("ip.proto", IP_PROTO_PIM, dissect_pim, proto_pim);
|
2000-04-16 22:46:25 +00:00
|
|
|
|
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors.
Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.
Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate). Then use it in IP.
Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.
svn path=/trunk/; revision=2658
2000-11-18 10:38:33 +00:00
|
|
|
/*
|
2001-04-23 03:56:57 +00:00
|
|
|
* Get handles for the IPv4 and IPv6 dissectors.
|
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors.
Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.
Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate). Then use it in IP.
Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.
svn path=/trunk/; revision=2658
2000-11-18 10:38:33 +00:00
|
|
|
*/
|
|
|
|
ip_handle = find_dissector("ip");
|
2001-04-23 03:56:57 +00:00
|
|
|
ipv6_handle = find_dissector("ipv6");
|
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors.
Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.
Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate). Then use it in IP.
Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.
svn path=/trunk/; revision=2658
2000-11-18 10:38:33 +00:00
|
|
|
}
|