5fad192a4cce23c3611ef7f46c2152ab95c1e16f
[obnox/wireshark/wip.git] / epan / dissectors / packet-rgmp.c
1 /* packet-rgmp.c
2  * Routines for IGMP/RGMP packet disassembly
3  * Copyright 2006 Jaap Keuter
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 /* 
27  Based on RFC3488 
28
29  This is a setup for RGMP dissection, a simple protocol bolted on IGMP.
30  The trick is to have IGMP dissector call this function (which by itself is not
31  registered as dissector). IGAP and other do the same.
32
33  */
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <glib.h>
40 #include <epan/packet.h>
41 #include <epan/strutil.h>
42 #include "packet-igmp.h"
43 #include "packet-rgmp.h"
44
45
46 static int proto_rgmp      = -1;
47 static int hf_type         = -1;
48 static int hf_checksum     = -1;
49 static int hf_checksum_bad = -1;
50 static int hf_maddr        = -1;
51
52 static int ett_rgmp = -1;
53
54 static const value_string rgmp_types[] = {
55     {IGMP_RGMP_LEAVE, "Leave"},
56     {IGMP_RGMP_JOIN,  "Join"},
57     {IGMP_RGMP_BYE,   "Bye"},
58     {IGMP_RGMP_HELLO, "Hello"},
59     {0, NULL}
60 };
61
62 /* This function is only called from the IGMP dissector */
63 int
64 dissect_rgmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
65 {
66     proto_tree *tree;
67     proto_item *item;
68     guint8 type;
69
70     if (!proto_is_protocol_enabled(find_protocol_by_id(proto_rgmp))) {
71         /* we are not enabled, skip entire packet to be nice
72            to the igmp layer. (so clicking on IGMP will display the data)
73            */
74         return offset + tvb_length_remaining(tvb, offset);
75     }
76
77     item = proto_tree_add_item(parent_tree, proto_rgmp, tvb, offset, -1, FALSE);
78     tree = proto_item_add_subtree(item, ett_rgmp);
79
80     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RGMP");
81     col_clear(pinfo->cinfo, COL_INFO);
82
83     type = tvb_get_guint8(tvb, offset);
84     if (check_col(pinfo->cinfo, COL_INFO)) {
85         col_add_str(pinfo->cinfo, COL_INFO, 
86                      val_to_str(type, rgmp_types, "Unknown Type: 0x%02x"));
87     }
88     proto_tree_add_uint(tree, hf_type, tvb, offset, 1, type);
89     offset += 1;
90
91     /* reserved */
92
93     offset += 1;
94
95     igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
96     offset += 2;
97
98     proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
99     offset += 4;
100
101     return offset;
102 }
103
104
105 void
106 proto_register_rgmp(void)
107 {
108     static hf_register_info hf[] = {
109         { &hf_type,
110           { "Type", "rgmp.type", FT_UINT8, BASE_HEX,
111             VALS(rgmp_types), 0, "RGMP Packet Type", HFILL }
112         },
113
114         { &hf_checksum,
115           { "Checksum", "rgmp.checksum", FT_UINT16, BASE_HEX,
116             NULL, 0, NULL, HFILL }
117         },
118
119         { &hf_checksum_bad,
120           { "Bad Checksum", "rgmp.checksum_bad", FT_BOOLEAN, BASE_NONE,
121             NULL, 0x0, NULL, HFILL }
122         },
123
124         { &hf_maddr,
125           { "Multicast group address", "rgmp.maddr", FT_IPv4, BASE_NONE,
126             NULL, 0, NULL, HFILL }
127         }
128     };
129
130     static gint *ett[] = {
131         &ett_rgmp
132     };
133
134     proto_rgmp = proto_register_protocol
135         ("Router-port Group Management Protocol", "RGMP", "rgmp");
136     proto_register_field_array(proto_rgmp, hf, array_length(hf));
137     proto_register_subtree_array(ett, array_length(ett));
138 }