Based on RFC3488. This is a setup for RGMP dissection, a simple protocol bolted on...
[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     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
81         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RGMP");
82     }
83     if (check_col(pinfo->cinfo, COL_INFO)) {
84         col_clear(pinfo->cinfo, COL_INFO);
85     }
86
87     type = tvb_get_guint8(tvb, offset);
88     if (check_col(pinfo->cinfo, COL_INFO)) {
89         col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
90                      val_to_str(type, rgmp_types, "Unknown Type: 0x%02x"));
91     }
92     proto_tree_add_uint(tree, hf_type, tvb, offset, 1, type);
93     offset += 1;
94
95     /* reserved */
96
97     offset += 1;
98
99     igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
100     offset += 2;
101
102     proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, FALSE);
103     offset += 4;
104
105     return offset;
106 }
107
108
109 void
110 proto_register_rgmp(void)
111 {
112     static hf_register_info hf[] = {
113         { &hf_type,
114           { "Type", "rgmp.type", FT_UINT8, BASE_HEX,
115             VALS(rgmp_types), 0, "RGMP Packet Type", HFILL }
116         },
117
118         { &hf_checksum,
119           { "Checksum", "rgmp.checksum", FT_UINT16, BASE_HEX,
120             NULL, 0, "Checksum", HFILL }
121         },
122
123         { &hf_checksum_bad,
124           { "Bad Checksum", "rgmp.checksum_bad", FT_BOOLEAN, BASE_NONE,
125             NULL, 0, "Bad Checksum", HFILL }
126         },
127
128         { &hf_maddr,
129           { "Multicast group address", "rgmp.maddr", FT_IPv4, BASE_NONE,
130             NULL, 0, "Multicast group address", HFILL }
131         }
132     };
133
134     static gint *ett[] = {
135         &ett_rgmp
136     };
137
138     proto_rgmp = proto_register_protocol
139         ("Router-port Group Management Protocol", "RGMP", "rgmp");
140     proto_register_field_array(proto_rgmp, hf, array_length(hf));
141     proto_register_subtree_array(ett, array_length(ett));
142 }