Wireshark-dev: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
From: Matthijs Mekking <matthijs@xxxxxxxxxxxx>
Date: Tue, 20 Mar 2007 15:34:38 +0100
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, The last two months I have been working on a SHIM6 enabled version of Wireshark. The subject of my final thesis is about SHIM6 and I needed to analyze the SHIM6 communication exchange. SHIM6 is an IPv6 based solution for multihoming.(www.shim6.org) SHIM6 is handled as an IPv6 extension header. So I have changed the source and header files of packet-ipv6. I have added dissecting functions for different the message formats of the SHIM6 protocol. I also needed to change the ipproto files to add the new extension header. The included patch is pretty clear about that. The message formats are conform the latest draft specification of SHIM6: http://tools.ietf.org/html/draft-ietf-shim6-proto-07 http://tools.ietf.org/html/draft-ietf-shim6-failure-detection-07 Regards, Matthijs Mekking matthijs@xxxxxxxxxxxx NLNetLabs Amsterdam / Radboud University Nijmegen -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFF//D+NiaStnTWEtYRAmxUAJ4+s+KNTUkOJQY0vm+9Yr7f5KT3XgCeLrDA Nb8iiJWcL4aZoQzgkTteSHc= =HW21 -----END PGP SIGNATURE-----
diff -r -u -N --strip-trailing-cr wireshark-0.99.5/epan/dissectors/packet-ipv6.c wireshark-0.99.5-shim6/epan/dissectors/packet-ipv6.c --- wireshark-0.99.5/epan/dissectors/packet-ipv6.c 2007-02-02 00:00:57.000000000 +0100 +++ wireshark-0.99.5-shim6/epan/dissectors/packet-ipv6.c 2007-03-20 10:30:01.000000000 +0100 @@ -7,6 +7,8 @@ * By Gerald Combs <gerald@xxxxxxxxxxxxx> * Copyright 1998 Gerald Combs * + * SHIM6 support added by Matthijs Mekking <matthijs@xxxxxxxxxxxx> + * * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@xxxxxxxxxx> * * This program is free software; you can redistribute it and/or @@ -29,6 +31,7 @@ #endif #include <string.h> +#include <math.h> #include <stdio.h> #include <glib.h> #include <epan/packet.h> @@ -39,11 +42,13 @@ #include <epan/prefs.h> #include <epan/reassemble.h> #include <epan/ipproto.h> +#include <epan/ipv6-utils.h> #include <epan/etypes.h> #include <epan/ppptypes.h> #include <epan/aftypes.h> #include <epan/nlpid.h> #include <epan/arcnet_pids.h> +#include <epan/in_cksum.h> /* * NOTE: ipv6.nxt is not very useful as we will have chained header. @@ -77,6 +82,10 @@ static int hf_ipv6_mipv6_length = -1; static int hf_ipv6_mipv6_home_address = -1; +static int hf_ipv6_shim6 = -1; +static int hf_ipv6_shim6_nxt = -1; +static int hf_ipv6_shim6_len = -1; + static gint ett_ipv6 = -1; static gint ett_ipv6_fragments = -1; static gint ett_ipv6_fragment = -1; @@ -168,6 +177,19 @@ } offset += advance; goto again; + case IP_PROTO_SHIM6: + if (!BYTES_ARE_IN_FRAME(offset, len, 2)) { + ld->other++; + return; + } + nxt = pd[offset]; + advance = (pd[offset+1] + 1) << 3; + if (!BYTES_ARE_IN_FRAME(offset, len, advance)) { + ld->other++; + return; + } + offset += advance; + goto again; } switch(nxt) { @@ -557,16 +579,562 @@ return dissect_opts(tvb, offset, tree, "Destination Option"); } +/* START SHIM6 PART */ +static guint16 shim_checksum(const guint8 *ptr, int len) +{ + vec_t cksum_vec[1]; + + cksum_vec[0].ptr = ptr; + cksum_vec[0].len = len; + return in_cksum(&cksum_vec[0], 1); +} + +static int +dissect_shim_ip_addr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *itemname, ...) +{ + int count; + struct e_in6_addr addr; + + for(count=0;count<16;count++) { + addr.bytes[count] = tvb_get_guint8(tvb, offset+count); + } + + proto_tree_add_text(tree, tvb, offset, 16, "%s %s", + itemname, ip6_to_str(&addr)); + + return 16; +} + +static int +dissect_hex_val(tvbuff_t *tvb, int offset, int len, const char *itemname, guint8 bitmask, proto_tree *tree) +{ + proto_item *ti; + int count; + gint p; + + p = offset; + + ti = proto_tree_add_text(tree, tvb, offset, len, itemname); + + for (count=0; count<len; count++) + { + if (count==0) { + proto_item_append_text(ti, " 0x%02x", tvb_get_guint8(tvb, p+count) & bitmask); + } + else { + proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, p+count)); + } + } + + return len; +} + +static const value_string shimoptvals[] = { + { SHIM6_OPT_RESPVAL, "Responder Validator" }, + { SHIM6_OPT_LOCLIST, "Locator List" }, + { SHIM6_OPT_LOCPREF, "Locator Preferences" }, + { SHIM6_OPT_CGAPDM, "CGA Parameter Data Structure" }, + { SHIM6_OPT_CGASIG, "CGA Signature" }, + { SHIM6_OPT_ULIDPAIR, "ULID Pair" }, + { SHIM6_OPT_FII, "Forked Instance Identifier" }, + { 0, NULL }, +}; + +static const value_string shimverifmethods[] = { + { SHIM6_VERIF_HBA, "HBA" }, + { SHIM6_VERIF_CGA, "CGA" }, + { 0, NULL }, +}; + +static const value_string shimflags[] = { + { SHIM6_FLAG_BROKEN, "BROKEN" }, + { SHIM6_FLAG_TEMPORARY, "TEMPORARY" }, + { 0, NULL }, +}; + +static const value_string shimreapstates[] = { + { SHIM6_REAP_OPERATIONAL, "Operational" }, + { SHIM6_REAP_EXPLORING, "Exploring" }, + { SHIM6_REAP_INBOUNDOK, "InboundOK" }, + { 0, NULL }, +}; + +static int +dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree) +{ + int len, total_len; + gint p; + proto_tree *opt_tree; + proto_item *ti; + guint8 tmp[4]; + + p = offset; + + tmp[0] = tvb_get_guint8(tvb, p++); + tmp[1] = tvb_get_guint8(tvb, p++); + tmp[2] = tvb_get_guint8(tvb, p++); + tmp[3] = tvb_get_guint8(tvb, p++); + + len = tmp[2]*256 + tmp[3]; + total_len = (11+len) - ((len+3)%8); + + if (tree) + { + char *ctype; + char locnum[6]; + int count; + guint32 tmp32; + guint8 optlen; + + ctype = val_to_str( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, + shimoptvals, "Unknown Option Type"); + ti = proto_tree_add_text(tree, tvb, offset, total_len, "%s Option", ctype); + opt_tree = proto_item_add_subtree(ti, ett_ipv6); + + /* Option Type */ + proto_tree_add_text(opt_tree, tvb, offset, 2, "Type: %s", ctype); + + /* Critical */ + proto_tree_add_text(opt_tree, tvb, offset+1, 1, "Critical: %s", + tmp[1] & SHIM6_BITMASK_CRITICAL ? "Yes" : "No"); + + /* Content Length */ + proto_tree_add_text(opt_tree, tvb, offset+2, 2, "Content Length: %u (Total Length: %u)", + len, total_len); + + /* Option Type Specific */ + switch (tvb_get_ntohs(tvb, offset) >> 1) + { + case SHIM6_OPT_RESPVAL: + p += dissect_hex_val(tvb, p, len, "Validator:", 0xff, opt_tree); + + if (total_len-(len+4) > 0) + proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding"); + + break; + case SHIM6_OPT_LOCLIST: + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(opt_tree, tvb, p, 4, "Locator List Generation: %u", + tmp32); + p += 4; + + optlen = tvb_get_guint8(tvb, p); + proto_tree_add_text(opt_tree, tvb, p, 1, "Num Locators: %u", + optlen); + p++; + + /* Verification Methods */ + proto_tree_add_text(opt_tree, tvb, p, optlen, "Locator Verification Methods:"); + + for (count=0;count<optlen;count++) { + proto_tree_add_text(opt_tree, tvb, p+count, 1, "(%u): %s", count+1, + val_to_str(tvb_get_guint8(tvb, p+count), shimverifmethods, "Unknown")); + } + p += optlen; + + /* Padding, included in length field */ + if ((7-optlen % 8) > 0) { + proto_tree_add_text(opt_tree, tvb, p, (7-optlen % 8), "Padding"); + p += (7-optlen % 8); + } + + /* Locators */ + proto_tree_add_text(opt_tree, tvb, p, 16*optlen, "Locators"); + + for (count=0;count<optlen;count++) { + g_snprintf(locnum, sizeof locnum, "(%u)", count+1); + p += dissect_shim_ip_addr(tvb, p, opt_tree, locnum); + } + + break; + case SHIM6_OPT_LOCPREF: + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(opt_tree, tvb, p, 4, "Locator List Generation: %u", + tmp32); + p += 4; + + optlen = tvb_get_guint8(tvb, p); + proto_tree_add_text(opt_tree, tvb, p, 1, "Element Length: %u", optlen); + p++; + + /* Locator Preferences */ + count = 0; + while (p < offset+len+4) { + count++; + if (optlen > 0) { + /* Flags */ + proto_tree_add_text(opt_tree, tvb, p, 1, "Locator Flag %u: %s", count, + val_to_str(tvb_get_guint8(tvb, p), shimflags, "Unknown")); + p++; + + if (optlen > 1) { + /* Priority */ + proto_tree_add_text(opt_tree, tvb, p, 1, "Locator Priority %u: %u", + count, tvb_get_guint8(tvb, p)); + p++; + + if (optlen > 2) { + /* + * This document doesn't specify the format when the Element length is + * more than three, except that any such formats MUST be defined so that + * the first three octets are the same as in the above case, that is, a + * of a 1 octet flags field followed by a 1 octet priority field, and a + * 1 octet weight field. + */ + + /* Weight */ + proto_tree_add_text(opt_tree, tvb, p, 1, "Locator Weight %u: %u", + count, tvb_get_guint8(tvb, p)); + p++; + } + } + } + } + + if (total_len-(len+4) > 0) + proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding"); + + break; + case SHIM6_OPT_CGAPDM: + p += dissect_hex_val(tvb, p, len, "CGA Parameter Data Structure:", 0xff, opt_tree); + + if (total_len-(len+4) > 0) + proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding"); + + break; + case SHIM6_OPT_CGASIG: + p += dissect_hex_val(tvb, p, len, "CGA Signature:", 0xff, opt_tree); + + if (total_len-(len+4) > 0) + proto_tree_add_text(opt_tree, tvb, p, total_len-(len+4), "Padding"); + + break; + case SHIM6_OPT_ULIDPAIR: + proto_tree_add_text(opt_tree, tvb, p, 4, "Reserved"); + p += 4; + + p += dissect_shim_ip_addr(tvb, p, opt_tree, "Sender ULID:"); + p += dissect_shim_ip_addr(tvb, p, opt_tree, "Receiver ULID:"); + + break; + case SHIM6_OPT_FII: + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(opt_tree, tvb, p, 4, + "Forked Instance Identifier: %u (0x%02x)", tmp32, tmp32); + p += 4; + break; + default: + break; + } + } + + return total_len; +} + +/* Dissect SHIM6 data: control messages */ +static int +dissect_shimctrl(tvbuff_t *tvb, int offset, guint type, proto_tree *shim_tree) +{ + gint p; + guint32 tmp32; + guint8 tmp8; + const char *sta; + int count; + + p = offset; + + switch (type) + { + case SHIM6_TYPE_I1: + p += dissect_hex_val(tvb, p, 6, "Initiator Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Initiator Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + break; + case SHIM6_TYPE_R1: + proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2"); + p += 2; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Initiator Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Responder Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + break; + case SHIM6_TYPE_I2: + p += dissect_hex_val(tvb, p, 6, "Initiator Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Initiator Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Responder Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2"); + p += 4; + + break; + case SHIM6_TYPE_R2: + p += dissect_hex_val(tvb, p, 6, "Responder Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Initiator Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + break; + case SHIM6_TYPE_R1BIS: + p += dissect_hex_val(tvb, p, 6, "Packet Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Responder Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + break; + case SHIM6_TYPE_I2BIS: + p += dissect_hex_val(tvb, p, 6, "Initiator Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Initiator Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Responder Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2"); + p += 6; + + p += dissect_hex_val(tvb, p, 6, "Packet Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + break; + case SHIM6_TYPE_UPD_REQ: + case SHIM6_TYPE_UPD_ACK: + p += dissect_hex_val(tvb, p, 6, "Receiver Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "Request Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + break; + case SHIM6_TYPE_KEEPALIVE: + p += dissect_hex_val(tvb, p, 6, "Receiver Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2"); + p += 4; + break; + case SHIM6_TYPE_PROBE: + p += dissect_hex_val(tvb, p, 6, "Receiver Context Tag:", + SHIM6_BITMASK_CT, shim_tree); + + tmp8 = tvb_get_guint8(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 1, "Probes Received: %u", + (tmp8 & SHIM6_BITMASK_PRECVD) >> 4); + proto_tree_add_text(shim_tree, tvb, p, 1, "Probes Sent: %u", + tmp8 & SHIM6_BITMASK_PSENT); + p++; + + sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6, + shimreapstates, "Unknown REAP State"); + proto_tree_add_text(shim_tree, tvb, p, 1, "State: %s", sta); + + proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2"); + p += 3; + + /* Probes Sent */ + for (count=0;count<(tmp8 & SHIM6_BITMASK_PSENT);count++) { + proto_tree_add_text(shim_tree, tvb, p, 40, "Probe Sent %u:", count+1); + + p += dissect_shim_ip_addr(tvb, p, shim_tree, "- Source address:"); + p += dissect_shim_ip_addr(tvb, p, shim_tree, "- Destination address:"); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "- Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "- Data: 0x%02x", + tmp32); + p += 4; + } + + /* Probes Received */ + for (count=0;count<((tmp8 & SHIM6_BITMASK_PRECVD)>>4);count++) { + proto_tree_add_text(shim_tree, tvb, p, 40, "Probe Received %u:", count+1); + + p += dissect_shim_ip_addr(tvb, p, shim_tree, "- Source address:"); + p += dissect_shim_ip_addr(tvb, p, shim_tree, "- Destination address:"); + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "- Nonce: %u (0x%02x)", + tmp32, tmp32); + p += 4; + + tmp32 = tvb_get_ntohl(tvb, p); + proto_tree_add_text(shim_tree, tvb, p, 4, "- Data: 0x%02x", + tmp32); + p += 4; + } + + break; + default: + break; + } + + return p-offset; +} + +/* Dissect SHIM6 data: payload, common part, options */ +static const value_string shimctrlvals[] = { + { SHIM6_TYPE_I1, "I1" }, + { SHIM6_TYPE_R1, "R1" }, + { SHIM6_TYPE_I2, "I2" }, + { SHIM6_TYPE_R2, "R2" }, + { SHIM6_TYPE_R1BIS, "R1bis" }, + { SHIM6_TYPE_I2BIS, "I2bis" }, + { SHIM6_TYPE_UPD_REQ, "Update Request" }, + { SHIM6_TYPE_UPD_ACK, "Update Acknowledgement" }, + { SHIM6_TYPE_KEEPALIVE, "Keepalive" }, + { SHIM6_TYPE_PROBE, "Probe" }, + { 0, NULL }, +}; + +static int +dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree) +{ + struct ip6_shim shim; + int len; + gint p; + proto_tree *shim_tree, *opt_tree; + proto_item *ti; + guint8 tmp[5]; + + tvb_memcpy(tvb, (guint8 *)&shim, offset, sizeof(shim)); + len = (shim.ip6s_len + 1) << 3; + + if (tree) + { + ti = proto_tree_add_item(tree, hf_ipv6_shim6, tvb, offset, len, FALSE); + shim_tree = proto_item_add_subtree(ti, ett_ipv6); + + /* Next Header */ + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_nxt, tvb, + offset + offsetof(struct ip6_shim, ip6s_nxt), 1, shim.ip6s_nxt, + "Next header: %s (0x%02x)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt); + + /* Header Extension Length */ + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_len, tvb, + offset + offsetof(struct ip6_shim, ip6s_len), 1, shim.ip6s_len, + "Header Ext Length: %u (%d bytes)", shim.ip6s_len, len); + + /* P Field */ + proto_tree_add_text(shim_tree, tvb, + offset + offsetof(struct ip6_shim, ip6s_p), 1, "P field: %s", + shim.ip6s_p & SHIM6_BITMASK_P ? "Payload extension" : "Control message"); + + /* skip the first 3 bytes (nxt hdr, hdr ext len, p field + 7 bits) */ + p = offset + 3; + + if (shim.ip6s_p & SHIM6_BITMASK_P) + { + /* Payload Extension Header */ + p += dissect_hex_val(tvb, offset + offsetof(struct ip6_shim, ip6s_p), + 6, "Initiator Context Tag:", SHIM6_BITMASK_CT, shim_tree); + } + else + { + /* Control Message */ + const char *ctype; + proto_item *ti_shim; + guint16 csum, tmp16; + int advance; + + /* Message Type */ + ctype = val_to_str(shim.ip6s_p & SHIM6_BITMASK_TYPE, shimctrlvals, + "Unknown Message Type"); + + proto_tree_add_text(shim_tree, tvb, offset + offsetof(struct ip6_shim, ip6s_p), + 1, "Message Type: %s", ctype); + + /* Type Specific field (Reserved) and zero bit */ + tmp[0] = tvb_get_guint8(tvb, p++); + + /* Protocol bit (Must be zero for SHIM6 */ + proto_tree_add_text(shim_tree, tvb, p-1, 1, "Protocol: %s", + tmp[0] & SHIM6_BITMASK_PROTOCOL ? "HIP" : "SHIM6"); + + /* Checksum */ + csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len); + tmp16 = tvb_get_ntohs(tvb, p); + p += 2; + + if (csum == 0) + proto_tree_add_text(shim_tree, tvb, p-2, 2, "Checksum: 0x%04x [correct]", tmp16); + else + proto_tree_add_text(shim_tree, tvb, p-2, 2, "Checksum: 0x%04x [incorrect: should be 0x%04x]", + tmp16, in_cksum_shouldbe(tmp16, csum)); + + /* Type specific data */ + advance = dissect_shimctrl(tvb, p, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree); + + p += advance; + + /* Options */ + + if (p < offset+len && shim_tree) { + ti_shim = proto_tree_add_text(shim_tree, tvb, p, len-(advance+6), + "Options (%u bytes)", len-(advance+6)); + + opt_tree = proto_item_add_subtree(ti_shim, ett_ipv6); + + while (p < offset+len) { + p += dissect_shimopts(tvb, p, opt_tree); + } + } + + } + } + + return len; +} + +/* END SHIM6 PART */ + static void dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ipv6_tree = NULL; proto_item *ti; - guint8 nxt; + guint8 nxt, stype; int advance; int poffset; guint16 plen; - gboolean hopopts, routing, frag, ah, dstopts; + gboolean hopopts, routing, frag, ah, shim6, dstopts; guint16 offlg; guint32 ident; int offset; @@ -677,6 +1245,7 @@ routing = FALSE; frag = FALSE; ah = FALSE; + shim6 = FALSE; dstopts = FALSE; again: @@ -716,6 +1285,15 @@ offset += advance; plen -= advance; goto again; + case IP_PROTO_SHIM6: + shim6 = TRUE; + advance = dissect_shim6(tvb, offset, tree); + nxt = tvb_get_guint8(tvb, offset); + stype = tvb_get_guint8(tvb, offset+2); + poffset = offset; + offset += advance; + plen -= advance; + goto again; case IP_PROTO_DSTOPTS: dstopts = TRUE; advance = dissect_dstopts(tvb, offset, tree); @@ -795,7 +1373,7 @@ /* If we had an Authentication Header, the AH dissector already put something in the Info column; leave it there. */ if (!ah) { - if (hopopts || routing || dstopts) { + if (hopopts || routing || dstopts || shim6) { const char *sep = "IPv6 "; if (hopopts) { col_append_fstr(pinfo->cinfo, COL_INFO, "%shop-by-hop options", @@ -810,6 +1388,15 @@ col_append_fstr(pinfo->cinfo, COL_INFO, "%sdestination options", sep); } + if (shim6) { + if (stype & SHIM6_BITMASK_P) { + col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (Payload)"); + } + else { + col_append_fstr(pinfo->cinfo, COL_INFO, "Shim6 (%s)", + val_to_str(stype & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown")); + } + } } else col_set_str(pinfo->cinfo, COL_INFO, "IPv6 no next header"); } @@ -912,6 +1499,22 @@ FT_IPv6, BASE_HEX, NULL, 0x0, "", HFILL }}, + /* SHIM6 */ + { &hf_ipv6_shim6, + { "SHIM6 ", "ipv6.shim6", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_nxt, + { "SHIM6 Next Header", "ipv6.shim6.nxt", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_len, + { "SHIM6 Header Ext Length", "ipv6.shim6.len", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + #ifdef TEST_FINALHDR { &hf_ipv6_final, { "Final next header", "ipv6.final", diff -r -u -N --strip-trailing-cr wireshark-0.99.5/epan/dissectors/packet-ipv6.h wireshark-0.99.5-shim6/epan/dissectors/packet-ipv6.h --- wireshark-0.99.5/epan/dissectors/packet-ipv6.h 2007-02-02 00:00:57.000000000 +0100 +++ wireshark-0.99.5-shim6/epan/dissectors/packet-ipv6.h 2007-03-20 10:30:02.000000000 +0100 @@ -150,6 +150,61 @@ guint32 ip6f_ident; /* identification */ }; +/* SHIM6 control message types */ +#define SHIM6_TYPE_I1 0x01 /* 0 000 0001 */ +#define SHIM6_TYPE_R1 0x02 /* 0 000 0010 */ +#define SHIM6_TYPE_I2 0x03 /* 0 000 0011 */ +#define SHIM6_TYPE_R2 0x04 /* 0 000 0100 */ +#define SHIM6_TYPE_R1BIS 0x05 /* 0 000 0101 */ +#define SHIM6_TYPE_I2BIS 0x06 /* 0 000 0110 */ +#define SHIM6_TYPE_UPD_ACK 0x40 /* 0 100 0000 = 64 */ +#define SHIM6_TYPE_UPD_REQ 0x41 /* 0 100 0001 = 65 */ +#define SHIM6_TYPE_KEEPALIVE 0x42 /* 0 100 0010 = 66 */ +#define SHIM6_TYPE_PROBE 0x43 /* 0 100 0011 = 67 */ + +/* SHIM6 Options */ +#define SHIM6_OPT_RESPVAL 0x01 /* 0 000 0001 */ +#define SHIM6_OPT_LOCLIST 0x02 /* 0 000 0010 */ +#define SHIM6_OPT_LOCPREF 0x03 /* 0 000 0011 */ +#define SHIM6_OPT_CGAPDM 0x04 /* 0 000 0100 */ +#define SHIM6_OPT_CGASIG 0x05 /* 0 000 0101 */ +#define SHIM6_OPT_ULIDPAIR 0x06 /* 0 000 0110 */ +#define SHIM6_OPT_FII 0x07 /* 0 000 0111 */ + +/* SHIM6 Bitmasks */ +#define SHIM6_BITMASK_P 0x80 /* 1 000 0000 */ +#define SHIM6_BITMASK_TYPE 0x7F /* 0 111 1111 */ +#define SHIM6_BITMASK_PROTOCOL 0x01 /* 0 000 0001 */ +#define SHIM6_BITMASK_SPECIFIC 0xFE /* 1 111 1110 */ +#define SHIM6_BITMASK_R 0x80 /* 1 000 0000 */ +#define SHIM6_BITMASK_CT 0x7F /* 0 111 1111 */ +#define SHIM6_BITMASK_OPT_TYPE 0xFFFE /* 1 111 1111 1 111 1110 */ +#define SHIM6_BITMASK_CRITICAL 0x01 /* 0 000 0001 */ +#define SHIM6_BITMASK_PRECVD 0xF0 /* 1 111 0000 */ +#define SHIM6_BITMASK_PSENT 0x0F /* 0 000 1111 */ +#define SHIM6_BITMASK_STA 0xC0 /* 1 100 0000 */ + +/* SHIM6 Verification Methods */ +#define SHIM6_VERIF_HBA 0x01 /* 0 000 0001 */ +#define SHIM6_VERIF_CGA 0x02 /* 0 000 0010 */ + +/* SHIM6 Flags */ +#define SHIM6_FLAG_BROKEN 0x01 /* 0 000 0001 */ +#define SHIM6_FLAG_TEMPORARY 0x02 /* 0 000 0010 */ + +/* SHIM6 REAP States */ +#define SHIM6_REAP_OPERATIONAL 0x00 /* 0 000 0000 */ +#define SHIM6_REAP_EXPLORING 0x01 /* 0 000 0001 */ +#define SHIM6_REAP_INBOUNDOK 0x02 /* 0 000 0010 */ + +/* SHIM6 header */ +struct ip6_shim { + guint8 ip6s_nxt; /* next header */ + guint8 ip6s_len; /* header extension length */ + guint8 ip6s_p; /* P field and first 7 bits of remainder */ + /* followed by shim6 specific data*/ +}; + #define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */ #define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ diff -r -u -N --strip-trailing-cr wireshark-0.99.5/epan/ipproto.c wireshark-0.99.5-shim6/epan/ipproto.c --- wireshark-0.99.5/epan/ipproto.c 2007-02-02 00:01:02.000000000 +0100 +++ wireshark-0.99.5-shim6/epan/ipproto.c 2007-03-20 10:30:03.000000000 +0100 @@ -107,6 +107,7 @@ { IP_PROTO_ICMPV6, "ICMPv6" }, { IP_PROTO_NONE, "IPv6 no next header" }, { IP_PROTO_DSTOPTS, "IPv6 destination option" }, + { IP_PROTO_SHIM6, "SHIM6 header" }, { IP_PROTO_MIPV6_OLD, "Mobile IPv6 (old)" }, { IP_PROTO_SATEXPAK,"SATNET EXPAK" }, { IP_PROTO_KRYPTOLAN, "Kryptolan" }, diff -r -u -N --strip-trailing-cr wireshark-0.99.5/epan/ipproto.h wireshark-0.99.5-shim6/epan/ipproto.h --- wireshark-0.99.5/epan/ipproto.h 2007-02-02 00:01:03.000000000 +0100 +++ wireshark-0.99.5-shim6/epan/ipproto.h 2007-03-20 10:30:03.000000000 +0100 @@ -96,6 +96,9 @@ #define IP_PROTO_NONE 59 /* IP6 no next header - RFC1883 */ #define IP_PROTO_DSTOPTS 60 /* IP6 destination options - RFC1883 */ /* 61 is reserved by IANA for any host internal protocol */ +/* 61 is used by UCL's SHIM6 implementation as Next Header for SHIM6 */ +#define IP_PROTO_SHIM6 61 /* SHIM6 */ + /* * The current Protocol Numbers list says that the IP protocol number for * mobility headers is 135; it cites draft-ietf-mobileip-ipv6-24, but
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- From: Sebastien Tandel
- Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- Prev by Date: Re: [Wireshark-dev] Prevent compiler warnings by using "stop on warnings"/"treat warnings as errors" compiler option?
- Next by Date: Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- Previous by thread: Re: [Wireshark-dev] Compilation errors
- Next by thread: Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- Index(es):