diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-02-04 20:17:01 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-02-04 20:17:01 +0000 |
commit | 625d0088d424c53f2308652383f5d132133bcb48 (patch) | |
tree | e3371104722ddbc2caf0cb00f13259aee31edc0e /packet-mip6.c | |
parent | e2d77c29113420b5ec4b200bd30ddd356d3a2c46 (diff) |
From Teemu Rinta-aho: draft 20 MIPv6 support (now in a file of its own).
svn path=/trunk/; revision=7071
Diffstat (limited to 'packet-mip6.c')
-rw-r--r-- | packet-mip6.c | 688 |
1 files changed, 688 insertions, 0 deletions
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); +} |