Based on RFC3488. This is a setup for RGMP dissection, a simple protocol bolted on...
[obnox/wireshark/wip.git] / epan / dissectors / packet-igmp.c
index 890c2340439c94cab609a6a751e5780855479741..17bdb8b87af1b4182beaeadbfb8f9badda867e61 100644 (file)
@@ -3,8 +3,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -19,7 +19,7 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 /*
        IGMP is defined in the following RFCs
@@ -30,7 +30,7 @@
        RFC3376 Version 3
 
        Size in bytes for each packet
-       type    RFC988  RFC1054 RFC2236 RFC3376  DVMRP  MRDISC  MSNIP  IGAP
+       type    RFC988  RFC1054 RFC2236 RFC3376  DVMRP  MRDISC  MSNIP  IGAP  RGMP
                v0      v1      v2      v3       v1/v3
        0x01      20
        0x02      20
        0x40                                                           ??c
        0x41                                                           ??c
        0x42                                                           ??c
+       0xfc                                                                  8
+       0xfd                                                                  8
+       0xfe                                                                  8
+       0xff                                                                  8
 
    * Differs in second byte of protocol. Always 0 in V1
 
         IGAP : Internet Group membership Authentication Protocol
        draft-hayashi-igap-03.txt
 
+   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
+
 */
 
 #ifdef HAVE_CONFIG_H
 #include <string.h>
 #include <glib.h>
 
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
 #include <epan/packet.h>
 #include <epan/ipproto.h>
 #include <epan/in_cksum.h>
+#include "packet-igmp.h"
 #include "packet-dvmrp.h"
 #include "packet-pim.h"
 #include "packet-mrdisc.h"
 #include "packet-msnip.h"
 #include "packet-igap.h"
+#include "packet-rgmp.h"
 
 static int proto_igmp = -1;
 static int hf_type = -1;
@@ -129,7 +137,7 @@ 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;
-static int hf_supress = -1;
+static int hf_suppress = -1;
 static int hf_qrv = -1;
 static int hf_qqic = -1;
 static int hf_num_src = -1;
@@ -167,6 +175,7 @@ static int ett_mtrace_block = -1;
 
 #define MC_ALL_ROUTERS         0xe0000002
 #define MC_ALL_IGMPV3_ROUTERS  0xe0000016
+#define MC_RGMP                        0xe0000019
 
 
 #define IGMP_V0_CREATE_GROUP_REQUEST   0x01
@@ -246,8 +255,8 @@ static const value_string vs_reply_code[] = {
 };
 
 static const true_false_string tfs_s = {
-       "SUPRESS router side processing",
-       "Do not supress router side processing"
+       "SUPPRESS router side processing",
+       "Do not suppress router side processing"
 };
 
 #define IGMP_V3_MODE_IS_INCLUDE                1
@@ -431,7 +440,7 @@ dissect_v3_sqrv_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        tree = proto_item_add_subtree(item, ett_sqrv_bits);
 
        /* S flag */
-       proto_tree_add_boolean(tree, hf_supress, tvb, offset, 1, bits);
+       proto_tree_add_boolean(tree, hf_suppress, tvb, offset, 1, bits);
        /* QRV */
        proto_tree_add_uint(tree, hf_qrv, tvb, offset, 1, bits);
        offset += 1;
@@ -449,7 +458,7 @@ dissect_v3_group_record(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        guint16 num;
        guint32 ip;
 
-       tvb_memcpy(tvb, (guint8 *)&ip, offset+4, 4);
+       ip = tvb_get_ipv4(tvb, offset+4);
        item = proto_tree_add_text(parent_tree, tvb, offset, -1,
                "Group Record : %s  %s",
                        ip_to_str((guint8*)&ip),
@@ -649,7 +658,7 @@ dissect_igmp_v0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int type, i
 static int
 dissect_igmp_mtrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int type, int offset)
 {
-       char *typestr, *blocks = NULL;
+       const char *typestr, *blocks = NULL;
        char buf[20];
 
        /* All multicast traceroute packets (Query, Request and
@@ -662,7 +671,7 @@ dissect_igmp_mtrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int typ
         */
        if (type == IGMP_TRACEROUTE_RESPONSE) {
                int i = (tvb_reported_length_remaining(tvb, offset) - IGMP_TRACEROUTE_HDR_LEN) / IGMP_TRACEROUTE_RSP_LEN;
-               snprintf(buf, sizeof buf, ", %d block%s", i, plurality(i, "", "s"));
+               g_snprintf(buf, sizeof buf, ", %d block%s", i, plurality(i, "", "s"));
                typestr = "Traceroute Response";
                blocks = buf;
        } else if (tvb_reported_length_remaining(tvb, offset) == IGMP_TRACEROUTE_HDR_LEN)
@@ -895,6 +904,16 @@ dissect_igmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                offset = dissect_igap(tvb, pinfo, parent_tree, offset);
                break;
 
+       case IGMP_RGMP_HELLO:
+       case IGMP_RGMP_BYE:
+       case IGMP_RGMP_JOIN:
+       case IGMP_RGMP_LEAVE:
+               dst = g_htonl(MC_RGMP);
+               if (!memcmp(pinfo->dst.data, &dst, 4)) {
+                       offset = dissect_rgmp(tvb, pinfo, parent_tree, offset);
+               }
+               break;
+
        default:
                offset = dissect_igmp_unknown(tvb, pinfo, tree, type, offset);
                break;
@@ -948,9 +967,9 @@ proto_register_igmp(void)
                        { "Max Resp Time", "igmp.max_resp", FT_UINT8, BASE_DEC,
                          NULL, 0, "Max Response Time", HFILL }},
 
-               { &hf_supress,
+               { &hf_suppress,
                        { "S", "igmp.s", FT_BOOLEAN, 8,
-                         TFS(&tfs_s), IGMP_V3_S, "Supress Router Side Processing", HFILL }},
+                         TFS(&tfs_s), IGMP_V3_S, "Suppress Router Side Processing", HFILL }},
 
                { &hf_qrv,
                        { "QRV", "igmp.qrv", FT_UINT8, BASE_DEC,