diff options
-rw-r--r-- | AUTHORS | 4 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | Makefile.nmake | 3 | ||||
-rw-r--r-- | doc/ethereal.pod.template | 1 | ||||
-rw-r--r-- | ipproto.c | 3 | ||||
-rw-r--r-- | ipproto.h | 3 | ||||
-rw-r--r-- | packet-icmpv6.c | 69 | ||||
-rw-r--r-- | packet-ipv6.c | 386 | ||||
-rw-r--r-- | packet-ipv6.h | 51 | ||||
-rw-r--r-- | packet-mip6.c | 688 | ||||
-rw-r--r-- | packet-mip6.h | 217 |
11 files changed, 1014 insertions, 414 deletions
@@ -1597,6 +1597,10 @@ Pasi Kovanen <Pasi.Kovanen [AT] tahoenetworks.fi> { Display flow label IE in GTP v0 in hex } +Teemu Rinta-aho <teemu.rinta-aho [AT] nomadiclab.com> { + Draft 20 MIPv6 support +} + Alain Magloire <alainm[AT]rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. diff --git a/Makefile.am b/Makefile.am index 97aba9700b..87b89999b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.550 2003/01/30 18:49:47 guy Exp $ +# $Id: Makefile.am,v 1.551 2003/02/04 20:16:57 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -256,6 +256,7 @@ DISSECTOR_SRC = \ packet-mbtcp.c \ packet-mdshdr.c \ packet-mip.c \ + packet-mip6.c \ packet-mmse.c \ packet-mount.c \ packet-mpeg1.c \ diff --git a/Makefile.nmake b/Makefile.nmake index a946d0e719..2379d7f2e9 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -1,7 +1,7 @@ ## Makefile for building ethereal.exe with Microsoft C and nmake ## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake # -# $Id: Makefile.nmake,v 1.277 2003/01/30 18:49:47 guy Exp $ +# $Id: Makefile.nmake,v 1.278 2003/02/04 20:16:57 guy Exp $ include config.nmake include <win32.mak> @@ -199,6 +199,7 @@ DISSECTOR_SRC = \ packet-mbtcp.c \ packet-mdshdr.c \ packet-mip.c \ + packet-mip6.c \ packet-mmse.c \ packet-mount.c \ packet-mpeg1.c \ diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index 91743fc168..7660d46943 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -1724,6 +1724,7 @@ B<http://www.ethereal.com>. Huagang Xie <xie [AT] lids.org> cjs 2895 <cjs2895 [AT] hotmail.com> Pasi Kovanen <Pasi.Kovanen [AT] tahoenetworks.fi> + Teemu Rinta-aho <teemu.rinta-aho [AT] nomadiclab.com> Alain Magloire <alainm[AT]rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. @@ -1,7 +1,7 @@ /* ipproto.c * Routines for converting IPv4 protocol/v6 nxthdr field into string * - * $Id: ipproto.c,v 1.20 2002/08/30 02:11:16 sharpe Exp $ + * $Id: ipproto.c,v 1.21 2003/02/04 20:16:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -75,6 +75,7 @@ static const value_string ipproto_val[] = { { IP_PROTO_ICMPV6, "ICMPv6" }, { IP_PROTO_NONE, "IPv6 no next header" }, { IP_PROTO_DSTOPTS, "IPv6 destination option" }, + { IP_PROTO_MIPV6, "Mobile IPv6" }, { IP_PROTO_EON, "EON" }, { IP_PROTO_OSPF, "OSPF" }, { IP_PROTO_ENCAP, "ENCAP" }, @@ -2,7 +2,7 @@ * Declarations of IP protocol numbers, and of routines for converting * IP protocol numbers into strings. * - * $Id: ipproto.h,v 1.6 2002/08/28 21:00:06 jmayer Exp $ + * $Id: ipproto.h,v 1.7 2003/02/04 20:16:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -53,6 +53,7 @@ #define IP_PROTO_ICMPV6 58 /* ICMP6 */ #define IP_PROTO_NONE 59 /* IP6 no next header */ #define IP_PROTO_DSTOPTS 60 /* IP6 destination options */ +#define IP_PROTO_MIPV6 62 /* Mobile IPv6 */ #define IP_PROTO_EON 80 /* ISO cnlp */ #define IP_PROTO_VINES 83 /* Vines over raw IP */ #define IP_PROTO_EIGRP 88 diff --git a/packet-icmpv6.c b/packet-icmpv6.c index 2fa4fd8615..9225b82e8f 100644 --- a/packet-icmpv6.c +++ b/packet-icmpv6.c @@ -1,7 +1,7 @@ /* packet-icmpv6.c * Routines for ICMPv6 packet disassembly * - * $Id: packet-icmpv6.c,v 1.69 2003/01/20 05:42:30 guy Exp $ + * $Id: packet-icmpv6.c,v 1.70 2003/02/04 20:16:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -1098,6 +1098,26 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) "Unknown"); len = sizeof(struct icmp6_nodeinfo); break; + case ICMP6_MIP6_DHAAD_REQUEST: + typename = coltypename = "Dynamic Home Agent Address Discovery Request"; + codename = "Should always be zero"; + colcodename = NULL; + break; + case ICMP6_MIP6_DHAAD_REPLY: + typename = coltypename = "Dynamic Home Agent Address Discovery Reply"; + codename = "Should always be zero"; + colcodename = NULL; + break; + case ICMP6_MIP6_MPS: + typename = coltypename = "Mobile Prefix Solicitation"; + codename = "Should always be zero"; + colcodename = NULL; + break; + case ICMP6_MIP6_MPA: + typename = coltypename = "Mobile Prefix Advertisement"; + codename = "Should always be zero"; + colcodename = NULL; + break; } if (check_col(pinfo->cinfo, COL_INFO)) { @@ -1368,6 +1388,53 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) "Unknown")); dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree); break; + case ICMP6_MIP6_DHAAD_REQUEST: + proto_tree_add_text(icmp6_tree, tvb, + offset + 4, 2, "Identifier: %d (0x%02x)", + tvb_get_ntohs(tvb, offset + 4), + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(icmp6_tree, tvb, + offset + 6, 2, "Reserved: %d", + tvb_get_ntohs(tvb, offset + 6)); + break; + case ICMP6_MIP6_DHAAD_REPLY: + proto_tree_add_text(icmp6_tree, tvb, + offset + 4, 2, "Identifier: %d (0x%02x)", + tvb_get_ntohs(tvb, offset + 4), + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(icmp6_tree, tvb, + offset + 6, 2, "Reserved: %d", + tvb_get_ntohs(tvb, offset + 6)); + /* TODO Show all Home Agent Addresses */ + break; + case ICMP6_MIP6_MPS: + proto_tree_add_text(icmp6_tree, tvb, + offset + 4, 2, "Identifier: %d (0x%02x)", + tvb_get_ntohs(tvb, offset + 4), + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(icmp6_tree, tvb, + offset + 6, 2, "Reserved: %d", + tvb_get_ntohs(tvb, offset + 6)); + break; + case ICMP6_MIP6_MPA: + proto_tree_add_text(icmp6_tree, tvb, + offset + 4, 2, "Identifier: %d (0x%02x)", + tvb_get_ntohs(tvb, offset + 4), + tvb_get_ntohs(tvb, offset + 4)); + proto_tree_add_text(icmp6_tree, tvb, + offset + 6, 2, + decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6), + 0x8000, 16, + "Managed Address Configuration", + "No Managed Address Configuration")); + proto_tree_add_text(icmp6_tree, tvb, + offset + 6, 2, + decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6), + 0x4000, 16, + "Other Stateful Configuration", + "No Other Stateful Configuration")); + /* TODO Show all options */ + break; default: next_tvb = tvb_new_subset(tvb, offset + sizeof(*dp), -1, -1); call_dissector(data_handle,next_tvb, pinfo, tree); diff --git a/packet-ipv6.c b/packet-ipv6.c index bc90fb0521..b5b0bf20bc 100644 --- a/packet-ipv6.c +++ b/packet-ipv6.c @@ -1,7 +1,7 @@ /* packet-ipv6.c * Routines for IPv6 packet disassembly * - * $Id: packet-ipv6.c,v 1.92 2003/01/23 09:39:32 guy Exp $ + * $Id: packet-ipv6.c,v 1.93 2003/02/04 20:16:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -74,22 +74,7 @@ static int hf_ipv6_fragment_error = -1; static int hf_ipv6_mipv6_type = -1; static int hf_ipv6_mipv6_length = -1; -static int hf_ipv6_mipv6_a_flag = -1; -static int hf_ipv6_mipv6_h_flag = -1; -static int hf_ipv6_mipv6_r_flag = -1; -static int hf_ipv6_mipv6_d_flag = -1; -static int hf_ipv6_mipv6_m_flag = -1; -static int hf_ipv6_mipv6_b_flag = -1; -static int hf_ipv6_mipv6_prefix_length = -1; -static int hf_ipv6_mipv6_sequence_number = -1; -static int hf_ipv6_mipv6_life_time = -1; -static int hf_ipv6_mipv6_status = -1; -static int hf_ipv6_mipv6_refresh = -1; static int hf_ipv6_mipv6_home_address = -1; -static int hf_ipv6_mipv6_sub_type = -1; -static int hf_ipv6_mipv6_sub_length = -1; -static int hf_ipv6_mipv6_sub_unique_ID = -1; -static int hf_ipv6_mipv6_sub_alternative_COA = -1; static gint ett_ipv6 = -1; static gint ett_ipv6_fragments = -1; @@ -270,8 +255,11 @@ dissect_routing6(tvbuff_t *tvb, int offset, proto_tree *tree) { ); } } - - /* decode... */ + if (rt.ip6r_type == 2) { + proto_tree_add_ipv6(rthdr_tree, hf_ipv6_mipv6_home_address, + tvb, offset + 8, 16, + tvb_get_ptr(tvb, offset + 8, 16)); + } } return len; @@ -332,266 +320,26 @@ dissect_frag6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, return len; } -/* Binding Update flag description */ -static const true_false_string ipv6_mipv6_bu_a_flag_value = { - "Binding Acknowledgement requested", - "Binding Acknowledgement not requested" -}; -static const true_false_string ipv6_mipv6_bu_h_flag_value = { - "Home Registration", - "No Home Registration" -}; -static const true_false_string ipv6_mipv6_bu_r_flag_value = { - "Router", - "Not a Router" -}; -static const true_false_string ipv6_mipv6_bu_d_flag_value = { - "Perform Duplicate Address Detection", - "Do not perform Duplicate Address Detection" -}; -static const true_false_string ipv6_mipv6_bu_m_flag_value = { - "MAP Registration", - "No MAP Registration" -}; -static const true_false_string ipv6_mipv6_bu_b_flag_value = { - "Request for bicasting", - "Do not request for bicasting" -}; - -static int -dissect_mipv6_ba(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) -{ - guint8 status, len = 0; - const char *status_text; - gboolean sub_options = FALSE; - - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb, - offset + len, IP6_MIPv6_OPTION_TYPE_LENGTH, - tvb_get_guint8(tvb, offset + len), - "Option Type: %u (0x%02x) - Binding Acknowledgement", - tvb_get_guint8(tvb, offset + len), - tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_TYPE_LENGTH; - if (tvb_get_guint8(tvb, offset + len) > 11) - sub_options = TRUE; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len, - IP6_MIPv6_OPTION_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_LENGTH_LENGTH; - status = tvb_get_guint8(tvb, offset + len); - switch (status) { - case BA_OK: - status_text = "- Binding Update accepted"; - break; - case BA_REAS_UNSPEC: - status_text = "- Binding Update was rejected - Reason unspecified"; - break; - case BA_ADMIN_PROH: - status_text = "- Binding Update was rejected - Administratively prohibited"; - break; - case BA_INSUF_RES: - status_text = "- Binding Update was rejected - Insufficient resources"; - break; - case BA_NO_HR: - status_text = "- Binding Update was rejected - Home registration not supported"; - break; - case BA_NO_SUBNET: - status_text = "- Binding Update was rejected - Not home subnet"; - break; - case BA_ERR_ID_LEN: - status_text = "- Binding Update was rejected - Incorrect interface identifier length"; - break; - case BA_NO_HA: - status_text = "- Binding Update was rejected - Not home agent for this mobile node"; - break; - case BA_DUPL_ADDR: - status_text = "- Binding Update was rejected - Duplicate Address Detection failed"; - break; - default: - status_text = NULL; - break; - } - if (!status_text) { - if (status > 128) - status_text = "- Binding Update was rejected"; - else - status_text = ""; - } - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_status, - tvb, offset + len, IP6_MIPv6_STATUS_LENGTH, - tvb_get_guint8(tvb, offset + len), - "Status: %u %s", tvb_get_guint8(tvb, offset + len), status_text); - len += IP6_MIPv6_STATUS_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_sequence_number, - tvb, offset + len, IP6_MIPv6_SEQUENCE_NUMBER_LENGTH, - tvb_get_ntohs(tvb, offset + len)); - len += IP6_MIPv6_SEQUENCE_NUMBER_LENGTH; - if (tvb_get_ntohl(tvb, offset + len) == 0xffffffff) { - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_life_time, - tvb, offset + len, IP6_MIPv6_LIFE_TIME_LENGTH, - tvb_get_ntohl(tvb, offset + len), - "Life Time: %u - Infinity", tvb_get_ntohl(tvb, offset + len)); - } else { - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_life_time, - tvb, offset + len, IP6_MIPv6_LIFE_TIME_LENGTH, - tvb_get_ntohl(tvb, offset + len)); - } - len += IP6_MIPv6_LIFE_TIME_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_refresh, tvb, - offset + len, IP6_MIPv6_REFRESH_LENGTH, - tvb_get_ntohl(tvb, offset + len)); - len += IP6_MIPv6_REFRESH_LENGTH; - /* sub - options */ - if (sub_options) - proto_tree_add_text(dstopt_tree, tvb, offset + len, 1, "Sub-Options"); - return len; -} - static int -dissect_mipv6_bu(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) +dissect_mipv6_hoa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) { int len = 0; - gboolean sub_options = FALSE; - - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb, offset, - IP6_MIPv6_OPTION_TYPE_LENGTH, tvb_get_guint8(tvb, offset), - "Option Type: %u (0x%02x) - Binding Update", - tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset)); - len += IP6_MIPv6_OPTION_TYPE_LENGTH; - if (tvb_get_guint8(tvb, offset + len) > 8) - sub_options = TRUE; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len, - IP6_MIPv6_OPTION_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_LENGTH_LENGTH; - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_a_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_h_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_r_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_d_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_m_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - proto_tree_add_boolean(dstopt_tree, hf_ipv6_mipv6_b_flag, tvb, offset + len, - IP6_MIPv6_FLAGS_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_FLAGS_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_prefix_length, tvb, - offset + len, - IP6_MIPv6_PREFIX_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_PREFIX_LENGTH_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_sequence_number, tvb, - offset + len, IP6_MIPv6_SEQUENCE_NUMBER_LENGTH, - tvb_get_ntohs(tvb, offset + len)); - len += IP6_MIPv6_SEQUENCE_NUMBER_LENGTH; - if (tvb_get_ntohl(tvb, offset + len) == 0xffffffff) { - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_life_time, tvb, - offset + len, IP6_MIPv6_LIFE_TIME_LENGTH, - tvb_get_ntohl(tvb, offset + len), "Life Time: %u - Infinity", - tvb_get_ntohl(tvb, offset + len)); - } else { - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_life_time, tvb, - offset + len, IP6_MIPv6_LIFE_TIME_LENGTH, tvb_get_ntohl(tvb, - offset + len)); - } - len += IP6_MIPv6_LIFE_TIME_LENGTH; - /* sub - options */ - if (sub_options) - proto_tree_add_text(dstopt_tree, tvb, offset + len, 1, "Sub-Options"); - return len; -} - -static int -dissect_mipv6_ha(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) -{ - int len = 0; - gboolean sub_options = FALSE; proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb, - offset + len, IP6_MIPv6_OPTION_TYPE_LENGTH, + offset + len, 1, tvb_get_guint8(tvb, offset + len), - "Option Type: %u (0x%02x) - Home Address", - tvb_get_guint8(tvb, offset + len), tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_TYPE_LENGTH; - if (tvb_get_guint8(tvb, offset + len) > 16) - sub_options = TRUE; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len, - IP6_MIPv6_OPTION_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_LENGTH_LENGTH; - proto_tree_add_ipv6(dstopt_tree, hf_ipv6_mipv6_home_address, tvb, - offset + len, IP6_MIPv6_HOME_ADDRESS_LENGTH, - tvb_get_ptr(tvb, offset + len, IP6_MIPv6_HOME_ADDRESS_LENGTH)); - len += IP6_MIPv6_HOME_ADDRESS_LENGTH; - /* sub - options */ - if (sub_options) - proto_tree_add_text(dstopt_tree, tvb, offset + len, 1, "Sub-Options"); - return len; -} - -static int -dissect_mipv6_br(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) -{ - int len = 0; - gboolean sub_options = FALSE; - - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_type, tvb, - offset + len, IP6_MIPv6_OPTION_TYPE_LENGTH, + "Option Type: %u (0x%02x) - Home Address Option", tvb_get_guint8(tvb, offset + len), - "Option Type: %u (0x%02x) - Binding Request", - tvb_get_guint8(tvb, offset + len), tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_TYPE_LENGTH; - if (tvb_get_guint8(tvb, offset + len) > 0) - sub_options = TRUE; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len, - IP6_MIPv6_OPTION_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_OPTION_LENGTH_LENGTH; - /* sub - options */ - if (sub_options) - proto_tree_add_text(dstopt_tree, tvb, offset + len, 1, "Sub-Options"); - return len; -} - -static int -dissect_mipv6_sub_u(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) -{ - int len = 0; - - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_sub_length, tvb, - offset + len, IP6_MIPv6_SUB_TYPE_LENGTH, - tvb_get_guint8(tvb, offset + len), - "Sub-Option Type: %u (0x%02x) - Unique Identifier Sub-Option", - tvb_get_guint8(tvb, offset + len), tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_SUB_TYPE_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_sub_length, tvb, - offset + len, IP6_MIPv6_SUB_LENGTH_LENGTH, tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_SUB_LENGTH_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_sub_unique_ID, tvb, - offset + len, IP6_MIPv6_SUB_UNIQUE_ID_LENGTH, - tvb_get_ntohs(tvb, offset + len)); - len += IP6_MIPv6_SUB_UNIQUE_ID_LENGTH; - return len; -} + len += 1; -static int -dissect_mipv6_sub_a_coa(tvbuff_t *tvb, proto_tree *dstopt_tree, int offset) -{ - int len = 0; + proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_length, tvb, offset + len, + 1, tvb_get_guint8(tvb, offset + len)); + len += 1; - proto_tree_add_uint_format(dstopt_tree, hf_ipv6_mipv6_sub_type, tvb, - offset + len, IP6_MIPv6_SUB_TYPE_LENGTH, - tvb_get_guint8(tvb, offset + len), - "Sub-Option Type: %u (0x%02x) - Alternative Care Of Address", - tvb_get_guint8(tvb, offset + len), - tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_SUB_TYPE_LENGTH; - proto_tree_add_uint(dstopt_tree, hf_ipv6_mipv6_sub_length, tvb, - offset + len, IP6_MIPv6_SUB_LENGTH_LENGTH, - tvb_get_guint8(tvb, offset + len)); - len += IP6_MIPv6_SUB_LENGTH_LENGTH; - proto_tree_add_ipv6(dstopt_tree, hf_ipv6_mipv6_sub_alternative_COA, tvb, - offset + len, IP6_MIPv6_SUB_ALTERNATIVE_COA_LENGTH, - tvb_get_ptr(tvb, offset + len, IP6_MIPv6_SUB_ALTERNATIVE_COA_LENGTH)); - len += IP6_MIPv6_SUB_ALTERNATIVE_COA_LENGTH; + proto_tree_add_ipv6(dstopt_tree, hf_ipv6_mipv6_home_address, tvb, + offset + len, 16, tvb_get_ptr(tvb, offset + len, 16)); + len += 16; return len; } @@ -680,33 +428,8 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, char *optname) mip_offset += tvb_get_guint8(tvb, mip_offset + 1) + 2; break; } - case IP6OPT_BINDING_UPDATE : - delta = dissect_mipv6_bu(tvb, dstopt_tree, mip_offset); - p += delta; - mip_offset += delta; - break; - case IP6OPT_BINDING_ACK : - delta = dissect_mipv6_ba(tvb, dstopt_tree, mip_offset); - p += delta; - mip_offset += delta; - break; - case IP6OPT_HOME_ADDRESS : - delta = dissect_mipv6_ha(tvb, dstopt_tree, mip_offset); - p += delta; - mip_offset += delta; - break; - case IP6OPT_BINDING_REQUEST : - delta = dissect_mipv6_br(tvb, dstopt_tree, mip_offset); - p += delta; - mip_offset += delta; - break; - case IP6OPT_MIPv6_UNIQUE_ID_SUB : - delta = dissect_mipv6_sub_u(tvb, dstopt_tree, mip_offset); - p += delta; - mip_offset += delta; - break; - case IP6OPT_MIPv6_ALTERNATIVE_COA_SUB : - delta = dissect_mipv6_sub_a_coa(tvb, dstopt_tree, mip_offset); + case IP6OPT_HOME_ADDRESS: + delta = dissect_mipv6_hoa(tvb, dstopt_tree, mip_offset); p += delta; mip_offset += delta; break; @@ -1084,87 +807,20 @@ proto_register_ipv6(void) FT_NONE, BASE_NONE, NULL, 0x0, "IPv6 Fragments", HFILL }}, - /* BT INSERT BEGIN */ + /* Mobile IPv6 */ { &hf_ipv6_mipv6_type, { "Option Type ", "ipv6.mipv6_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_ipv6_mipv6_length, - { "Option Length ", "ipv6.mipv6_length", - FT_UINT8, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_a_flag, - { "Acknowledge (A) ", "ipv6.mipv6_a_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_a_flag_value), - IP6_MIPv6_BU_A_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_h_flag, - { "Home Registration (H) ", "ipv6.mipv6_h_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_h_flag_value), - IP6_MIPv6_BU_H_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_r_flag, - { "Router (R) ", "ipv6.mipv6_r_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_r_flag_value), - IP6_MIPv6_BU_R_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_d_flag, - { "Duplicate Address Detection (D) ", "ipv6.mipv6_d_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_d_flag_value), - IP6_MIPv6_BU_D_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_m_flag, - { "MAP Registration (M) ", "ipv6.mipv6_m_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_m_flag_value), - IP6_MIPv6_BU_M_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_b_flag, - { "Bicasting all (B) ", "ipv6.mipv6_b_flag", - FT_BOOLEAN, 8, TFS(&ipv6_mipv6_bu_b_flag_value), - IP6_MIPv6_BU_B_FLAG, - "", HFILL }}, - { &hf_ipv6_mipv6_prefix_length, - { "Prefix Length ", "ipv6.mipv6_prefix_length", + { "Option Length ", "ipv6.mipv6_length", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, - { &hf_ipv6_mipv6_sequence_number, - { "Sequence Number ", "ipv6.mipv6_sequence_number", - FT_UINT16, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_life_time, - { "Life Time ", "ipv6.mipv6_life_time", - FT_UINT32, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_status, - { "Status ", "ipv6.mipv6_status", - FT_UINT8, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_refresh, - { "Refresh ", "ipv6.mipv6_refresh", - FT_UINT32, BASE_DEC, NULL, 0x0, - "", HFILL }}, { &hf_ipv6_mipv6_home_address, - { "Home Address ", "ipv6.mipv6_home_address", - FT_IPv6, BASE_HEX, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_sub_type, - { "Sub-Option Type ", "ipv6.mipv6_sub_type", - FT_UINT8, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_sub_length, - { "Sub-Option Length ", "ipv6.mipv6_sub_length", - FT_UINT8, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_sub_unique_ID, - { "Unique Identifier ", "ipv6.mipv6_sub_unique_ID", - FT_UINT16, BASE_DEC, NULL, 0x0, - "", HFILL }}, - { &hf_ipv6_mipv6_sub_alternative_COA, - { "Alternative Care of Address ", "ipv6.mipv6_sub_alternative_COA", + { "Home Address ", "ipv6.mipv6_home_address", FT_IPv6, BASE_HEX, NULL, 0x0, "", HFILL }}, - /* BT INSERT END */ #ifdef TEST_FINALHDR { &hf_ipv6_final, { "Final next header", "ipv6.final", diff --git a/packet-ipv6.h b/packet-ipv6.h index 813b45d1d3..2646913400 100644 --- a/packet-ipv6.h +++ b/packet-ipv6.h @@ -1,7 +1,7 @@ /* packet-ipv6.h * Definitions for IPv6 packet disassembly * - * $Id: packet-ipv6.h,v 1.29 2002/10/22 22:04:21 jmayer Exp $ + * $Id: packet-ipv6.h,v 1.30 2003/02/04 20:16:57 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -110,13 +110,7 @@ struct ip6_dest { #define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ #define IP6OPT_MINLEN 2 -#define IP6OPT_BINDING_UPDATE 0xC6 /* 11 0 00110 */ -#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ -#define IP6OPT_BINDING_REQUEST 0x08 /* 00 0 01000 */ #define IP6OPT_HOME_ADDRESS 0xC9 /* 11 0 01001 */ -#define IP6OPT_EID 0x8a /* 10 0 01010 */ -#define IP6OPT_MIPv6_UNIQUE_ID_SUB 0x02 /* 00 0 00010 */ -#define IP6OPT_MIPv6_ALTERNATIVE_COA_SUB 0x04 /* 00 0 00100 */ #define IP6OPT_TYPE(o) ((o) & 0xC0) #define IP6OPT_TYPE_SKIP 0x00 @@ -126,42 +120,6 @@ struct ip6_dest { #define IP6OPT_MUTABLE 0x20 -/* MIPv6 Lifetime */ -#define MIP_INFINITY 0xffffffff /* Infinity lifetime */ - -/* Binding Update Flags */ -#define IP6_MIPv6_BU_A_FLAG 0x80 /* 1000 0000 - Acknowledge */ -#define IP6_MIPv6_BU_H_FLAG 0x40 /* 0100 0000 - Home Registration */ -#define IP6_MIPv6_BU_R_FLAG 0x20 /* 0010 0000 - Router */ -#define IP6_MIPv6_BU_D_FLAG 0x10 /* 0001 0000 - Duplicate Address Detection */ -#define IP6_MIPv6_BU_M_FLAG 0x8 /* 0000 1000 - MAP Registration */ -#define IP6_MIPv6_BU_B_FLAG 0x4 /* 0000 0100 - Request for bicasting */ - -#define IP6_MIPv6_OPTION_TYPE_LENGTH 1 -#define IP6_MIPv6_OPTION_LENGTH_LENGTH 1 -#define IP6_MIPv6_FLAGS_LENGTH 1 -#define IP6_MIPv6_PREFIX_LENGTH_LENGTH 1 -#define IP6_MIPv6_SEQUENCE_NUMBER_LENGTH 2 -#define IP6_MIPv6_LIFE_TIME_LENGTH 4 -#define IP6_MIPv6_REFRESH_LENGTH 4 -#define IP6_MIPv6_STATUS_LENGTH 1 -#define IP6_MIPv6_HOME_ADDRESS_LENGTH 16 -#define IP6_MIPv6_SUB_TYPE_LENGTH 1 -#define IP6_MIPv6_SUB_LENGTH_LENGTH 1 -#define IP6_MIPv6_SUB_UNIQUE_ID_LENGTH 2 -#define IP6_MIPv6_SUB_ALTERNATIVE_COA_LENGTH 16 - -/* Binding Ackonwledgement Status */ -#define BA_OK 0 /* Binding update accepted */ -#define BA_REAS_UNSPEC 128 /*Reason unspecified */ -#define BA_ADMIN_PROH 130 /* Administratively prohibited */ -#define BA_INSUF_RES 131 /* Insufficient resources */ -#define BA_NO_HR 132 /* Home registration not supported */ -#define BA_NO_SUBNET 133 /* Not home subnet */ -#define BA_ERR_ID_LEN 136 /* Incorrect interface identifier length */ -#define BA_NO_HA 137 /* Not home agent for this mobile node */ -#define BA_DUPL_ADDR 138 /* Duplicate Address Detection failed */ - /* Routing header */ struct ip6_rthdr { guint8 ip6r_nxt; /* next header */ @@ -255,7 +213,12 @@ struct icmp6_hdr { #define MLD6_MTRACE_RESP 141 /* mtrace response(to sender) */ #define MLD6_MTRACE 142 /* mtrace messages */ -#define ICMP6_MAXTYPE 142 +#define ICMP6_MIP6_DHAAD_REQUEST 150 /* Mobile IPv6 DHAAD */ +#define ICMP6_MIP6_DHAAD_REPLY 151 /* Mobile IPv6 DHAAD */ +#define ICMP6_MIP6_MPS 152 /* Mobile IPv6 MPS */ +#define ICMP6_MIP6_MPA 153 /* Mobile IPv6 MPA */ + +#define ICMP6_MAXTYPE 153 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ #define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ diff --git a/packet-mip6.c b/packet-mip6.c new file mode 100644 index 0000000000..e331dc936b --- /dev/null +++ b/packet-mip6.c @@ -0,0 +1,688 @@ +/* packet-mip6.c + * + * $Id: packet-mip6.c,v 1.1 2003/02/04 20:16:57 guy Exp $ + * + * Routines for Mobile IPv6 dissection (draft-ietf-mobileip-ipv6-20.txt) + * Copyright 2003 Oy L M Ericsson Ab <teemu.rinta-aho@ericsson.fi> + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <epan/packet.h> + +#include "ipproto.h" +#include "packet-mip6.h" + +/* Initialize the protocol and registered header fields */ +static int proto_mip6 = -1; +static int hf_mip6_proto = -1; +static int hf_mip6_hlen = -1; +static int hf_mip6_mhtype = -1; +static int hf_mip6_reserved = -1; +static int hf_mip6_csum = -1; + +static int hf_mip6_hoti_cookie = -1; + +static int hf_mip6_coti_cookie = -1; + +static int hf_mip6_hot_nindex = -1; +static int hf_mip6_hot_cookie = -1; +static int hf_mip6_hot_token = -1; + +static int hf_mip6_cot_nindex = -1; +static int hf_mip6_cot_cookie = -1; +static int hf_mip6_cot_token = -1; + +static int hf_mip6_bu_seqnr = -1; +static int hf_mip6_bu_a_flag = -1; +static int hf_mip6_bu_h_flag = -1; +static int hf_mip6_bu_l_flag = -1; +static int hf_mip6_bu_k_flag = -1; +static int hf_mip6_bu_lifetime = -1; + +static int hf_mip6_ba_status = -1; +static int hf_mip6_ba_k_flag = -1; +static int hf_mip6_ba_seqnr = -1; +static int hf_mip6_ba_lifetime = -1; + +static int hf_mip6_be_status = -1; +static int hf_mip6_be_haddr = -1; + +static int hf_mip6_bra_interval = -1; + +static int hf_mip6_acoa_acoa = -1; + +static int hf_mip6_ni_hni = -1; +static int hf_mip6_ni_cni = -1; + +static int hf_mip6_bad_auth = -1; + +/* Initialize the subtree pointers */ +static gint ett_mip6 = -1; + +/* Functions to dissect the mobility headers */ + +static int +dissect_mip6_brr(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Binding Error"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_BRR_LEN, "Binding Refresh Request"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + } + + return MIP6_DATA_OFF+MIP6_BRR_LEN; +} + +static int +dissect_mip6_hoti(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Home Test Init"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_HOTI_LEN, "Home Test Init"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_hoti_cookie, tvb, + MIP6_HOTI_COOKIE_OFF, MIP6_HOTI_COOKIE_LEN, FALSE); + } + + return MIP6_DATA_OFF+MIP6_HOTI_LEN; +} + +static int +dissect_mip6_coti(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Care-of Test Init"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_COTI_LEN, "Care-of Test Init"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_coti_cookie, tvb, + MIP6_COTI_COOKIE_OFF, MIP6_COTI_COOKIE_LEN, FALSE); + } + + return MIP6_DATA_OFF+MIP6_COTI_LEN; +} + +static int +dissect_mip6_hot(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Home Test"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_HOT_LEN, "Home Test"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_hot_nindex, tvb, + MIP6_HOT_INDEX_OFF, MIP6_HOT_INDEX_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_hot_cookie, tvb, + MIP6_HOT_COOKIE_OFF, MIP6_HOT_COOKIE_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_hot_token, tvb, + MIP6_HOT_TOKEN_OFF, MIP6_HOT_TOKEN_LEN, FALSE); + } + + return MIP6_DATA_OFF+MIP6_HOT_LEN; +} + +static int +dissect_mip6_cot(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Care-of Test"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_COT_LEN, "Care-of Test"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_cot_nindex, tvb, + MIP6_COT_INDEX_OFF, MIP6_COT_INDEX_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_cot_cookie, tvb, + MIP6_COT_COOKIE_OFF, MIP6_COT_COOKIE_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_hot_token, tvb, + MIP6_COT_TOKEN_OFF, MIP6_COT_TOKEN_LEN, FALSE); + } + + return MIP6_DATA_OFF+MIP6_COT_LEN; +} + +static int +dissect_mip6_bu(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + int lifetime; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Binding Update"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_BU_LEN, "Binding Update"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_bu_seqnr, tvb, + MIP6_BU_SEQNR_OFF, MIP6_BU_SEQNR_LEN, FALSE); + + proto_tree_add_item(data_tree, hf_mip6_bu_a_flag, tvb, + MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_bu_h_flag, tvb, + MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_bu_l_flag, tvb, + MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_bu_k_flag, tvb, + MIP6_BU_FLAGS_OFF, MIP6_BU_FLAGS_LEN, FALSE); + + lifetime = tvb_get_ntohs(tvb, MIP6_BU_LIFETIME_OFF); + proto_tree_add_uint_format(data_tree, hf_mip6_bu_lifetime, tvb, + MIP6_BU_LIFETIME_OFF, + MIP6_BU_LIFETIME_LEN, lifetime, + "Lifetime: %d (%ld seconds)", + lifetime, (long)lifetime * 4); + } + + return MIP6_DATA_OFF+MIP6_BU_LEN; +} + +static int +dissect_mip6_ba(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + int lifetime; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Binding Acknowledgement"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_BA_LEN, "Binding Acknowledgement"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_ba_status, tvb, + MIP6_BA_STATUS_OFF, MIP6_BA_STATUS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_ba_k_flag, tvb, + MIP6_BA_FLAGS_OFF, MIP6_BA_FLAGS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_ba_seqnr, tvb, + MIP6_BA_SEQNR_OFF, MIP6_BA_SEQNR_LEN, FALSE); + lifetime = tvb_get_ntohs(tvb, MIP6_BA_LIFETIME_OFF); + proto_tree_add_uint_format(data_tree, hf_mip6_ba_lifetime, tvb, + MIP6_BA_LIFETIME_OFF, + MIP6_BA_LIFETIME_LEN, lifetime, + "Lifetime: %d (%ld seconds)", + lifetime, (long)lifetime * 4); + } + + return MIP6_DATA_OFF+MIP6_BA_LEN; +} + +static int +dissect_mip6_be(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Binding Error"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_BE_LEN, "Binding Error"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(data_tree, hf_mip6_be_status, tvb, + MIP6_BE_STATUS_OFF, MIP6_BE_STATUS_LEN, FALSE); + proto_tree_add_item(data_tree, hf_mip6_be_haddr, tvb, + MIP6_BE_HOA_OFF, MIP6_BE_HOA_LEN, FALSE); + } + + return MIP6_DATA_OFF+MIP6_BE_LEN; +} + +static int +dissect_mip6_unknown(tvbuff_t *tvb, proto_tree *mip6_tree, packet_info *pinfo) +{ + proto_tree *data_tree = NULL; + proto_item *ti; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Unknown MH Type"); + + if (mip6_tree) { + ti = proto_tree_add_text(mip6_tree, tvb, MIP6_DATA_OFF, + MIP6_DATA_OFF+1, "Unknown MH Type"); + data_tree = proto_item_add_subtree(ti, ett_mip6); + } + + return MIP6_DATA_OFF+1; +} + +/* Functions to dissect the mobility options */ + +static int +dissect_mip6_opt_pad1(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + proto_tree_add_text(opts_tree, tvb, offset, len, "Pad1"); + + return offset+len; +} + +static int +dissect_mip6_opt_padn(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + proto_tree_add_text(opts_tree, tvb, offset, len, "PadN: %u bytes", len); + + return offset+len; +} + +static int +dissect_mip6_opt_bra(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + proto_tree *opt_tree = NULL; + proto_item *ti; + int len, ri; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + ti = proto_tree_add_text(opts_tree, tvb, offset, len, + "Binding Refresh Advice"); + opt_tree = proto_item_add_subtree(ti, ett_mip6); + + ri = tvb_get_ntohs(tvb, offset+MIP6_BRA_RI_OFF); + proto_tree_add_uint_format(opt_tree, hf_mip6_bra_interval, tvb, + offset+MIP6_BRA_RI_OFF, MIP6_BRA_RI_LEN, + ri, "Refresh interval: %d (%ld seconds)", + ri, (long)ri * 4); + + return offset+len; +} + +static int +dissect_mip6_opt_acoa(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + proto_tree *opt_tree = NULL; + proto_item *ti; + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + ti = proto_tree_add_text(opts_tree, tvb, offset, len, + "Alternate Care-of Address"); + opt_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(opt_tree, hf_mip6_acoa_acoa, tvb, + offset+MIP6_ACOA_ACOA_OFF, MIP6_ACOA_ACOA_LEN, FALSE); + + return offset+len; +} + +static int +dissect_mip6_opt_ni(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + proto_tree *opt_tree = NULL; + proto_item *ti; + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + ti = proto_tree_add_text(opts_tree, tvb, offset, len, "Nonce Indices"); + opt_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(opt_tree, hf_mip6_ni_hni, tvb, + offset+MIP6_NI_HNI_OFF, MIP6_NI_HNI_LEN, FALSE); + proto_tree_add_item(opt_tree, hf_mip6_ni_cni, tvb, + offset+MIP6_NI_CNI_OFF, MIP6_NI_CNI_LEN, FALSE); + + return offset+len; +} + +static int +dissect_mip6_opt_bad(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + proto_tree *opt_tree = NULL; + proto_item *ti; + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + ti = proto_tree_add_text(opts_tree, tvb, offset, len, + "Binding Authorization Data"); + opt_tree = proto_item_add_subtree(ti, ett_mip6); + + proto_tree_add_item(opt_tree, hf_mip6_bad_auth, tvb, + offset+MIP6_BAD_AUTH_OFF, MIP6_BAD_AUTH_LEN, FALSE); + + return offset+len; +} + +static int +dissect_mip6_opt_unknown(tvbuff_t *tvb, proto_tree *opts_tree, int offset) +{ + int len; + + len = (tvb_get_guint8(tvb, offset + 1)) + 2; + proto_tree_add_text(opts_tree, tvb, offset, len, "Unknown option"); + + return offset+len; +} + +/* Function to dissect mobility options */ +static int +dissect_mip6_options(tvbuff_t *tvb, proto_tree *mip6_tree, int offset, int len) +{ + proto_tree *opts_tree = NULL; + proto_item *ti; + guint8 type; + + if (!mip6_tree) + return len; + + ti = proto_tree_add_text(mip6_tree, tvb, offset, len - offset, + "Mobility Options"); + opts_tree = proto_item_add_subtree(ti, ett_mip6); + + while (offset < len) { + type = tvb_get_guint8(tvb, offset); + switch (type) { + case PAD1: + offset = dissect_mip6_opt_pad1(tvb, opts_tree, offset); + break; + case PADN: + offset = dissect_mip6_opt_padn(tvb, opts_tree, offset); + break; + case BRA: + offset = dissect_mip6_opt_bra(tvb, opts_tree, offset); + break; + case ACOA: + offset = dissect_mip6_opt_acoa(tvb, opts_tree, offset); + break; + case NI: + offset = dissect_mip6_opt_ni(tvb, opts_tree, offset); + break; + case BAD: + offset = dissect_mip6_opt_bad(tvb, opts_tree, offset); + break; + default: + dissect_mip6_opt_unknown(tvb, opts_tree, offset); + offset = len; + } + } + + return len; +} + +/* Function that dissects the whole MIPv6 packet */ +static void +dissect_mip6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *mip6_tree = NULL; + proto_item *ti; + guint8 type; + guint len, offset = 0; + + /* Make entries in Protocol column and Info column on summary display */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "MIPv6"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + len = (tvb_get_guint8(tvb, MIP6_HLEN_OFF) + 1) * 8; + if (tree) { + ti = proto_tree_add_item(tree, proto_mip6, tvb, 0, len, FALSE); + mip6_tree = proto_item_add_subtree(ti, ett_mip6); + + /* Process header fields */ + proto_tree_add_uint_format(mip6_tree, hf_mip6_proto, tvb, + MIP6_PROTO_OFF, 1, + tvb_get_guint8(tvb, MIP6_PROTO_OFF), + "Payload protocol: %s (0x%02x)", + ipprotostr( + tvb_get_guint8(tvb, MIP6_PROTO_OFF)), + tvb_get_guint8(tvb, MIP6_PROTO_OFF)); + + proto_tree_add_uint_format(mip6_tree, hf_mip6_hlen, tvb, + MIP6_HLEN_OFF, 1, + tvb_get_guint8(tvb, MIP6_HLEN_OFF), + "Header length: %u (%u bytes)", + tvb_get_guint8(tvb, MIP6_HLEN_OFF), + len); + + proto_tree_add_item(mip6_tree, hf_mip6_mhtype, tvb, + MIP6_TYPE_OFF, 1, FALSE); + + proto_tree_add_item(mip6_tree, hf_mip6_reserved, tvb, + MIP6_RES_OFF, 1, FALSE); + + proto_tree_add_item(mip6_tree, hf_mip6_csum, tvb, + MIP6_CSUM_OFF, 2, FALSE); + } + + /* Process mobility header */ + type = tvb_get_guint8(tvb, MIP6_TYPE_OFF); + switch (type) { + case BRR: + offset = dissect_mip6_brr(tvb, mip6_tree, pinfo); + break; + case HOTI: + offset = dissect_mip6_hoti(tvb, mip6_tree, pinfo); + break; + case COTI: + offset = dissect_mip6_coti(tvb, mip6_tree, pinfo); + break; + case HOT: + offset = dissect_mip6_hot(tvb, mip6_tree, pinfo); + break; + case COT: + offset = dissect_mip6_cot(tvb, mip6_tree, pinfo); + break; + case BU: + offset = dissect_mip6_bu(tvb, mip6_tree, pinfo); + break; + case BA: + offset = dissect_mip6_ba(tvb, mip6_tree, pinfo); + break; + case BE: + offset = dissect_mip6_be(tvb, mip6_tree, pinfo); + break; + default: + dissect_mip6_unknown(tvb, mip6_tree, pinfo); + offset = len; + break; + } + + /* Process mobility options */ + if (offset < len) + dissect_mip6_options(tvb, mip6_tree, offset, len); +} + +/* Register the protocol with Ethereal */ +void +proto_register_mip6(void) +{ + /* Setup list of header fields */ + static hf_register_info hf[] = { + + { &hf_mip6_proto, { "Payload protocol", "mip6.proto", + FT_UINT8, BASE_DEC, NULL, 0, + "Payload protocol", HFILL }}, + { &hf_mip6_hlen, { "Header length", "mip6.hlen", + FT_UINT8, BASE_DEC, NULL, 0, + "Header length", HFILL }}, + { &hf_mip6_mhtype, { "Mobility Header Type", "mip6.mhtype", + FT_UINT8, BASE_DEC, VALS(mip6_mh_types), 0, + "Mobility Header Type", HFILL }}, + { &hf_mip6_reserved, { "Reserved", "mip6.reserved", + FT_UINT8, BASE_HEX, NULL, 0, + "Reserved", HFILL }}, + { &hf_mip6_csum, { "Checksum", "mip6.csum", + FT_UINT16, BASE_HEX, NULL, 0, + "Header Checksum", HFILL }}, + + { &hf_mip6_hoti_cookie, { "Home Init Cookie", "mip6.hoti.cookie", + FT_UINT64, BASE_HEX, NULL, 0, + "Home Init Cookie", HFILL }}, + + { &hf_mip6_coti_cookie, { "Care-of Init Cookie", "mip6.coti.cookie", + FT_UINT64, BASE_HEX, NULL, 0, + "Care-of Init Cookie", HFILL }}, + + { &hf_mip6_hot_nindex, { "Home Nonce Index", "mip6.hot.nindex", + FT_UINT16, BASE_DEC, NULL, 0, + "Home Nonce Index", HFILL }}, + { &hf_mip6_hot_cookie, { "Home Init Cookie", "mip6.hot.cookie", + FT_UINT64, BASE_HEX, NULL, 0, + "Home Init Cookie", HFILL }}, + { &hf_mip6_hot_token, { "Home Keygen Token", "mip6.hot.token", + FT_UINT64, BASE_HEX, NULL, 0, + "Home Keygen Token", HFILL }}, + + { &hf_mip6_cot_nindex, { "Care-of Nonce Index", "mip6.cot.nindex", + FT_UINT16, BASE_DEC, NULL, 0, + "Care-of Nonce Index", HFILL }}, + { &hf_mip6_cot_cookie, { "Care-of Init Cookie", "mip6.cot.cookie", + FT_UINT64, BASE_HEX, NULL, 0, + "Care-of Init Cookie", HFILL }}, + { &hf_mip6_cot_token, { "Care-of Keygen Token", "mip6.cot.token", + FT_UINT64, BASE_HEX, NULL, 0, + "Care-of Keygen Token", HFILL }}, + + { &hf_mip6_bu_seqnr, { "Sequence number", "mip6.bu.seqnr", + FT_UINT16, BASE_DEC, NULL, 0, + "Sequence number", HFILL }}, + { &hf_mip6_bu_a_flag, { "Acknowledge (A) flag", "mip6.bu.a_flag", + FT_BOOLEAN, 8, TFS(&mip6_bu_a_flag_value), + 0x80, "Acknowledge (A) flag", HFILL }}, + { &hf_mip6_bu_h_flag, { "Home Registration (H) flag", + "mip6.bu.h_flag", + FT_BOOLEAN, 8, TFS(&mip6_bu_h_flag_value), + 0x40, "Home Registration (H) flag", HFILL }}, + { &hf_mip6_bu_l_flag, { "Link-Local Compatibility (L) flag", + "mip6.bu.l_flag", + FT_BOOLEAN, 8, TFS(&mip6_bu_l_flag_value), + 0x20, "Home Registration (H) flag", HFILL }}, + { &hf_mip6_bu_k_flag, { "Key Management Compatibility (K) flag", + "mip6.bu.k_flag", + FT_BOOLEAN, 8, TFS(&mip6_bu_k_flag_value), + 0x10, "Key Management Compatibility (K) flag", + HFILL }}, + { &hf_mip6_bu_lifetime, { "Lifetime", "mip6.bu.lifetime", + FT_UINT16, BASE_DEC, NULL, 0, + "Lifetime", HFILL }}, + + { &hf_mip6_ba_status, { "Status", "mip6.ba.status", + FT_UINT8, BASE_DEC, + VALS(&mip6_ba_status_value), 0, + "Binding Acknowledgement status", HFILL }}, + { &hf_mip6_ba_k_flag, { "Key Management Compatibility (K) flag", + "mip6.ba.k_flag", + FT_BOOLEAN, 8, TFS(&mip6_bu_k_flag_value), + 0x80, "Key Management Compatibility (K) flag", + HFILL }}, + { &hf_mip6_ba_seqnr, { "Sequence number", "mip6.ba.seqnr", + FT_UINT16, BASE_DEC, NULL, 0, + "Sequence number", HFILL }}, + { &hf_mip6_ba_lifetime, { "Lifetime", "mip6.ba.lifetime", + FT_UINT16, BASE_DEC, NULL, 0, + "Lifetime", HFILL }}, + + { &hf_mip6_be_status, { "Status", "mip6.be.status", + FT_UINT8, BASE_DEC, + VALS(&mip6_be_status_value), 0, + "Binding Error status", HFILL }}, + { &hf_mip6_be_haddr, { "Home Address", "mip6.be.haddr", + FT_IPv6, BASE_HEX, NULL, 0, + "Home Address", HFILL }}, + + { &hf_mip6_bra_interval, { "Refresh interval", "mip6.bra.interval", + FT_UINT16, BASE_DEC, NULL, 0, + "Refresh interval", HFILL }}, + + { &hf_mip6_acoa_acoa, { "Alternate care-of address", "mip6.acoa.acoa", + FT_IPv6, BASE_HEX, NULL, 0, + "Alternate Care-of address", HFILL }}, + + { &hf_mip6_ni_hni, { "Home nonce index", "mip6.ni.hni", + FT_UINT16, BASE_DEC, NULL, 0, + "Home nonce index", HFILL }}, + { &hf_mip6_ni_cni, { "Care-of nonce index", "mip6.ni.cni", + FT_UINT16, BASE_DEC, NULL, 0, + "Care-of nonce index", HFILL }}, + + { &hf_mip6_bad_auth, { "Authenticator", "mip6.bad.auth", + FT_BYTES, BASE_HEX, NULL, 0, + "Care-of nonce index", HFILL }} + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_mip6 + }; + + /* Register the protocol name and description */ + proto_mip6 = proto_register_protocol("Mobile IPv6", "MIPv6", "mipv6"); + + /* Register the dissector by name */ + /* register_dissector("mipv6", dissect_mip6, proto_mip6); */ + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_mip6, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +}; + +void +proto_reg_handoff_mip6(void) +{ + dissector_handle_t mip6_handle; + + /* mip6_handle = find_dissector("mipv6"); */ + mip6_handle = create_dissector_handle(dissect_mip6, proto_mip6); + dissector_add("ip.proto", IP_PROTO_MIPV6, mip6_handle); +} diff --git a/packet-mip6.h b/packet-mip6.h new file mode 100644 index 0000000000..38fda0e2b1 --- /dev/null +++ b/packet-mip6.h @@ -0,0 +1,217 @@ +/* packet-mip6.h + * + * $Id: packet-mip6.h,v 1.1 2003/02/04 20:16:57 guy Exp $ + * + * Definitions for Mobile IPv6 dissection (draft-ietf-mobileip-ipv6-20.txt) + * Copyright 2003 Oy L M Ericsson Ab <teemu.rinta-aho@ericsson.fi> + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + +#ifndef __PACKET_MIP6_H_DEFINED__ +#define __PACKET_MIP6_H_DEFINED__ + +/* Mobility Header types */ +typedef enum { + BRR = 0, + HOTI = 1, + COTI = 2, + HOT = 3, + COT = 4, + BU = 5, + BA = 6, + BE = 7 +} mhTypes; + +static const value_string mip6_mh_types[] = { + {BRR, "Binding Refresh Request"}, + {HOTI, "Home Test Init"}, + {COTI, "Care-of Test Init"}, + {HOT, "Home Test"}, + {COT, "Care-of Test"}, + {BU, "Binding Update"}, + {BA, "Binding Acknowledgement"}, + {BE, "Binding Error"}, + {0, NULL} +}; + +/* Mobility Option types */ +typedef enum { + PAD1 = 0, + PADN = 1, + BRA = 2, + ACOA = 3, + NI = 4, + BAD = 5 +} optTypes; + +static const value_string mip6_opt_types[]= { + {PAD1, "Pad1"}, + {PADN, "PadN"}, + {BRA, "Binding Refresh Advice"}, + {ACOA, "Alternate Care-of Address"}, + {NI, "Nonce Indices"}, + {BAD, "Binding Authorization Data"}, + {0, NULL} +}; + +/* Binding Update flag description */ +static const true_false_string mip6_bu_a_flag_value = { + "Binding Acknowledgement requested", + "Binding Acknowledgement not requested" +}; + +static const true_false_string mip6_bu_h_flag_value = { + "Home Registration", + "No Home Registration" +}; + +static const true_false_string mip6_bu_l_flag_value = { + "Link-Local Address Compatibility", + "No Link-Local Address Compatibility" +}; + +static const true_false_string mip6_bu_k_flag_value = { + "Key Management Mobility Compatibility", + "No Key Management Mobility Compatibility" +}; + +/* Binding Acknowledgement status values */ +static const value_string mip6_ba_status_value[] = { + { 0, "Binding Update accepted" }, + { 128, "Reason unspecified" }, + { 129, "Adminstratively prohibited" }, + { 130, "Insufficient resources" }, + { 131, "Home registration not supported" }, + { 132, "Not home subnet" }, + { 133, "Not home agent for this mobile node" }, + { 134, "Duplicate address detection failed" }, + { 135, "Sequence number out of window" }, + { 136, "Expired home nonce index" }, + { 137, "Expired care-of nonce index" }, + { 138, "Expired nonces" }, + { 0, NULL } +}; + +/* Binding Error status values */ +static const value_string mip6_be_status_value[] = { + { 1, "Unknown binding for Home Address destination option" }, + { 2, "Unrecognized MH type value" }, + { 0, NULL } +}; + +/* Message lengths */ +#define MIP6_BRR_LEN 2 +#define MIP6_HOTI_LEN 10 +#define MIP6_COTI_LEN 10 +#define MIP6_HOT_LEN 18 +#define MIP6_COT_LEN 18 +#define MIP6_BU_LEN 6 +#define MIP6_BA_LEN 6 +#define MIP6_BE_LEN 18 + +/* Field offsets & lengths for mobility headers */ +#define MIP6_PROTO_OFF 0 +#define MIP6_HLEN_OFF 1 +#define MIP6_TYPE_OFF 2 +#define MIP6_RES_OFF 3 +#define MIP6_CSUM_OFF 4 +#define MIP6_DATA_OFF 6 +#define MIP6_PROTO_LEN 1 +#define MIP6_HLEN_LEN 1 +#define MIP6_TYPE_LEN 1 +#define MIP6_RES_LEN 1 +#define MIP6_CSUM_LEN 2 + +#define MIP6_BRR_RES_OFF 6 +#define MIP6_BRR_OPTS_OFF 8 +#define MIP6_BRR_RES_LEN 2 + +#define MIP6_HOTI_RES_OFF 6 +#define MIP6_HOTI_COOKIE_OFF 8 +#define MIP6_HOTI_OPTS_OFF 16 +#define MIP6_HOTI_RES_LEN 2 +#define MIP6_HOTI_COOKIE_LEN 8 + +#define MIP6_COTI_RES_OFF 6 +#define MIP6_COTI_COOKIE_OFF 8 +#define MIP6_COTI_OPTS_OFF 16 +#define MIP6_COTI_RES_LEN 2 +#define MIP6_COTI_COOKIE_LEN 8 + +#define MIP6_HOT_INDEX_OFF 6 +#define MIP6_HOT_COOKIE_OFF 8 +#define MIP6_HOT_TOKEN_OFF 16 +#define MIP6_HOT_OPTS_OFF 24 +#define MIP6_HOT_INDEX_LEN 2 +#define MIP6_HOT_COOKIE_LEN 8 +#define MIP6_HOT_TOKEN_LEN 8 + +#define MIP6_COT_INDEX_OFF 6 +#define MIP6_COT_COOKIE_OFF 8 +#define MIP6_COT_TOKEN_OFF 16 +#define MIP6_COT_OPTS_OFF 24 +#define MIP6_COT_INDEX_LEN 2 +#define MIP6_COT_COOKIE_LEN 8 +#define MIP6_COT_TOKEN_LEN 8 + +#define MIP6_BU_SEQNR_OFF 6 +#define MIP6_BU_FLAGS_OFF 8 +#define MIP6_BU_RES_OFF 9 +#define MIP6_BU_LIFETIME_OFF 10 +#define MIP6_BU_OPTS_OFF 12 +#define MIP6_BU_SEQNR_LEN 2 +#define MIP6_BU_FLAGS_LEN 1 +#define MIP6_BU_RES_LEN 1 +#define MIP6_BU_LIFETIME_LEN 2 + +#define MIP6_BA_STATUS_OFF 6 +#define MIP6_BA_FLAGS_OFF 7 +#define MIP6_BA_SEQNR_OFF 8 +#define MIP6_BA_LIFETIME_OFF 10 +#define MIP6_BA_OPTS_OFF 12 +#define MIP6_BA_STATUS_LEN 1 +#define MIP6_BA_FLAGS_LEN 1 +#define MIP6_BA_SEQNR_LEN 2 +#define MIP6_BA_LIFETIME_LEN 2 + +#define MIP6_BE_STATUS_OFF 6 +#define MIP6_BE_RES_OFF 7 +#define MIP6_BE_HOA_OFF 8 +#define MIP6_BE_OPTS_OFF 24 +#define MIP6_BE_STATUS_LEN 1 +#define MIP6_BE_RES_LEN 1 +#define MIP6_BE_HOA_LEN 16 + +/* Field offsets & lengths for mobility options */ +#define MIP6_BRA_RI_OFF 2 +#define MIP6_BRA_RI_LEN 2 + +#define MIP6_ACOA_ACOA_OFF 2 +#define MIP6_ACOA_ACOA_LEN 16 + +#define MIP6_NI_HNI_OFF 2 +#define MIP6_NI_CNI_OFF 4 +#define MIP6_NI_HNI_LEN 2 +#define MIP6_NI_CNI_LEN 2 + +#define MIP6_BAD_AUTH_OFF 2 +#define MIP6_BAD_AUTH_LEN 12 + +#endif /* __PACKET_MIP6_H_DEFINED__ */ |