aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ip.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-10-31 22:03:53 +0000
committerGuy Harris <guy@alum.mit.edu>2001-10-31 22:03:53 +0000
commitbb113a607b85fef1b8764d7025c4a558a92f1ce5 (patch)
tree28a9d216bdac399791c4d7c48e7187dcb7fcb564 /packet-ip.c
parent97a05828cd6320744f7c305516b7bf87c422eb23 (diff)
Support for Mobile IP's use of ICMP Router Advertisements, from David
Frascone. Small white-space fix. Display the preference level in router advertisements as signed, not unsigned, as per RFC 1256, which says it's a "signed, twos-complement value". svn path=/trunk/; revision=4118
Diffstat (limited to 'packet-ip.c')
-rw-r--r--packet-ip.c280
1 files changed, 269 insertions, 11 deletions
diff --git a/packet-ip.c b/packet-ip.c
index 3467c61566..ee4e530a44 100644
--- a/packet-ip.c
+++ b/packet-ip.c
@@ -1,7 +1,7 @@
/* packet-ip.c
* Routines for IP and miscellaneous IP protocol packet disassembly
*
- * $Id: packet-ip.c,v 1.142 2001/10/01 08:29:34 guy Exp $
+ * $Id: packet-ip.c,v 1.143 2001/10/31 22:03:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -124,7 +124,28 @@ static int hf_icmp_code = -1;
static int hf_icmp_checksum = -1;
static int hf_icmp_checksum_bad = -1;
+/* Mobile ip */
+static int hf_icmp_mip_type = -1;
+static int hf_icmp_mip_length = -1;
+static int hf_icmp_mip_prefix_length = -1;
+static int hf_icmp_mip_seq = -1;
+static int hf_icmp_mip_life = -1;
+static int hf_icmp_mip_flags = -1;
+static int hf_icmp_mip_r = -1;
+static int hf_icmp_mip_b = -1;
+static int hf_icmp_mip_h = -1;
+static int hf_icmp_mip_f = -1;
+static int hf_icmp_mip_m = -1;
+static int hf_icmp_mip_g = -1;
+static int hf_icmp_mip_v = -1;
+static int hf_icmp_mip_res = -1;
+static int hf_icmp_mip_reserved = -1;
+static int hf_icmp_mip_coa = -1;
+static int hf_icmp_mip_challenge = -1;
+
static gint ett_icmp = -1;
+static gint ett_icmp_mip = -1;
+static gint ett_icmp_mip_flags = -1;
/* ICMP definitions */
@@ -1119,6 +1140,155 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pi = save_pi;
}
+#define ICMP_MIP_EXTENSION_PAD 0
+#define ICMP_MIP_MOB_AGENT_ADV 16
+#define ICMP_MIP_PREFIX_LENGTHS 19
+#define ICMP_MIP_CHALLENGE 24
+
+static value_string mip_extensions[] = {
+ { ICMP_MIP_EXTENSION_PAD, "One byte padding extension"}, /* RFC 2002 */
+ { ICMP_MIP_MOB_AGENT_ADV, "Mobility Agent Advertisement Extension"},
+ /* RFC 2002 */
+ { ICMP_MIP_PREFIX_LENGTHS, "Prefix Lengths Extension"}, /* RFC 2002 */
+ { ICMP_MIP_CHALLENGE, "Challenge Extension"}, /* RFC 3012 */
+ { 0, NULL}
+};
+
+/*
+ * Dissect the mobile ip advertisement extensions.
+ */
+static void
+dissect_mip_extensions(tvbuff_t *tvb, size_t offset, packet_info *pinfo,
+ proto_tree *tree)
+{
+ guint8 type;
+ guint8 length;
+ guint8 flags;
+ proto_item *ti;
+ proto_tree *mip_tree=NULL;
+ proto_tree *flags_tree=NULL;
+ gint numCOAs;
+ gint i;
+
+ /* Not much to do if we're not parsing everything */
+ if (!tree) return;
+
+ while ((tvb_length(tvb) - offset) > 0) {
+
+ type = tvb_get_guint8(tvb, offset + 0);
+ if (type)
+ length = tvb_get_guint8(tvb, offset + 1);
+ else
+ length=0;
+
+ ti = proto_tree_add_text(tree, tvb, offset,
+ type?(length + 2):1,
+ "Ext: %s",
+ val_to_str(type, mip_extensions,
+ "Unknown ext %d"));
+ mip_tree = proto_item_add_subtree(ti, ett_icmp_mip);
+
+
+ switch (type) {
+ case ICMP_MIP_EXTENSION_PAD:
+ /* One byte padding extension */
+ /* Add our fields */
+ /* type */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_type, tvb, offset,
+ 1, FALSE);
+ offset++;
+ break;
+ case ICMP_MIP_MOB_AGENT_ADV:
+ /* Mobility Agent Advertisement Extension (RFC 2002)*/
+ /* Add our fields */
+ /* type */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_type, tvb, offset,
+ 1, FALSE);
+ offset++;
+ /* length */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_length, tvb, offset,
+ 1, FALSE);
+ offset++;
+ /* sequence number */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_seq, tvb, offset,
+ 2, FALSE);
+ offset+=2;
+ /* Registration Lifetime */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_life, tvb, offset,
+ 2, FALSE);
+ offset+=2;
+ /* flags */
+ flags = tvb_get_guint8(tvb, offset);
+ ti = proto_tree_add_item(mip_tree, hf_icmp_mip_flags, tvb, offset,
+ 1, FALSE);
+ flags_tree = proto_item_add_subtree(ti, ett_icmp_mip_flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_r, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_b, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_h, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_f, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_m, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_g, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_v, tvb, offset, 1, flags);
+ proto_tree_add_boolean(flags_tree, hf_icmp_mip_res, tvb, offset, 1, flags);
+ offset++;
+
+ /* Reserved */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_reserved, tvb, offset,
+ 1, FALSE);
+ offset++;
+
+ /* COAs */
+ numCOAs = (length - 6) / 4;
+ for (i=0; i<numCOAs; i++) {
+ proto_tree_add_item(mip_tree, hf_icmp_mip_coa, tvb, offset,
+ 4, FALSE);
+ offset+=4;
+ }
+ break;
+ case ICMP_MIP_PREFIX_LENGTHS:
+ /* Prefix-Lengths Extension (RFC 2002)*/
+ /* Add our fields */
+ /* type */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_type, tvb, offset,
+ 1, FALSE);
+ offset++;
+ /* length */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_length, tvb, offset,
+ 1, FALSE);
+ offset++;
+
+ /* prefix lengths */
+ for(i=0; i<length; i++) {
+ proto_tree_add_item(mip_tree, hf_icmp_mip_prefix_length, tvb, offset,
+ 1, FALSE);
+ offset++;
+ }
+ break;
+ case ICMP_MIP_CHALLENGE:
+ /* Challenge Extension (RFC 3012)*/
+ /* type */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_type, tvb, offset,
+ 1, FALSE);
+ offset++;
+ /* length */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_length, tvb, offset,
+ 1, FALSE);
+ offset++;
+ /* challenge */
+ proto_tree_add_item(mip_tree, hf_icmp_mip_challenge, tvb, offset,
+ length, FALSE);
+ offset+=length;
+
+ break;
+ default:
+ g_warning("Unknown type(%d)! I hope the length is right (%d)",
+ type, length);
+ offset += length;
+ break;
+ } /* switch type */
+ } /* end while */
+
+} /* dissect_mip_extensions */
static const gchar *unreach_str[] = {"Network unreachable",
"Host unreachable",
@@ -1155,6 +1325,12 @@ static const gchar *par_str[] = {"IP header bad", "Required option missing"};
#define N_PARAMPROB (sizeof par_str / sizeof par_str[0])
+/*
+ * RFC 792 for basic ICMP.
+ * RFC 1191 for ICMP_FRAG_NEEDED (with MTU of next hop).
+ * RFC 1256 for router discovery messages.
+ * RFC 2002 and 3012 for Mobile IP stuff.
+ */
static void
dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@@ -1214,7 +1390,14 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
strcpy(type_str, "Echo (ping) request");
break;
case ICMP_RTRADVERT:
- strcpy(type_str, "Router advertisement");
+ switch (icmp_code) {
+ case 16: /* Mobile-Ip */
+ strcpy(type_str, "Mobile IP Advertisement");
+ break;
+ default:
+ strcpy(type_str, "Router advertisement");
+ break;
+ } /* switch icmp_code */
break;
case ICMP_RTRSOLICIT:
strcpy(type_str, "Router solicitation");
@@ -1255,6 +1438,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
default:
strcpy(type_str, "Unknown ICMP (obsolete or malformed?)");
+ break;
}
if (check_col(pinfo->fd, COL_INFO))
@@ -1312,14 +1496,14 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb_get_guint8(tvb, 6), tvb_get_guint8(tvb, 7));
break;
- case ICMP_UNREACH:
- switch (icmp_code) {
- case ICMP_FRAG_NEEDED:
- proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u",
- tvb_get_ntohs(tvb, 6));
- break;
- }
- break;
+ case ICMP_UNREACH:
+ switch (icmp_code) {
+ case ICMP_FRAG_NEEDED:
+ proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u",
+ tvb_get_ntohs(tvb, 6));
+ break;
+ }
+ break;
case ICMP_RTRADVERT:
num_addrs = tvb_get_guint8(tvb, 4);
@@ -1416,7 +1600,11 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
"Router address: %s",
ip_to_str(tvb_get_ptr(tvb, 8 + (i*8), 4)));
proto_tree_add_text(icmp_tree, tvb, 12 + (i*8), 4,
- "Preference level: %u", tvb_get_ntohl(tvb, 12 + (i*8)));
+ "Preference level: %d", tvb_get_ntohl(tvb, 12 + (i*8)));
+ }
+ if (icmp_code == 16) {
+ /* Mobile-Ip */
+ dissect_mip_extensions(tvb,8 + i*8, pinfo, icmp_tree);
}
} else
dissect_data(tvb, 8, pinfo, icmp_tree);
@@ -1657,9 +1845,79 @@ proto_register_icmp(void)
{ &hf_icmp_checksum_bad,
{ "Bad Checksum", "icmp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"", HFILL }},
+
+ { &hf_icmp_mip_type,
+ { "Extension Type", "icmp.mip.type", FT_UINT8, BASE_DEC,
+ VALS(mip_extensions), 0x0,"", HFILL}},
+
+ { &hf_icmp_mip_length,
+ { "Length", "icmp.mip.length", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_prefix_length,
+ { "Prefix Length", "icmp.mip.prefixlength", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_seq,
+ { "Sequence Number", "icmp.mip.seq", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_life,
+ { "Registration Lifetime", "icmp.mip.life", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_flags,
+ { "Flags", "icmp.mip.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_r,
+ { "Registration Required", "icmp.mip.r", FT_BOOLEAN, 8, NULL, 128,
+ "Registration with this FA is required", HFILL }},
+
+ { &hf_icmp_mip_b,
+ { "Busy", "icmp.mip.b", FT_BOOLEAN, 8, NULL, 64,
+ "This FA will not accept requests at this time", HFILL }},
+
+ { &hf_icmp_mip_h,
+ { "Home Agent", "icmp.mip.h", FT_BOOLEAN, 8, NULL, 32,
+ "Home Agent Services Offered", HFILL }},
+
+ { &hf_icmp_mip_f,
+ { "Foreign Agent", "icmp.mip.f", FT_BOOLEAN, 8, NULL, 16,
+ "Foreign Agent Services Offered", HFILL }},
+
+ { &hf_icmp_mip_m,
+ { "Minimal Encapsulation", "icmp.mip.m", FT_BOOLEAN, 8, NULL, 8,
+ "Minimal encapsulation tunneled datagram support", HFILL }},
+
+ { &hf_icmp_mip_g,
+ { "GRE", "icmp.mip.g", FT_BOOLEAN, 8, NULL, 4,
+ "GRE encapsulated tunneled datagram support", HFILL }},
+
+ { &hf_icmp_mip_v,
+ { "VJ Comp", "icmp.mip.v", FT_BOOLEAN, 8, NULL, 2,
+ "Van Jacobson Header Compression Support", HFILL }},
+
+ { &hf_icmp_mip_res,
+ { "Reserved", "icmp.mip.res", FT_BOOLEAN, 8, NULL, 1,
+ "Reserved", HFILL }},
+
+ { &hf_icmp_mip_reserved,
+ { "Reserved", "icmp.mip.reserved", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_coa,
+ { "Care-Of-Address", "icmp.mip.coa", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL}},
+
+ { &hf_icmp_mip_challenge,
+ { "Challenge", "icmp.mip.challenge", FT_BYTES, BASE_NONE, NULL, 0x0,
+ "", HFILL}},
};
static gint *ett[] = {
&ett_icmp,
+ &ett_icmp_mip,
+ &ett_icmp_mip_flags
};
proto_icmp = proto_register_protocol("Internet Control Message Protocol",