2011-01-14 03:44:58 +00:00
|
|
|
/* packet-igmp.c
|
2001-05-20 22:20:33 +00:00
|
|
|
* Routines for IGMP packet disassembly
|
2008-01-25 06:32:53 +00:00
|
|
|
* 2001 Ronnie Sahlberg
|
|
|
|
* 2007 Thomas Morin
|
|
|
|
* <See AUTHORS for emails>
|
2001-05-20 22:20:33 +00:00
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2001-05-20 22:20:33 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-05-20 22:20:33 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-05-20 22:20:33 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-05-20 22:20:33 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2006-10-28 21:52:38 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2001-05-20 22:20:33 +00:00
|
|
|
*/
|
|
|
|
/*
|
|
|
|
IGMP is defined in the following RFCs
|
|
|
|
RFC988 Version 0 Obsolete
|
|
|
|
RFC1054 Version 1
|
|
|
|
RFC1112 Version 1 (same as RFC1054 as far as we are concerned)
|
|
|
|
RFC2236 Version 2
|
2005-04-01 04:19:28 +00:00
|
|
|
RFC3376 Version 3
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
Size in bytes for each packet
|
2006-10-28 21:52:38 +00:00
|
|
|
type RFC988 RFC1054 RFC2236 RFC3376 DVMRP MRDISC MSNIP IGAP RGMP
|
2001-06-12 06:21:55 +00:00
|
|
|
v0 v1 v2 v3 v1/v3
|
2001-05-20 22:20:33 +00:00
|
|
|
0x01 20
|
|
|
|
0x02 20
|
|
|
|
0x03 20
|
|
|
|
0x04 20
|
|
|
|
0x05 20
|
|
|
|
0x06 20
|
|
|
|
0x07 20
|
|
|
|
0x08 20
|
|
|
|
0x11 8* 8* >=12
|
2003-07-24 20:46:26 +00:00
|
|
|
0x12 8* 8*
|
2001-06-12 06:21:55 +00:00
|
|
|
0x13 x
|
2001-05-20 22:20:33 +00:00
|
|
|
0x16 8
|
|
|
|
0x17 8
|
|
|
|
0x22 >=8
|
2002-08-28 21:04:11 +00:00
|
|
|
0x23 >=8b
|
2001-06-29 18:55:50 +00:00
|
|
|
0x24 >=8a 8b
|
|
|
|
0x25 4a >=8b
|
|
|
|
0x26 4a
|
2003-12-10 19:21:55 +00:00
|
|
|
0x40 ??c
|
|
|
|
0x41 ??c
|
|
|
|
0x42 ??c
|
2006-10-28 21:52:38 +00:00
|
|
|
0xfc 8
|
|
|
|
0xfd 8
|
|
|
|
0xfe 8
|
|
|
|
0xff 8
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
* Differs in second byte of protocol. Always 0 in V1
|
2001-06-12 06:21:55 +00:00
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
|
|
|
|
Multicast traceroute was taken from
|
|
|
|
draft-ietf-idmr-traceroute-ipm-07.txt
|
|
|
|
|
|
|
|
Size in bytes for each packet
|
|
|
|
type draft-ietf-idmr-traceroute-ipm-07.ps
|
|
|
|
0x1e 24 + n*32
|
2002-08-28 21:04:11 +00:00
|
|
|
0x1f 24 + n*32 (n == 0 for Query)
|
2001-07-10 20:55:54 +00:00
|
|
|
|
2001-06-27 20:19:19 +00:00
|
|
|
x DVMRP Protocol see packet-dvmrp.c
|
2001-06-12 06:21:55 +00:00
|
|
|
|
|
|
|
DVMRP is defined in the following RFCs
|
|
|
|
RFC1075 Version 1
|
|
|
|
draft-ietf-idmr-dvmrp-v3-10.txt Version 3
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
V1 and V3 can be distinguished by looking at bytes 6 and 7 in the
|
2001-06-12 06:21:55 +00:00
|
|
|
IGMP header.
|
|
|
|
If header[6]==0xff and header[7]==0x03 we have version 3.
|
2001-06-27 20:19:19 +00:00
|
|
|
|
|
|
|
a MRDISC Protocol see packet-mrdisc.c
|
|
|
|
|
|
|
|
MRDISC : IGMP Multicast Router DISCovery
|
|
|
|
draft-ietf-idmr-igmp-mrdisc-06.txt
|
|
|
|
TTL == 1 and IP.DST==224.0.0.2 for all packets
|
|
|
|
|
2001-06-29 18:55:50 +00:00
|
|
|
b MSNIP Protocol see packet-msnip.c
|
|
|
|
|
|
|
|
MSNIP : Multicast Source Notification of Interest Protocol
|
|
|
|
draft-ietf-idmr-msnip-00.txt
|
|
|
|
0x23, 0x24 are sent with ip.dst==224.0.0.22
|
|
|
|
0x25 is sent as unicast.
|
|
|
|
|
2003-12-10 19:21:55 +00:00
|
|
|
c IGAP Protocol see packet-igap.c
|
|
|
|
|
|
|
|
IGAP : Internet Group membership Authentication Protocol
|
|
|
|
draft-hayashi-igap-03.txt
|
|
|
|
|
2006-10-28 21:52:38 +00:00
|
|
|
d RGMP Protocol see packet-rgmp.c
|
|
|
|
|
|
|
|
RGMP : Router-port Group Management Protocol
|
|
|
|
RFC3488
|
|
|
|
TTL == 1 and IP.DST==224.0.0.25 for all packets
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
*/
|
|
|
|
|
2012-09-20 02:03:38 +00:00
|
|
|
#include "config.h"
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2014-11-07 12:47:43 +00:00
|
|
|
#include <epan/range.h>
|
2013-11-09 13:41:10 +00:00
|
|
|
#include <epan/to_str.h>
|
2004-09-29 00:52:45 +00:00
|
|
|
#include <epan/ipproto.h>
|
2004-09-28 00:06:32 +00:00
|
|
|
#include <epan/in_cksum.h>
|
2005-07-30 16:28:00 +00:00
|
|
|
#include "packet-igmp.h"
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2013-12-15 23:44:12 +00:00
|
|
|
void proto_register_igmp(void);
|
|
|
|
void proto_reg_handoff_igmp(void);
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
static int proto_igmp = -1;
|
|
|
|
static int hf_type = -1;
|
|
|
|
static int hf_version = -1;
|
|
|
|
static int hf_group_type = -1;
|
|
|
|
static int hf_reply_code = -1;
|
|
|
|
static int hf_reply_pending = -1;
|
|
|
|
static int hf_checksum = -1;
|
|
|
|
static int hf_checksum_bad = -1;
|
|
|
|
static int hf_identifier = -1;
|
|
|
|
static int hf_access_key = -1;
|
|
|
|
static int hf_max_resp = -1;
|
|
|
|
static int hf_max_resp_exp = -1;
|
|
|
|
static int hf_max_resp_mant = -1;
|
2006-01-05 13:01:08 +00:00
|
|
|
static int hf_suppress = -1;
|
2001-05-20 22:20:33 +00:00
|
|
|
static int hf_qrv = -1;
|
|
|
|
static int hf_qqic = -1;
|
|
|
|
static int hf_num_src = -1;
|
|
|
|
static int hf_saddr = -1;
|
|
|
|
static int hf_num_grp_recs = -1;
|
|
|
|
static int hf_record_type = -1;
|
|
|
|
static int hf_aux_data_len = -1;
|
|
|
|
static int hf_maddr = -1;
|
|
|
|
static int hf_aux_data = -1;
|
2014-08-09 17:43:44 +00:00
|
|
|
static int hf_data = -1;
|
2001-07-10 20:55:54 +00:00
|
|
|
static int hf_mtrace_max_hops = -1;
|
|
|
|
static int hf_mtrace_saddr = -1;
|
|
|
|
static int hf_mtrace_raddr = -1;
|
|
|
|
static int hf_mtrace_rspaddr = -1;
|
|
|
|
static int hf_mtrace_resp_ttl = -1;
|
|
|
|
static int hf_mtrace_q_id = -1;
|
|
|
|
static int hf_mtrace_q_arrival = -1;
|
|
|
|
static int hf_mtrace_q_inaddr = -1;
|
|
|
|
static int hf_mtrace_q_outaddr = -1;
|
|
|
|
static int hf_mtrace_q_prevrtr = -1;
|
|
|
|
static int hf_mtrace_q_inpkt = -1;
|
|
|
|
static int hf_mtrace_q_outpkt = -1;
|
|
|
|
static int hf_mtrace_q_total = -1;
|
|
|
|
static int hf_mtrace_q_rtg_proto = -1;
|
|
|
|
static int hf_mtrace_q_fwd_ttl = -1;
|
|
|
|
static int hf_mtrace_q_mbz = -1;
|
|
|
|
static int hf_mtrace_q_s = -1;
|
|
|
|
static int hf_mtrace_q_src_mask = -1;
|
|
|
|
static int hf_mtrace_q_fwd_code = -1;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
static int ett_igmp = -1;
|
|
|
|
static int ett_group_record = -1;
|
|
|
|
static int ett_sqrv_bits = -1;
|
|
|
|
static int ett_max_resp = -1;
|
2001-07-10 20:55:54 +00:00
|
|
|
static int ett_mtrace_block = -1;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
static dissector_table_t subdissector_table;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
#define IGMP_TRACEROUTE_HDR_LEN 24
|
|
|
|
#define IGMP_TRACEROUTE_RSP_LEN 32
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
static const value_string commands[] = {
|
|
|
|
{IGMP_V0_CREATE_GROUP_REQUEST, "Create Group Request" },
|
|
|
|
{IGMP_V0_CREATE_GROUP_REPLY, "Create Group Reply" },
|
|
|
|
{IGMP_V0_JOIN_GROUP_REQUEST, "Join Group Request" },
|
|
|
|
{IGMP_V0_JOIN_GROUP_REPLY, "Join Group Reply" },
|
|
|
|
{IGMP_V0_LEAVE_GROUP_REQUEST, "Leave Group Request" },
|
|
|
|
{IGMP_V0_LEAVE_GROUP_REPLY, "Leave Group Reply" },
|
|
|
|
{IGMP_V0_CONFIRM_GROUP_REQUEST, "Confirm Group Request" },
|
|
|
|
{IGMP_V0_CONFIRM_GROUP_REPLY, "Confirm Group Reply" },
|
|
|
|
{IGMP_V1_HOST_MEMBERSHIP_QUERY, "Membership Query" },
|
|
|
|
{IGMP_V1_HOST_MEMBERSHIP_REPORT,"Membership Report" },
|
2001-06-12 06:21:55 +00:00
|
|
|
{IGMP_DVMRP, "DVMRP Protocol" },
|
2001-05-25 06:47:02 +00:00
|
|
|
{IGMP_V1_PIM_ROUTING_MESSAGE, "PIM Routing Message" },
|
2001-05-20 22:20:33 +00:00
|
|
|
{IGMP_V2_MEMBERSHIP_REPORT, "Membership Report" },
|
|
|
|
{IGMP_V2_LEAVE_GROUP, "Leave Group" },
|
2001-07-11 04:24:34 +00:00
|
|
|
{IGMP_TRACEROUTE_RESPONSE, "Traceroute Response" },
|
|
|
|
{IGMP_TRACEROUTE_QUERY_REQ, "Traceroute Query or Request" },
|
2001-05-20 22:20:33 +00:00
|
|
|
{IGMP_V3_MEMBERSHIP_REPORT, "Membership Report" },
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
#define IGMP_V3_S 0x08
|
|
|
|
#define IGMP_V3_QRV_MASK 0x07
|
|
|
|
|
|
|
|
#define IGMP_MAX_RESP_EXP 0x70
|
|
|
|
#define IGMP_MAX_RESP_MANT 0x0f
|
|
|
|
|
|
|
|
#define IGMP_V0_GROUP_PUBLIC 0x00
|
|
|
|
#define IGMP_V0_GROUP_PRIVATE 0x01
|
|
|
|
|
|
|
|
static const value_string vs_group_type[] = {
|
|
|
|
{IGMP_V0_GROUP_PUBLIC, "Public Group" },
|
|
|
|
{IGMP_V0_GROUP_PRIVATE, "Private Group" },
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
#define IGMP_V0_REPLY_GRANTED 0x00
|
|
|
|
#define IGMP_V0_REPLY_NO_RESOURCES 0x01
|
|
|
|
#define IGMP_V0_REPLY_INVALID_CODE 0x02
|
|
|
|
#define IGMP_V0_REPLY_INVALID_GROUP 0x03
|
|
|
|
#define IGMP_V0_REPLY_INVALID_KEY 0x04
|
|
|
|
|
|
|
|
static const value_string vs_reply_code[] = {
|
|
|
|
{IGMP_V0_REPLY_GRANTED, "Request Granted" },
|
|
|
|
{IGMP_V0_REPLY_NO_RESOURCES, "Request Denied, No Resources" },
|
|
|
|
{IGMP_V0_REPLY_INVALID_CODE, "Request Denied, Invalid Code" },
|
|
|
|
{IGMP_V0_REPLY_INVALID_GROUP, "Request Denied, Invalid Group" },
|
|
|
|
{IGMP_V0_REPLY_INVALID_KEY, "Request Denied, Invalid Key" },
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_s = {
|
2006-01-05 13:01:08 +00:00
|
|
|
"SUPPRESS router side processing",
|
|
|
|
"Do not suppress router side processing"
|
2001-05-20 22:20:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define IGMP_V3_MODE_IS_INCLUDE 1
|
|
|
|
#define IGMP_V3_MODE_IS_EXCLUDE 2
|
|
|
|
#define IGMP_V3_CHANGE_TO_INCLUDE_MODE 3
|
|
|
|
#define IGMP_V3_CHANGE_TO_EXCLUDE_MODE 4
|
|
|
|
#define IGMP_V3_ALLOW_NEW_SOURCES 5
|
|
|
|
#define IGMP_V3_BLOCK_OLD_SOURCES 6
|
|
|
|
|
|
|
|
static const value_string vs_record_type[] = {
|
|
|
|
{IGMP_V3_MODE_IS_INCLUDE, "Mode Is Include" },
|
|
|
|
{IGMP_V3_MODE_IS_EXCLUDE, "Mode Is Exclude" },
|
|
|
|
{IGMP_V3_CHANGE_TO_INCLUDE_MODE,"Change To Include Mode" },
|
|
|
|
{IGMP_V3_CHANGE_TO_EXCLUDE_MODE,"Change To Exclude Mode" },
|
|
|
|
{IGMP_V3_ALLOW_NEW_SOURCES, "Allow New Sources" },
|
|
|
|
{IGMP_V3_BLOCK_OLD_SOURCES, "Block Old Sources" },
|
|
|
|
{ 0, NULL}
|
|
|
|
};
|
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
static const value_string mtrace_rtg_vals[] = {
|
|
|
|
{1, "DVMRP" },
|
|
|
|
{2, "MOSPF" },
|
|
|
|
{3, "PIM" },
|
|
|
|
{4, "CBT" },
|
|
|
|
{5, "PIM using special routing table" },
|
|
|
|
{6, "PIM using a static route" },
|
|
|
|
{7, "DVMRP using a static route" },
|
|
|
|
{8, "PIM using MBGP (aka BGP4+) route" },
|
|
|
|
{9, "CBT using special routing table" },
|
|
|
|
{10, "CBT using a static route" },
|
|
|
|
{11, "PIM using state created by Assert processing" },
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string mtrace_fwd_code_vals[] = {
|
|
|
|
{0x00, "NO_ERROR" },
|
|
|
|
{0x01, "WRONG_IF" },
|
|
|
|
{0x02, "PRUNE_SENT" },
|
|
|
|
{0x03, "PRUNE_RCVD" },
|
|
|
|
{0x04, "SCOPED" },
|
|
|
|
{0x05, "NO_ROUTE" },
|
|
|
|
{0x06, "WRONG_LAST_HOP" },
|
|
|
|
{0x07, "NOT_FORWARDING" },
|
|
|
|
{0x08, "REACHED_RP" },
|
|
|
|
{0x09, "RPF_IF" },
|
|
|
|
{0x0A, "NO_MULTICAST" },
|
|
|
|
{0x0B, "INFO_HIDDEN" },
|
|
|
|
{0x81, "NO_SPACE" },
|
|
|
|
{0x82, "OLD_ROUTER" },
|
|
|
|
{0x83, "ADMIN_PROHIB" },
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
2002-02-01 11:01:57 +00:00
|
|
|
void igmp_checksum(proto_tree *tree, tvbuff_t *tvb, int hf_index,
|
2011-09-26 20:34:33 +00:00
|
|
|
int hf_index_bad, packet_info *pinfo, guint len)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2001-07-11 04:24:34 +00:00
|
|
|
guint16 cksum, hdrcksum;
|
2001-05-20 22:20:33 +00:00
|
|
|
vec_t cksum_vec[1];
|
2008-05-14 01:47:41 +00:00
|
|
|
proto_item *hidden_item;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2001-07-11 04:24:34 +00:00
|
|
|
if (len == 0) {
|
|
|
|
/*
|
|
|
|
* Checksum the entire IGMP packet.
|
|
|
|
*/
|
|
|
|
len = tvb_reported_length(tvb);
|
2001-05-20 22:20:33 +00:00
|
|
|
}
|
2002-02-01 11:01:57 +00:00
|
|
|
|
2001-07-11 04:24:34 +00:00
|
|
|
hdrcksum = tvb_get_ntohs(tvb, 2);
|
2014-06-19 17:18:16 +00:00
|
|
|
if (!pinfo->fragmented && tvb_length(tvb) >= len) {
|
2001-07-11 04:24:34 +00:00
|
|
|
/*
|
|
|
|
* The packet isn't part of a fragmented datagram and isn't
|
|
|
|
* truncated, so we can checksum it.
|
|
|
|
*/
|
Clean up Internet checksum handling.
Add macros to set entries of a vec_t, one for use when you have a
pointer to private data, and one for use when you have data in a tvbuff.
The latter wraps the use of tvb_get_ptr(), so that you're not directly
calling it in a dissector.
Move ip_checksum() to epan/in_cksum.c, and add an ip_checksum_tvb() that
wraps the use of tvb_get_ptr().
In the CARP dissector, give the length variable an unsigned type -
there's no benefit to it being signed, and that requires some casts to
be thrown around.
In the DCCP dissector, check only against the coverage length to see if
we have enough data, combine the "should we check the checksum?" check
with the "*can* we check the checksum?" check in a single if, and throw
a dissector assertion if the source network address type isn't IPv4 or
IPv6.
Get rid of inclues of <epan/in_cksum.h> in dissectors that don't use any
of the Internet checksum routines.
In the HIP dissector, make sure we have the data to calculate the
checksum before doing so.
Change-Id: I2f9674775dbb54c533d33082632809f7d32ec8ae
Reviewed-on: https://code.wireshark.org/review/3517
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-08-09 01:09:00 +00:00
|
|
|
SET_CKSUM_VEC_TVB(cksum_vec[0], tvb, 0, len);
|
2001-07-11 04:24:34 +00:00
|
|
|
|
|
|
|
cksum = in_cksum(&cksum_vec[0],1);
|
|
|
|
|
|
|
|
if (cksum == 0) {
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_uint_format(tree, hf_index, tvb, 2, 2, hdrcksum,
|
|
|
|
"Header checksum: 0x%04x [correct]", hdrcksum);
|
2001-07-11 04:24:34 +00:00
|
|
|
} else {
|
2008-05-14 01:47:41 +00:00
|
|
|
hidden_item = proto_tree_add_boolean(tree, hf_index_bad,
|
2011-09-26 20:34:33 +00:00
|
|
|
tvb, 2, 2, TRUE);
|
2008-05-14 01:47:41 +00:00
|
|
|
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_uint_format(tree, hf_index, tvb, 2, 2, hdrcksum,
|
|
|
|
"Header checksum: 0x%04x [incorrect, should be 0x%04x]",
|
|
|
|
hdrcksum, in_cksum_shouldbe(hdrcksum,cksum));
|
2001-07-11 04:24:34 +00:00
|
|
|
}
|
|
|
|
} else
|
2002-02-01 11:01:57 +00:00
|
|
|
proto_tree_add_uint(tree, hf_index, tvb, 2, 2, hdrcksum);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
static proto_tree*
|
|
|
|
dissect_igmp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int* offset, unsigned char* type, int version)
|
|
|
|
{
|
|
|
|
proto_item* ti;
|
|
|
|
proto_tree* igmp_tree;
|
|
|
|
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "IGMPv%d", version);
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
|
|
|
|
ti = proto_tree_add_item(tree, proto_igmp, tvb, 0, -1, ENC_NA);
|
|
|
|
igmp_tree = proto_item_add_subtree(ti, ett_igmp);
|
|
|
|
|
|
|
|
*type = tvb_get_guint8(tvb, 0);
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(*type, commands, "Unknown Type:0x%02x"));
|
|
|
|
|
|
|
|
/* version of IGMP protocol */
|
|
|
|
ti = proto_tree_add_uint(igmp_tree, hf_version, tvb, 0, 0, version);
|
|
|
|
PROTO_ITEM_SET_GENERATED(ti);
|
|
|
|
|
|
|
|
/* type of command */
|
2014-12-13 17:52:20 +00:00
|
|
|
proto_tree_add_item(igmp_tree, hf_type, tvb, 0, 1, ENC_BIG_ENDIAN);
|
2014-11-07 12:47:43 +00:00
|
|
|
*offset = 1;
|
|
|
|
|
|
|
|
return igmp_tree;
|
|
|
|
}
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2001-05-25 18:44:01 +00:00
|
|
|
/* Unknown IGMP message type */
|
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
2001-05-25 18:44:01 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_item* ti;
|
|
|
|
proto_tree* tree;
|
2001-05-25 18:44:01 +00:00
|
|
|
int len;
|
2014-11-07 12:47:43 +00:00
|
|
|
int offset = 0;
|
|
|
|
unsigned char type;
|
|
|
|
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGMP");
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
|
|
|
|
ti = proto_tree_add_item(parent_tree, proto_igmp, tvb, offset, -1, ENC_NA);
|
|
|
|
tree = proto_item_add_subtree(ti, ett_igmp);
|
2001-05-25 18:44:01 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
type = tvb_get_guint8(tvb, offset);
|
2011-09-26 20:34:33 +00:00
|
|
|
col_add_str(pinfo->cinfo, COL_INFO,
|
|
|
|
val_to_str(type, commands, "Unknown Type:0x%02x"));
|
2001-05-25 18:44:01 +00:00
|
|
|
|
|
|
|
/* type of command */
|
|
|
|
proto_tree_add_uint(tree, hf_type, tvb, offset, 1, type);
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* Just call the rest of it "data" */
|
2014-06-19 17:18:16 +00:00
|
|
|
len = tvb_length_remaining(tvb, offset);
|
2014-08-09 17:43:44 +00:00
|
|
|
proto_tree_add_item(tree, hf_data, tvb, offset, -1, ENC_NA);
|
2001-05-25 18:44:01 +00:00
|
|
|
offset += len;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2001-06-12 06:21:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************
|
|
|
|
* IGMP Protocol dissectors
|
|
|
|
*************************************************************/
|
2001-05-20 22:20:33 +00:00
|
|
|
static int
|
2002-05-02 07:54:41 +00:00
|
|
|
dissect_v3_max_resp(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
|
|
|
proto_tree *tree;
|
|
|
|
proto_item *item;
|
|
|
|
guint8 bits;
|
|
|
|
guint32 tsecs;
|
|
|
|
|
|
|
|
bits = tvb_get_guint8(tvb, offset);
|
|
|
|
if (bits&0x80) {
|
|
|
|
tsecs = ((bits&IGMP_MAX_RESP_MANT)|0x10);
|
|
|
|
tsecs = tsecs << ( ((bits&IGMP_MAX_RESP_EXP)>>4) + 3);
|
|
|
|
} else {
|
|
|
|
tsecs = bits;
|
2002-08-28 21:04:11 +00:00
|
|
|
}
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2013-09-16 10:39:06 +00:00
|
|
|
item = proto_tree_add_uint_format_value(parent_tree, hf_max_resp, tvb,
|
|
|
|
offset, 1, tsecs, "%.1f sec (0x%02x)",tsecs*0.1,bits);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
if (bits&0x80) {
|
|
|
|
tree = proto_item_add_subtree(item, ett_max_resp);
|
|
|
|
|
|
|
|
proto_tree_add_uint(tree, hf_max_resp_exp, tvb, offset, 1,
|
|
|
|
bits);
|
|
|
|
proto_tree_add_uint(tree, hf_max_resp_mant, tvb, offset, 1,
|
|
|
|
bits);
|
|
|
|
}
|
|
|
|
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2002-05-02 07:54:41 +00:00
|
|
|
dissect_v3_sqrv_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
|
|
|
proto_tree *tree;
|
|
|
|
guint8 bits;
|
|
|
|
|
|
|
|
bits = tvb_get_guint8(tvb, offset);
|
|
|
|
|
2014-06-29 13:13:51 +00:00
|
|
|
tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, 1,
|
|
|
|
ett_sqrv_bits, NULL, "QRV=%d S=%s", bits&IGMP_V3_QRV_MASK,
|
2001-05-20 22:20:33 +00:00
|
|
|
(bits&IGMP_V3_S)?tfs_s.true_string:tfs_s.false_string);
|
|
|
|
|
|
|
|
/* S flag */
|
2006-01-05 13:01:08 +00:00
|
|
|
proto_tree_add_boolean(tree, hf_suppress, tvb, offset, 1, bits);
|
2001-05-20 22:20:33 +00:00
|
|
|
/* QRV */
|
|
|
|
proto_tree_add_uint(tree, hf_qrv, tvb, offset, 1, bits);
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-01-25 06:32:53 +00:00
|
|
|
dissect_v3_group_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
|
|
|
proto_tree *tree;
|
|
|
|
proto_item *item;
|
|
|
|
int old_offset = offset;
|
|
|
|
guint8 adl;
|
|
|
|
guint16 num;
|
2014-10-06 16:55:18 +00:00
|
|
|
const gchar *maddr_str;
|
2011-09-26 20:34:33 +00:00
|
|
|
guint8 record_type;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-06-29 13:13:51 +00:00
|
|
|
tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, -1,
|
|
|
|
ett_group_record, &item, "Group Record : %s %s",
|
|
|
|
tvb_ip_to_str(tvb, offset+4),
|
2012-08-10 22:55:02 +00:00
|
|
|
val_to_str_const(tvb_get_guint8(tvb, offset), vs_record_type,"")
|
2001-05-20 22:20:33 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
/* record type */
|
2008-01-25 06:32:53 +00:00
|
|
|
record_type = tvb_get_guint8(tvb, offset);
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_record_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* aux data len */
|
|
|
|
adl = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_uint(tree, hf_aux_data_len, tvb, offset, 1, adl);
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/*number of sources*/
|
|
|
|
num = tvb_get_ntohs(tvb, offset);
|
|
|
|
proto_tree_add_uint(tree, hf_num_src, tvb, offset, 2, num);
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* multicast address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str = tvb_ip_to_str(tvb, offset);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 4;
|
|
|
|
|
2011-09-26 20:34:33 +00:00
|
|
|
if (num == 0) {
|
|
|
|
switch(record_type) {
|
|
|
|
case IGMP_V3_MODE_IS_INCLUDE:
|
|
|
|
case IGMP_V3_CHANGE_TO_INCLUDE_MODE:
|
2014-06-29 13:13:51 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " / Leave group %s", maddr_str);
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_MODE_IS_EXCLUDE:
|
|
|
|
case IGMP_V3_CHANGE_TO_EXCLUDE_MODE:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
2014-06-29 13:13:51 +00:00
|
|
|
" / Join group %s for any sources", maddr_str);
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_ALLOW_NEW_SOURCES:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Group %s, ALLOW_NEW_SOURCES but no source specified (?)",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str);
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_BLOCK_OLD_SOURCES:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Group %s, BLOCK_OLD_SOURCES but no source specified (?)",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str);
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
2014-06-29 13:13:51 +00:00
|
|
|
" / Group %s, unknown record type (?)", maddr_str);
|
2012-04-13 20:22:31 +00:00
|
|
|
break;
|
2011-09-26 20:34:33 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch(record_type) {
|
|
|
|
case IGMP_V3_MODE_IS_INCLUDE:
|
|
|
|
case IGMP_V3_CHANGE_TO_INCLUDE_MODE:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Join group %s for source%s {",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str, (num>1) ? "s in" : "");
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_MODE_IS_EXCLUDE:
|
|
|
|
case IGMP_V3_CHANGE_TO_EXCLUDE_MODE:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Join group %s, for source%s {",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str, (num>1) ? "s not in" : " not");
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_ALLOW_NEW_SOURCES:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Group %s, new source%s {",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str, (num>1) ? "s" : "");
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V3_BLOCK_OLD_SOURCES:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Group %s, block source%s {",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str, (num>1) ? "s" : "");
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO,
|
|
|
|
" / Group %s, unknown record type (?), sources {",
|
2014-06-29 13:13:51 +00:00
|
|
|
maddr_str);
|
2011-09-26 20:34:33 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-01-25 06:32:53 +00:00
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
/* source addresses */
|
|
|
|
while(num--){
|
2013-06-14 01:02:11 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
|
2011-09-26 20:34:33 +00:00
|
|
|
tvb_ip_to_str(tvb, offset), (num?", ":"}"));
|
2013-06-14 01:02:11 +00:00
|
|
|
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_saddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* aux data */
|
|
|
|
if(adl){
|
2011-10-04 22:44:31 +00:00
|
|
|
proto_tree_add_item(tree, hf_aux_data, tvb, offset, adl*4, ENC_NA);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += adl*4;
|
|
|
|
}
|
|
|
|
|
|
|
|
proto_item_set_len(item, offset-old_offset);
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2008-01-25 06:32:53 +00:00
|
|
|
/* dissectors for version 3, rfc3376 */
|
2001-05-20 22:20:33 +00:00
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_v3_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
2001-05-20 22:20:33 +00:00
|
|
|
guint16 num;
|
2014-11-07 12:47:43 +00:00
|
|
|
int offset;
|
|
|
|
unsigned char type;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
tree = dissect_igmp_common(tvb, pinfo, parent_tree, &offset, &type, 3);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* skip reserved field*/
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
|
|
|
|
offset += 2;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* skip reserved field */
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* number of group records */
|
|
|
|
num = tvb_get_ntohs(tvb, offset);
|
2011-09-26 20:34:33 +00:00
|
|
|
if (!num)
|
2013-10-29 14:09:20 +00:00
|
|
|
col_append_str(pinfo->cinfo, COL_INFO, " - General query");
|
2011-09-26 20:34:33 +00:00
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
proto_tree_add_uint(tree, hf_num_grp_recs, tvb, offset, 2, num);
|
|
|
|
offset += 2;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2011-09-26 20:34:33 +00:00
|
|
|
while (num--)
|
2008-01-25 06:32:53 +00:00
|
|
|
offset = dissect_v3_group_record(tvb, pinfo, tree, offset);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_v3_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
2001-05-20 22:20:33 +00:00
|
|
|
guint16 num;
|
2014-11-07 12:47:43 +00:00
|
|
|
int offset;
|
|
|
|
unsigned char type;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
tree = dissect_igmp_common(tvb, pinfo, parent_tree, &offset, &type, 3);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
num = tvb_get_ntohs(tvb, offset+9);
|
|
|
|
/* max resp code */
|
2002-05-02 07:54:41 +00:00
|
|
|
offset = dissect_v3_max_resp(tvb, tree, offset);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* group address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2008-01-25 06:32:53 +00:00
|
|
|
|
2014-12-21 13:02:26 +00:00
|
|
|
if (!tvb_get_ipv4(tvb, offset)) {
|
2013-10-29 14:09:20 +00:00
|
|
|
col_append_str(pinfo->cinfo, COL_INFO, ", general");
|
2011-09-26 20:34:33 +00:00
|
|
|
} else {
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", specific for group %s",
|
2014-12-21 13:02:26 +00:00
|
|
|
tvb_ip_to_str(tvb, offset));
|
2011-09-26 20:34:33 +00:00
|
|
|
}
|
2001-05-20 22:20:33 +00:00
|
|
|
offset +=4;
|
|
|
|
|
|
|
|
/* bitmask for S and QRV */
|
2002-05-02 07:54:41 +00:00
|
|
|
offset = dissect_v3_sqrv_bits(tvb, tree, offset);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* qqic */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_qqic, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/*number of sources*/
|
|
|
|
proto_tree_add_uint(tree, hf_num_src, tvb, offset, 2, num);
|
2011-09-26 20:34:33 +00:00
|
|
|
if (num) {
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", source%s {", (num>1)?"s":"");
|
|
|
|
}
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
while(num--){
|
2013-06-14 01:02:11 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s", tvb_ip_to_str(tvb, offset), (num?", ":"}"));
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_saddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2008-01-25 06:32:53 +00:00
|
|
|
/* dissector for version 2 query and report, rfc2236 */
|
2001-05-20 22:20:33 +00:00
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
2001-05-20 22:20:33 +00:00
|
|
|
guint8 tsecs;
|
2014-11-07 12:47:43 +00:00
|
|
|
int offset;
|
|
|
|
unsigned char type;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
tree = dissect_igmp_common(tvb, pinfo, parent_tree, &offset, &type, 2);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* max resp time */
|
|
|
|
tsecs = tvb_get_guint8(tvb, offset);
|
2013-09-16 10:39:06 +00:00
|
|
|
proto_tree_add_uint_format_value(tree, hf_max_resp, tvb,
|
|
|
|
offset, 1, tsecs, "%.1f sec (0x%02x)", tsecs*0.1,tsecs);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 8);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* group address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2008-01-25 06:32:53 +00:00
|
|
|
|
2014-12-21 13:02:26 +00:00
|
|
|
if (! tvb_get_ipv4(tvb, offset)) {
|
2013-10-29 14:09:20 +00:00
|
|
|
col_append_str(pinfo->cinfo, COL_INFO, ", general");
|
2011-09-26 20:34:33 +00:00
|
|
|
} else {
|
2014-11-07 12:47:43 +00:00
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case IGMP_V2_LEAVE_GROUP:
|
2014-12-21 13:02:26 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tvb_ip_to_str(tvb, offset));
|
2014-11-07 12:47:43 +00:00
|
|
|
break;
|
|
|
|
case IGMP_V1_HOST_MEMBERSHIP_QUERY:
|
2014-12-21 13:02:26 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", specific for group %s", tvb_ip_to_str(tvb, offset));
|
2014-11-07 12:47:43 +00:00
|
|
|
break;
|
|
|
|
default: /* IGMP_V2_MEMBERSHIP_REPORT is the only case left */
|
2014-12-21 13:02:26 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " group %s", tvb_ip_to_str(tvb, offset));
|
2014-11-07 12:47:43 +00:00
|
|
|
break;
|
2008-01-25 06:32:53 +00:00
|
|
|
}
|
2011-09-26 20:34:33 +00:00
|
|
|
}
|
2001-05-20 22:20:33 +00:00
|
|
|
offset +=4;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2008-01-25 06:32:53 +00:00
|
|
|
/* dissector for version 1 query and report, rfc1054 */
|
2001-05-20 22:20:33 +00:00
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
|
|
|
int offset;
|
|
|
|
unsigned char type;
|
|
|
|
|
|
|
|
tree = dissect_igmp_common(tvb, pinfo, parent_tree, &offset, &type, 1);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* skip unused byte */
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 8);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* group address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset +=4;
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* dissector for version 0, rfc988 */
|
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_v0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-05-20 22:20:33 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
2001-05-20 22:20:33 +00:00
|
|
|
unsigned char code;
|
2014-11-07 12:47:43 +00:00
|
|
|
int offset;
|
|
|
|
unsigned char type;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
tree = dissect_igmp_common(tvb, pinfo, parent_tree, &offset, &type, 0);
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* Code */
|
|
|
|
code = tvb_get_guint8(tvb, offset);
|
|
|
|
if (type==IGMP_V0_CREATE_GROUP_REQUEST) {
|
|
|
|
proto_tree_add_uint(tree, hf_group_type, tvb, offset, 1, code);
|
|
|
|
} else if (!(type&0x01)) {
|
|
|
|
if (code <5) {
|
|
|
|
proto_tree_add_uint(tree, hf_reply_code, tvb, offset, 1, code);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_uint(tree, hf_reply_pending, tvb, offset, 1, code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 20);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* identifier */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-05-20 22:20:33 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* group address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
|
|
offset += 4;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
/* access key */
|
2011-10-04 22:44:31 +00:00
|
|
|
proto_tree_add_item(tree, hf_access_key, tvb, offset, 8, ENC_NA);
|
2011-09-26 20:34:33 +00:00
|
|
|
offset += 8;
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
return offset;
|
|
|
|
}
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
static int
|
|
|
|
dissect_igmp_mquery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
|
|
|
|
{
|
|
|
|
if ( tvb_reported_length(tvb)>=12 ) {
|
|
|
|
/* version 3 */
|
|
|
|
return dissect_igmp_v3_query(tvb, pinfo, parent_tree, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* v1 and v2 differs in second byte of header */
|
|
|
|
if (tvb_get_guint8(tvb, 1)) {
|
|
|
|
return dissect_igmp_v2(tvb, pinfo, parent_tree, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dissect_igmp_v1(tvb, pinfo, parent_tree, data);
|
|
|
|
}
|
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
/* dissector for multicast traceroute, rfc???? */
|
|
|
|
static int
|
2014-11-07 12:47:43 +00:00
|
|
|
dissect_igmp_mtrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
|
2001-07-10 20:55:54 +00:00
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
proto_tree* tree;
|
|
|
|
proto_item* ti;
|
|
|
|
int offset = 0;
|
|
|
|
unsigned char type;
|
2005-07-30 16:28:00 +00:00
|
|
|
const char *typestr, *blocks = NULL;
|
2001-07-10 20:55:54 +00:00
|
|
|
char buf[20];
|
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
ti = proto_tree_add_item(parent_tree, proto_igmp, tvb, offset, -1, ENC_NA);
|
|
|
|
tree = proto_item_add_subtree(ti, ett_igmp);
|
|
|
|
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGMP");
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
/* All multicast traceroute packets (Query, Request and
|
|
|
|
* Response) have the same fixed header. Request and Response
|
|
|
|
* have one or more response data blocks following this fixed
|
|
|
|
* header. Since Query and Request share the same IGMP type,
|
|
|
|
* the method to differentiate between them is to check the
|
|
|
|
* IGMP packet length. Queries are only
|
|
|
|
* IGMP_TRACEROUTE_HDR_LEN bytes long.
|
|
|
|
*/
|
2014-11-07 12:47:43 +00:00
|
|
|
type = tvb_get_guint8(tvb, offset);
|
2001-07-10 20:55:54 +00:00
|
|
|
if (type == IGMP_TRACEROUTE_RESPONSE) {
|
|
|
|
int i = (tvb_reported_length_remaining(tvb, offset) - IGMP_TRACEROUTE_HDR_LEN) / IGMP_TRACEROUTE_RSP_LEN;
|
2005-08-08 18:50:39 +00:00
|
|
|
g_snprintf(buf, sizeof buf, ", %d block%s", i, plurality(i, "", "s"));
|
2001-07-10 20:55:54 +00:00
|
|
|
typestr = "Traceroute Response";
|
|
|
|
blocks = buf;
|
2001-07-11 04:24:34 +00:00
|
|
|
} else if (tvb_reported_length_remaining(tvb, offset) == IGMP_TRACEROUTE_HDR_LEN)
|
2001-07-10 20:55:54 +00:00
|
|
|
typestr = "Traceroute Query";
|
|
|
|
else
|
|
|
|
typestr = "Traceroute Request";
|
|
|
|
|
2011-09-26 20:34:33 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, typestr);
|
|
|
|
if (blocks)
|
|
|
|
col_append_str(pinfo->cinfo, COL_INFO, blocks);
|
2001-07-10 20:55:54 +00:00
|
|
|
|
2013-09-15 01:48:30 +00:00
|
|
|
proto_tree_add_uint_format_value(tree, hf_type, tvb, offset, 1, type,
|
|
|
|
"%s (0x%02x)", typestr, type);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* maximum number of hops that the requester wants to trace */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_max_hops, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
2001-07-11 04:24:34 +00:00
|
|
|
/* checksum */
|
2002-02-01 11:01:57 +00:00
|
|
|
igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
/* group address to be traced */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* address of multicast source for the path being traced */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_saddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* address of multicast receiver for the path being traced */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_raddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* address where the completed traceroute response packet gets sent */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_rspaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* for multicasted responses, TTL at which to multicast the response */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_resp_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* unique identifier for this traceroute request (for e.g. duplicate/delay detection) */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(tree, hf_mtrace_q_id, tvb, offset, 3, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 3;
|
|
|
|
|
|
|
|
/* If this was Query, we only had the fixed header */
|
|
|
|
if (tvb_reported_length_remaining(tvb, offset) == 0)
|
|
|
|
return offset;
|
|
|
|
|
|
|
|
/* Loop through the response data blocks */
|
2011-09-26 20:34:33 +00:00
|
|
|
while (tvb_reported_length_remaining(tvb, offset) >= IGMP_TRACEROUTE_RSP_LEN) {
|
|
|
|
proto_tree *block_tree;
|
|
|
|
|
2014-06-29 13:13:51 +00:00
|
|
|
block_tree = proto_tree_add_subtree_format(tree, tvb, offset, IGMP_TRACEROUTE_RSP_LEN,
|
|
|
|
ett_mtrace_block, NULL, "Response data block: %s -> %s, Proto: %s, Forwarding Code: %s",
|
2011-09-26 20:34:33 +00:00
|
|
|
tvb_ip_to_str(tvb, offset + 4),
|
|
|
|
tvb_ip_to_str(tvb, offset + 8),
|
2012-08-10 22:55:02 +00:00
|
|
|
val_to_str_const(tvb_get_guint8(tvb, offset + 28), mtrace_rtg_vals, "Unknown"),
|
|
|
|
val_to_str_const(tvb_get_guint8(tvb, offset + 31), mtrace_fwd_code_vals, "Unknown"));
|
2001-07-10 20:55:54 +00:00
|
|
|
|
|
|
|
/* Query Arrival Time */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_arrival, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Incoming Interface Address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_inaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Outgoing Interface Address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_outaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Previous-Hop Router Address */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_prevrtr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Input packet count on incoming interface */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_inpkt, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Output packet count on outgoing interface */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_outpkt, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Total number of packets for this source-group pair */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_total, tvb, offset, 4, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 4;
|
|
|
|
|
|
|
|
/* Routing protocol in use between this and previous-hop router */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_rtg_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* TTL that a packet is required to be forwarded */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_fwd_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* Must be zeroed and ignored bit, S bit and src network mask length */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_mbz, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_s, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_src_mask, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
|
|
|
|
/* Forwarding information/error code */
|
2011-09-26 20:34:33 +00:00
|
|
|
proto_tree_add_item(block_tree, hf_mtrace_q_fwd_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
2001-07-10 20:55:54 +00:00
|
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
static void
|
|
|
|
dissect_igmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
unsigned char type;
|
|
|
|
|
|
|
|
type = tvb_get_guint8(tvb, offset);
|
|
|
|
|
2014-11-07 12:47:43 +00:00
|
|
|
if (!dissector_try_uint(subdissector_table, type, tvb, pinfo, parent_tree))
|
|
|
|
{
|
|
|
|
dissect_igmp_unknown(tvb, pinfo, parent_tree);
|
2001-05-20 22:20:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_igmp(void)
|
|
|
|
{
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_type,
|
|
|
|
{ "Type", "igmp.type", FT_UINT8, BASE_HEX,
|
2001-06-18 02:18:27 +00:00
|
|
|
VALS(commands), 0, "IGMP Packet Type", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_version,
|
|
|
|
{ "IGMP Version", "igmp.version", FT_UINT8, BASE_DEC,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0, NULL, HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_group_type,
|
|
|
|
{ "Type Of Group", "igmp.group_type", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
VALS(vs_group_type), 0, "IGMP V0 Type Of Group", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_reply_code,
|
|
|
|
{ "Reply", "igmp.reply", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
VALS(vs_reply_code), 0, "IGMP V0 Reply", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_reply_pending,
|
|
|
|
{ "Reply Pending", "igmp.reply.pending", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "IGMP V0 Reply Pending, Retry in this many seconds", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_checksum,
|
|
|
|
{ "Checksum", "igmp.checksum", FT_UINT16, BASE_HEX,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "IGMP Checksum", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_checksum_bad,
|
|
|
|
{ "Bad Checksum", "igmp.checksum_bad", FT_BOOLEAN, BASE_NONE,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0x0, "Bad IGMP Checksum", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_identifier,
|
|
|
|
{ "Identifier", "igmp.identifier", FT_UINT32, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "IGMP V0 Identifier", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_access_key,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
{ "Access Key", "igmp.access_key", FT_BYTES, BASE_NONE,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "IGMP V0 Access Key", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_max_resp,
|
|
|
|
{ "Max Resp Time", "igmp.max_resp", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "Max Response Time", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2006-01-05 13:01:08 +00:00
|
|
|
{ &hf_suppress,
|
2001-05-20 22:20:33 +00:00
|
|
|
{ "S", "igmp.s", FT_BOOLEAN, 8,
|
2006-01-05 13:01:08 +00:00
|
|
|
TFS(&tfs_s), IGMP_V3_S, "Suppress Router Side Processing", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_qrv,
|
|
|
|
{ "QRV", "igmp.qrv", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, IGMP_V3_QRV_MASK, "Querier's Robustness Value", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_qqic,
|
|
|
|
{ "QQIC", "igmp.qqic", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "Querier's Query Interval Code", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_num_src,
|
|
|
|
{ "Num Src", "igmp.num_src", FT_UINT16, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "Number Of Sources", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_saddr,
|
|
|
|
{ "Source Address", "igmp.saddr", FT_IPv4, BASE_NONE,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0, NULL, HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_num_grp_recs,
|
|
|
|
{ "Num Group Records", "igmp.num_grp_recs", FT_UINT16, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "Number Of Group Records", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_record_type,
|
|
|
|
{ "Record Type", "igmp.record_type", FT_UINT8, BASE_DEC,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
VALS(vs_record_type), 0, NULL, HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_aux_data_len,
|
|
|
|
{ "Aux Data Len", "igmp.aux_data_len", FT_UINT8, BASE_DEC,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "Aux Data Len, In units of 32bit words", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_maddr,
|
|
|
|
{ "Multicast Address", "igmp.maddr", FT_IPv4, BASE_NONE,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, 0, NULL, HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_aux_data,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
{ "Aux Data", "igmp.aux_data", FT_BYTES, BASE_NONE,
|
2001-06-18 02:18:27 +00:00
|
|
|
NULL, 0, "IGMP V3 Auxiliary Data", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2014-08-09 17:43:44 +00:00
|
|
|
{ &hf_data,
|
|
|
|
{ "Data", "igmp.data", FT_BYTES, BASE_NONE,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
{ &hf_max_resp_exp,
|
|
|
|
{ "Exponent", "igmp.max_resp.exp", FT_UINT8, BASE_HEX,
|
2008-12-18 19:08:49 +00:00
|
|
|
NULL, IGMP_MAX_RESP_EXP, "Maximum Response Time, Exponent", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
|
|
|
{ &hf_max_resp_mant,
|
|
|
|
{ "Mantissa", "igmp.max_resp.mant", FT_UINT8, BASE_HEX,
|
2008-12-18 19:08:49 +00:00
|
|
|
NULL, IGMP_MAX_RESP_MANT, "Maximum Response Time, Mantissa", HFILL }},
|
2001-05-20 22:20:33 +00:00
|
|
|
|
2001-07-10 20:55:54 +00:00
|
|
|
{ &hf_mtrace_max_hops,
|
|
|
|
{ "# hops", "igmp.mtrace.max_hops", FT_UINT8, BASE_DEC,
|
2008-12-18 19:08:49 +00:00
|
|
|
NULL, 0, "Maximum Number of Hops to Trace", HFILL }},
|
2001-07-10 20:55:54 +00:00
|
|
|
|
|
|
|
{ &hf_mtrace_saddr,
|
|
|
|
{ "Source Address", "igmp.mtrace.saddr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Multicast Source for the Path Being Traced", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_raddr,
|
|
|
|
{ "Receiver Address", "igmp.mtrace.raddr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Multicast Receiver for the Path Being Traced", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_rspaddr,
|
|
|
|
{ "Response Address", "igmp.mtrace.rspaddr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Destination of Completed Traceroute Response", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_resp_ttl,
|
|
|
|
{ "Response TTL", "igmp.mtrace.resp_ttl", FT_UINT8, BASE_DEC,
|
|
|
|
NULL, 0, "TTL for Multicasted Responses", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_id,
|
|
|
|
{ "Query ID", "igmp.mtrace.q_id", FT_UINT24, BASE_DEC,
|
|
|
|
NULL, 0, "Identifier for this Traceroute Request", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_arrival,
|
|
|
|
{ "Query Arrival", "igmp.mtrace.q_arrival", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, "Query Arrival Time", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_inaddr,
|
|
|
|
{ "In itf addr", "igmp.mtrace.q_inaddr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Incoming Interface Address", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_outaddr,
|
|
|
|
{ "Out itf addr", "igmp.mtrace.q_outaddr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Outgoing Interface Address", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_prevrtr,
|
|
|
|
{ "Previous rtr addr", "igmp.mtrace.q_prevrtr", FT_IPv4, BASE_NONE,
|
|
|
|
NULL, 0, "Previous-Hop Router Address", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_inpkt,
|
|
|
|
{ "In pkts", "igmp.mtrace.q_inpkt", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, "Input packet count on incoming interface", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_outpkt,
|
|
|
|
{ "Out pkts", "igmp.mtrace.q_outpkt", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, "Output packet count on outgoing interface", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_total,
|
|
|
|
{ "S,G pkt count", "igmp.mtrace.q_total", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, "Total number of packets for this source-group pair", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_rtg_proto,
|
|
|
|
{ "Rtg Protocol", "igmp.mtrace.q_rtg_proto", FT_UINT8, BASE_DEC,
|
2009-11-17 18:35:27 +00:00
|
|
|
VALS(mtrace_rtg_vals), 0, "Routing protocol between this and previous hop rtr", HFILL }},
|
2001-07-10 20:55:54 +00:00
|
|
|
|
|
|
|
{ &hf_mtrace_q_fwd_ttl,
|
|
|
|
{ "FwdTTL", "igmp.mtrace.q_fwd_ttl", FT_UINT8, BASE_DEC,
|
|
|
|
NULL, 0, "TTL required for forwarding", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_mbz,
|
|
|
|
{ "MBZ", "igmp.mtrace.q_mbz", FT_UINT8, BASE_HEX,
|
|
|
|
NULL, 0x80, "Must be zeroed on transmission and ignored on reception", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_s,
|
|
|
|
{ "S", "igmp.mtrace.q_s", FT_UINT8, BASE_HEX,
|
|
|
|
NULL, 0x40, "Set if S,G packet count is for source network", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_src_mask,
|
|
|
|
{ "Src Mask", "igmp.mtrace.q_src_mask", FT_UINT8, BASE_HEX,
|
|
|
|
NULL, 0x3F, "Source mask length. 63 when forwarding on group state", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_mtrace_q_fwd_code,
|
|
|
|
{ "Forwarding Code", "igmp.mtrace.q_fwd_code", FT_UINT8, BASE_HEX,
|
2009-11-17 18:35:27 +00:00
|
|
|
VALS(mtrace_fwd_code_vals), 0, "Forwarding information/error code", HFILL }},
|
2001-07-10 20:55:54 +00:00
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_igmp,
|
|
|
|
&ett_group_record,
|
|
|
|
&ett_sqrv_bits,
|
|
|
|
&ett_max_resp,
|
2001-07-10 20:55:54 +00:00
|
|
|
&ett_mtrace_block,
|
2001-05-20 22:20:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
proto_igmp = proto_register_protocol("Internet Group Management Protocol",
|
2011-09-28 19:38:03 +00:00
|
|
|
"IGMP", "igmp");
|
2001-05-20 22:20:33 +00:00
|
|
|
proto_register_field_array(proto_igmp, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2014-11-07 12:47:43 +00:00
|
|
|
|
|
|
|
subdissector_table = register_dissector_table("igmp.type", "IGMP commands", FT_UINT32, BASE_HEX);
|
|
|
|
|
2001-05-20 22:20:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_igmp(void)
|
|
|
|
{
|
2014-11-07 12:47:43 +00:00
|
|
|
dissector_handle_t igmp_handle, igmpv0_handle, igmpv1_handle, igmpv2_handle,
|
|
|
|
igmp_mquery_handle, igmp_mtrace_handle, igmp_report_handle;
|
|
|
|
range_t *igmpv0_range;
|
2001-12-03 04:00:26 +00:00
|
|
|
|
|
|
|
igmp_handle = create_dissector_handle(dissect_igmp, proto_igmp);
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("ip.proto", IP_PROTO_IGMP, igmp_handle);
|
2014-11-07 12:47:43 +00:00
|
|
|
|
|
|
|
/* IGMP v0 */
|
|
|
|
range_convert_str(&igmpv0_range, "0-15", 15);
|
|
|
|
igmpv0_handle = new_create_dissector_handle(dissect_igmp_v0, proto_igmp);
|
|
|
|
dissector_add_uint_range("igmp.type", igmpv0_range, igmpv0_handle);
|
|
|
|
|
|
|
|
/* IGMP v1 */
|
|
|
|
igmpv1_handle = new_create_dissector_handle(dissect_igmp_v1, proto_igmp);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_V1_HOST_MEMBERSHIP_REPORT, igmpv1_handle);
|
|
|
|
|
|
|
|
/* IGMP v2 */
|
|
|
|
igmpv2_handle = new_create_dissector_handle(dissect_igmp_v2, proto_igmp);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_V2_MEMBERSHIP_REPORT, igmpv2_handle);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_V2_LEAVE_GROUP, igmpv2_handle);
|
|
|
|
|
|
|
|
/* IGMP_V1_HOST_MEMBERSHIP_QUERY, all versions */
|
|
|
|
igmp_mquery_handle = new_create_dissector_handle(dissect_igmp_mquery, proto_igmp);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_V1_HOST_MEMBERSHIP_QUERY, igmp_mquery_handle);
|
|
|
|
|
|
|
|
igmp_report_handle = new_create_dissector_handle(dissect_igmp_v3_report, proto_igmp);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_V3_MEMBERSHIP_REPORT, igmp_report_handle);
|
|
|
|
|
|
|
|
igmp_mtrace_handle = new_create_dissector_handle(dissect_igmp_mtrace, proto_igmp);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_TRACEROUTE_RESPONSE, igmp_mtrace_handle);
|
|
|
|
dissector_add_uint("igmp.type", IGMP_TRACEROUTE_QUERY_REQ, igmp_mtrace_handle);
|
2001-05-20 22:20:33 +00:00
|
|
|
}
|
2011-09-28 19:38:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
|
|
*
|
|
|
|
* Local variables:
|
2014-09-10 16:07:04 +00:00
|
|
|
* c-basic-offset: 8
|
2011-09-28 19:38:03 +00:00
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: t
|
|
|
|
* End:
|
|
|
|
*
|
2014-09-10 16:07:04 +00:00
|
|
|
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
|
|
|
|
* :indentSize=8:tabSize=8:noTabs=false:
|
2011-09-28 19:38:03 +00:00
|
|
|
*/
|
|
|
|
|