Wireshark-dev: Re: [Wireshark-dev] [PATCH][UPDATE] analyzing SHIM6 protocol
From: Matthijs Mekking <matthijs@xxxxxxxxxxxx>
Date: Thu, 22 Mar 2007 14:19:14 +0100
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks for the advice. I have attached a new patch, were you can apply shim6 elements as filter easier. more info at www.pletterpet.nl/shim6/ Regards, Matthijs Mekking matthijs@xxxxxxxxxxxx NLNetLabs Amsterdam / Radboud University Nijmegen Sebastien Tandel wrote: > I think most the proto_tree_add_text could be replaced by > proto_tree_add_item which could allow (i.e. at least Sébastien Barré ;)) > to perform an easy search on specific items. ;) > > > Regards, > Sebastien Tandel > > Matthijs Mekking wrote: >> 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 > _______________________________________________ > Wireshark-dev mailing list > Wireshark-dev@xxxxxxxxxxxxx > http://www.wireshark.org/mailman/listinfo/wireshark-dev > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGAoJSNiaStnTWEtYRAiDlAJ0a2YzB5rnC4jcTamNWI19m9H2+kgCdHzZu w3VdH7SmzULlIPNwkUCYykY= =x5Mt -----END PGP SIGNATURE-----
--- wireshark-0.99.5/epan/dissectors/packet-ipv6.c 2007-02-02 00:00:57.000000000 +0100 +++ wireshark-0.99.5-shim6-0.1/epan/dissectors/packet-ipv6.c 2007-03-22 14:03:32.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,29 @@ 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 int hf_ipv6_shim6_p = -1; +/* context tag is 49 bits, cannot be used for filter yet */ +static int hf_ipv6_shim6_ct = -1; +static int hf_ipv6_shim6_type = -1; +static int hf_ipv6_shim6_proto = -1; +static int hf_ipv6_shim6_csum = -1; +static int hf_ipv6_shim6_inonce = -1; /* also for request nonce */ +static int hf_ipv6_shim6_rnonce = -1; +static int hf_ipv6_shim6_precvd = -1; +static int hf_ipv6_shim6_psent = -1; +static int hf_ipv6_shim6_reap = -1; +static int hf_ipv6_shim6_opt_type = -1; +static int hf_ipv6_shim6_opt_len = -1; +static int hf_ipv6_shim6_opt_critical = -1; +static int hf_ipv6_shim6_opt_loclist = -1; +static int hf_ipv6_shim6_opt_locnum = -1; +static int hf_ipv6_shim6_opt_elemlen = -1; +static int hf_ipv6_shim6_opt_fii = -1; + static gint ett_ipv6 = -1; static gint ett_ipv6_fragments = -1; static gint ett_ipv6_fragment = -1; @@ -168,6 +196,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 +598,647 @@ 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_shim_hex(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; + guint8 optlen; + + /* Option Type */ + 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); + + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_type, tvb, + offset, 2, (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, + "Option Type: %s", ctype); + + /* Critical */ + proto_tree_add_boolean_format(opt_tree, hf_ipv6_shim6_opt_critical, tvb, + offset+1, 1, tmp[1] & SHIM6_BITMASK_CRITICAL, "Critical: %s", + tmp[1] & SHIM6_BITMASK_CRITICAL ? "Yes" : "No"); + + /* Content Length */ + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_len, tvb, offset+2, 2, + len, "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_shim_hex(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: + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Locator List Generation: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + optlen = tvb_get_guint8(tvb, p); + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_locnum, tvb, p, 1, + optlen, "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: + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_loclist, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Locator List Generation: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + optlen = tvb_get_guint8(tvb, p); + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_elemlen, tvb, p, 1, + optlen, "Element Lenght: %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_shim_hex(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_shim_hex(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: + proto_tree_add_uint_format(opt_tree, hf_ipv6_shim6_opt_fii, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Forked Instance Identifier: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + 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; + guint8 tmp[6]; + const char *sta; + int count; + + p = offset; + + switch (type) + { + case SHIM6_TYPE_I1: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Initiator Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Initiator Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + break; + case SHIM6_TYPE_R1: + proto_tree_add_text(shim_tree, tvb, p, 2, "Reserved2"); + p += 2; + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Initiator Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Responder Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + break; + case SHIM6_TYPE_I2: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Initiator Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Initiator Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Responder Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2"); + p += 4; + + break; + case SHIM6_TYPE_R2: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Responder Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Initiator Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + break; + case SHIM6_TYPE_R1BIS: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Packet Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Responder Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + break; + case SHIM6_TYPE_I2BIS: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Initiator Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Initiator Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_rnonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Responder Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 6, "Reserved2"); + p += 6; + + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Initiator Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + break; + case SHIM6_TYPE_UPD_REQ: + case SHIM6_TYPE_UPD_ACK: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Receiver Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_inonce, tvb, p, 4, + tvb_get_ntohl(tvb, p), "Request Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + break; + case SHIM6_TYPE_KEEPALIVE: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Receiver Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + proto_tree_add_text(shim_tree, tvb, p, 4, "Reserved2"); + p += 4; + break; + case SHIM6_TYPE_PROBE: + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + tmp[5] = tvb_get_guint8(tvb, p++); + + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + p-6, 6, "Receiver Context Tag: %02x %02x %02x %02x %02x %02x", + tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); + + tmp[0] = tvb_get_guint8(tvb, p); + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_precvd, tvb, + p, 1, (tmp[0] & SHIM6_BITMASK_PRECVD) >> 4, + "Probes Received: %u", (tmp[0] & SHIM6_BITMASK_PRECVD) >> 4); + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_psent, tvb, + p, 1, tmp[0] & SHIM6_BITMASK_PSENT, + "Probes Sent: %u", tmp[0] & SHIM6_BITMASK_PSENT); + + p++; + + sta = val_to_str((tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6, + shimreapstates, "Unknown REAP State"); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_reap, tvb, + p, 1, (tvb_get_guint8(tvb, p) & SHIM6_BITMASK_STA) >> 6, + "REAP State: %s", sta); + + proto_tree_add_text(shim_tree, tvb, p, 3, "Reserved2"); + p += 3; + + /* Probes Sent */ + for (count=0;count<(tmp[0] & 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:"); + + proto_tree_add_text(shim_tree, tvb, p, 4, "- Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 4, "- Data: 0x%02x", + tvb_get_ntohl(tvb, p)); + p += 4; + } + + /* Probes Received */ + for (count=0;count<((tmp[0] & 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:"); + + proto_tree_add_text(shim_tree, tvb, p, 4, "- Nonce: %u (0x%02x)", + tvb_get_ntohl(tvb, p), tvb_get_ntohl(tvb, p)); + p += 4; + + proto_tree_add_text(shim_tree, tvb, p, 4, "- Data: 0x%02x", + tvb_get_ntohl(tvb, p)); + 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_boolean(shim_tree, hf_ipv6_shim6_p, tvb, + offset + offsetof(struct ip6_shim, ip6s_p), 1, shim.ip6s_p & SHIM6_BITMASK_P); + + /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */ + p = offset + 3; + + if (shim.ip6s_p & SHIM6_BITMASK_P) + { + 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++); + tmp[4] = tvb_get_guint8(tvb, p++); + + /* Payload Extension Header */ + proto_tree_add_none_format(shim_tree, hf_ipv6_shim6_ct, tvb, + offset + offsetof(struct ip6_shim, ip6s_p), 6, + "Receiver Context Tag: %02x %02x %02x %02x %02x %02x", + shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]); + } + else + { + /* Control Message */ + const char *ctype; + proto_item *ti_shim; + guint16 csum; + int advance; + + /* Message Type */ + ctype = val_to_str(shim.ip6s_p & SHIM6_BITMASK_TYPE, shimctrlvals, + "Unknown Message Type"); + + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_type, tvb, + offset + offsetof(struct ip6_shim, ip6s_p), 1, shim.ip6s_p & SHIM6_BITMASK_TYPE, + "Message Type: %s", ctype); + + /* Protocol bit (Must be zero for SHIM6) */ + proto_tree_add_boolean_format(shim_tree, hf_ipv6_shim6_proto, tvb, p, 1, + tvb_get_guint8(tvb, p) & SHIM6_BITMASK_PROTOCOL, "Protocol: %s", + tvb_get_guint8(tvb, p) & SHIM6_BITMASK_PROTOCOL ? "HIP" : "SHIM6"); + p++; + + /* Checksum */ + csum = shim_checksum(tvb_get_ptr(tvb, offset, len), len); + + if (csum == 0) { + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_csum, tvb, p, 2, + tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [correct]", tvb_get_ntohs(tvb, p)); + } else { + proto_tree_add_uint_format(shim_tree, hf_ipv6_shim6_csum, tvb, p, 2, + tvb_get_ntohs(tvb, p), "Checksum: 0x%04x [incorrect: should be 0x%04x]", + tvb_get_ntohs(tvb, p), in_cksum_shouldbe(tvb_get_ntohs(tvb, p), csum)); + } + p += 2; + + /* 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 +1349,7 @@ routing = FALSE; frag = FALSE; ah = FALSE; + shim6 = FALSE; dstopts = FALSE; again: @@ -716,6 +1389,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 +1477,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 +1492,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 +1603,107 @@ 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, + { "Next Header", "ipv6.shim6.nxt", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_len, + { "Header Ext Length", "ipv6.shim6.len", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_p, + { "P Bit", "ipv6.shim6.p", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_ct, + { "Context Tag", "ipv6.shim6.ct", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_type, + { "Message Type", "ipv6.shim6.type", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_proto, + { "Protocol", "ipv6.shim6.proto", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_csum, + { "Checksum", "ipv6.shim6.csum", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_inonce, + { "Initiator Nonce", "ipv6.shim6.inonce", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_rnonce, + { "Responder Nonce", "ipv6.shim6.rnonce", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_precvd, + { "Probes Received", "ipv6.shim6.precvd", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_psent, + { "Probes Sent", "ipv6.shim6.psent", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_reap, + { "REAP State", "ipv6.shim6.reap", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_opt_type, + { "Option Type", "ipv6.shim6.opt.type", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_opt_critical, + { "Option Critical Bit", "ipv6.shim6.opt.critical", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_opt_len, + { "Option Length", "ipv6.shim6.opt.len", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_opt_loclist, + { "Locator List Generation", "ipv6.shim6.opt.loclist", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL }}, + + { &hf_ipv6_shim6_opt_locnum, + { "Num Locators", "ipv6.shim6.opt.locnum", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Number of Locators in Locator List", HFILL }}, + + { &hf_ipv6_shim6_opt_elemlen, + { "Element Length", "ipv6.shim6.opt.elemlen", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Length of Elements in Locator Preferences Option", HFILL }}, + + { &hf_ipv6_shim6_opt_len, + { "Forked Instance Identifier", "ipv6.shim6.opt.fii", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL }}, + #ifdef TEST_FINALHDR { &hf_ipv6_final, { "Final next header", "ipv6.final", --- wireshark-0.99.5/epan/dissectors/packet-ipv6.h 2007-02-02 00:00:57.000000000 +0100 +++ wireshark-0.99.5-shim6-0.1/epan/dissectors/packet-ipv6.h 2007-03-22 12:54:22.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 */ --- wireshark-0.99.5/epan/ipproto.c 2007-02-02 00:01:02.000000000 +0100 +++ wireshark-0.99.5-shim6-0.1/epan/ipproto.c 2007-03-22 12:54:22.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" }, --- wireshark-0.99.5/epan/ipproto.h 2007-02-02 00:01:03.000000000 +0100 +++ wireshark-0.99.5-shim6-0.1/epan/ipproto.h 2007-03-22 12:54:22.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][UPDATE] analyzing SHIM6 protocol
- From: Sebastien Tandel
- Re: [Wireshark-dev] [PATCH][UPDATE] analyzing SHIM6 protocol
- From: Sebastien Tandel
- Re: [Wireshark-dev] [PATCH][UPDATE] analyzing SHIM6 protocol
- References:
- [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- From: Matthijs Mekking
- Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- From: Sebastien Tandel
- [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- Prev by Date: [Wireshark-dev] building rpm gives error
- Next by Date: [Wireshark-dev] Looking for a definition document matching a dissector/plugin.
- Previous by thread: Re: [Wireshark-dev] [PATCH] analyzing SHIM6 protocol
- Next by thread: Re: [Wireshark-dev] [PATCH][UPDATE] analyzing SHIM6 protocol
- Index(es):