xref: /freebsd/contrib/tcpdump/print-mobility.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
15b0fe478SBruce M Simpson /*
25b0fe478SBruce M Simpson  * Copyright (C) 2002 WIDE Project.
35b0fe478SBruce M Simpson  * All rights reserved.
45b0fe478SBruce M Simpson  *
55b0fe478SBruce M Simpson  * Redistribution and use in source and binary forms, with or without
65b0fe478SBruce M Simpson  * modification, are permitted provided that the following conditions
75b0fe478SBruce M Simpson  * are met:
85b0fe478SBruce M Simpson  * 1. Redistributions of source code must retain the above copyright
95b0fe478SBruce M Simpson  *    notice, this list of conditions and the following disclaimer.
105b0fe478SBruce M Simpson  * 2. Redistributions in binary form must reproduce the above copyright
115b0fe478SBruce M Simpson  *    notice, this list of conditions and the following disclaimer in the
125b0fe478SBruce M Simpson  *    documentation and/or other materials provided with the distribution.
135b0fe478SBruce M Simpson  * 3. Neither the name of the project nor the names of its contributors
145b0fe478SBruce M Simpson  *    may be used to endorse or promote products derived from this software
155b0fe478SBruce M Simpson  *    without specific prior written permission.
165b0fe478SBruce M Simpson  *
175b0fe478SBruce M Simpson  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
185b0fe478SBruce M Simpson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
195b0fe478SBruce M Simpson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
205b0fe478SBruce M Simpson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
215b0fe478SBruce M Simpson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
225b0fe478SBruce M Simpson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
235b0fe478SBruce M Simpson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
245b0fe478SBruce M Simpson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
255b0fe478SBruce M Simpson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
265b0fe478SBruce M Simpson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
275b0fe478SBruce M Simpson  * SUCH DAMAGE.
285b0fe478SBruce M Simpson  */
295b0fe478SBruce M Simpson 
303340d773SGleb Smirnoff /* \summary: IPv6 mobility printer */
310bff6a5aSEd Maste /* RFC 3775 */
323340d773SGleb Smirnoff 
33ee67461eSJoseph Mingrone #include <config.h>
345b0fe478SBruce M Simpson 
35ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
365b0fe478SBruce M Simpson 
373340d773SGleb Smirnoff #include "netdissect.h"
385b0fe478SBruce M Simpson #include "addrtoname.h"
393340d773SGleb Smirnoff #include "extract.h"
403340d773SGleb Smirnoff 
410bff6a5aSEd Maste #include "ip6.h"
420bff6a5aSEd Maste 
435b0fe478SBruce M Simpson 
445b0fe478SBruce M Simpson /* Mobility header */
455b0fe478SBruce M Simpson struct ip6_mobility {
46ee67461eSJoseph Mingrone 	nd_uint8_t ip6m_pproto;	/* following payload protocol (for PG) */
47ee67461eSJoseph Mingrone 	nd_uint8_t ip6m_len;	/* length in units of 8 octets */
48ee67461eSJoseph Mingrone 	nd_uint8_t ip6m_type;	/* message type */
49ee67461eSJoseph Mingrone 	nd_uint8_t reserved;	/* reserved */
50ee67461eSJoseph Mingrone 	nd_uint16_t ip6m_cksum;	/* sum of IPv6 pseudo-header and MH */
515b0fe478SBruce M Simpson 	union {
52ee67461eSJoseph Mingrone 		nd_uint16_t	ip6m_un_data16[1]; /* type-specific field */
53ee67461eSJoseph Mingrone 		nd_uint8_t	ip6m_un_data8[2];  /* type-specific field */
545b0fe478SBruce M Simpson 	} ip6m_dataun;
555b0fe478SBruce M Simpson };
565b0fe478SBruce M Simpson 
575b0fe478SBruce M Simpson #define ip6m_data16	ip6m_dataun.ip6m_un_data16
585b0fe478SBruce M Simpson #define ip6m_data8	ip6m_dataun.ip6m_un_data8
595b0fe478SBruce M Simpson 
605b0fe478SBruce M Simpson #define IP6M_MINLEN	8
615b0fe478SBruce M Simpson 
62ee67461eSJoseph Mingrone /* https://www.iana.org/assignments/mobility-parameters/mobility-parameters.xhtml */
633c602fabSXin LI 
645b0fe478SBruce M Simpson /* message type */
655b0fe478SBruce M Simpson #define IP6M_BINDING_REQUEST	0	/* Binding Refresh Request */
665b0fe478SBruce M Simpson #define IP6M_HOME_TEST_INIT	1	/* Home Test Init */
675b0fe478SBruce M Simpson #define IP6M_CAREOF_TEST_INIT	2	/* Care-of Test Init */
685b0fe478SBruce M Simpson #define IP6M_HOME_TEST		3	/* Home Test */
695b0fe478SBruce M Simpson #define IP6M_CAREOF_TEST	4	/* Care-of Test */
705b0fe478SBruce M Simpson #define IP6M_BINDING_UPDATE	5	/* Binding Update */
715b0fe478SBruce M Simpson #define IP6M_BINDING_ACK	6	/* Binding Acknowledgement */
725b0fe478SBruce M Simpson #define IP6M_BINDING_ERROR	7	/* Binding Error */
738bdc5a62SPatrick Kelsey #define IP6M_MAX		7
748bdc5a62SPatrick Kelsey 
753340d773SGleb Smirnoff static const struct tok ip6m_str[] = {
763340d773SGleb Smirnoff 	{ IP6M_BINDING_REQUEST,  "BRR"  },
773340d773SGleb Smirnoff 	{ IP6M_HOME_TEST_INIT,   "HoTI" },
783340d773SGleb Smirnoff 	{ IP6M_CAREOF_TEST_INIT, "CoTI" },
793340d773SGleb Smirnoff 	{ IP6M_HOME_TEST,        "HoT"  },
803340d773SGleb Smirnoff 	{ IP6M_CAREOF_TEST,      "CoT"  },
813340d773SGleb Smirnoff 	{ IP6M_BINDING_UPDATE,   "BU"   },
823340d773SGleb Smirnoff 	{ IP6M_BINDING_ACK,      "BA"   },
833340d773SGleb Smirnoff 	{ IP6M_BINDING_ERROR,    "BE"   },
843340d773SGleb Smirnoff 	{ 0, NULL }
853340d773SGleb Smirnoff };
863340d773SGleb Smirnoff 
878bdc5a62SPatrick Kelsey static const unsigned ip6m_hdrlen[IP6M_MAX + 1] = {
888bdc5a62SPatrick Kelsey 	IP6M_MINLEN,      /* IP6M_BINDING_REQUEST  */
898bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 8,  /* IP6M_HOME_TEST_INIT   */
908bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 8,  /* IP6M_CAREOF_TEST_INIT */
918bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 16, /* IP6M_HOME_TEST        */
928bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 16, /* IP6M_CAREOF_TEST      */
938bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 4,  /* IP6M_BINDING_UPDATE   */
948bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 4,  /* IP6M_BINDING_ACK      */
958bdc5a62SPatrick Kelsey 	IP6M_MINLEN + 16, /* IP6M_BINDING_ERROR    */
968bdc5a62SPatrick Kelsey };
975b0fe478SBruce M Simpson 
985b0fe478SBruce M Simpson /* Mobility Header Options */
995b0fe478SBruce M Simpson #define IP6MOPT_MINLEN		2
1005b0fe478SBruce M Simpson #define IP6MOPT_PAD1          0x0	/* Pad1 */
1015b0fe478SBruce M Simpson #define IP6MOPT_PADN          0x1	/* PadN */
1025b0fe478SBruce M Simpson #define IP6MOPT_REFRESH	      0x2	/* Binding Refresh Advice */
1035b0fe478SBruce M Simpson #define IP6MOPT_REFRESH_MINLEN  4
1045b0fe478SBruce M Simpson #define IP6MOPT_ALTCOA        0x3	/* Alternate Care-of Address */
1055b0fe478SBruce M Simpson #define IP6MOPT_ALTCOA_MINLEN  18
1065b0fe478SBruce M Simpson #define IP6MOPT_NONCEID       0x4	/* Nonce Indices */
1075b0fe478SBruce M Simpson #define IP6MOPT_NONCEID_MINLEN  6
1085b0fe478SBruce M Simpson #define IP6MOPT_AUTH          0x5	/* Binding Authorization Data */
1095b0fe478SBruce M Simpson #define IP6MOPT_AUTH_MINLEN    12
1105b0fe478SBruce M Simpson 
111ee67461eSJoseph Mingrone static const struct tok ip6m_binding_update_bits [] = {
112ee67461eSJoseph Mingrone 	{ 0x08, "A" },
113ee67461eSJoseph Mingrone 	{ 0x04, "H" },
114ee67461eSJoseph Mingrone 	{ 0x02, "L" },
115ee67461eSJoseph Mingrone 	{ 0x01, "K" },
116ee67461eSJoseph Mingrone 	{ 0, NULL }
117ee67461eSJoseph Mingrone };
118ee67461eSJoseph Mingrone 
1193340d773SGleb Smirnoff static int
mobility_opt_print(netdissect_options * ndo,const u_char * bp,const unsigned len)1203c602fabSXin LI mobility_opt_print(netdissect_options *ndo,
1213c602fabSXin LI                    const u_char *bp, const unsigned len)
1225b0fe478SBruce M Simpson {
1233c602fabSXin LI 	unsigned i, optlen;
1245b0fe478SBruce M Simpson 
1255b0fe478SBruce M Simpson 	for (i = 0; i < len; i += optlen) {
126ee67461eSJoseph Mingrone 		if (GET_U_1(bp + i) == IP6MOPT_PAD1)
1275b0fe478SBruce M Simpson 			optlen = 1;
1285b0fe478SBruce M Simpson 		else {
1298bdc5a62SPatrick Kelsey 			if (i + 1 < len) {
130ee67461eSJoseph Mingrone 				optlen = GET_U_1(bp + i + 1) + 2;
131*0a7e5f1fSJoseph Mingrone 			} else
1325b0fe478SBruce M Simpson 				goto trunc;
1335b0fe478SBruce M Simpson 		}
1345b0fe478SBruce M Simpson 		if (i + optlen > len)
1355b0fe478SBruce M Simpson 			goto trunc;
136ee67461eSJoseph Mingrone 		ND_TCHECK_1(bp + i + optlen);
1375b0fe478SBruce M Simpson 
138ee67461eSJoseph Mingrone 		switch (GET_U_1(bp + i)) {
1395b0fe478SBruce M Simpson 		case IP6MOPT_PAD1:
140ee67461eSJoseph Mingrone 			ND_PRINT("(pad1)");
1415b0fe478SBruce M Simpson 			break;
1425b0fe478SBruce M Simpson 		case IP6MOPT_PADN:
1435b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_MINLEN) {
144ee67461eSJoseph Mingrone 				ND_PRINT("(padn: trunc)");
1455b0fe478SBruce M Simpson 				goto trunc;
1465b0fe478SBruce M Simpson 			}
147ee67461eSJoseph Mingrone 			ND_PRINT("(padn)");
1485b0fe478SBruce M Simpson 			break;
1495b0fe478SBruce M Simpson 		case IP6MOPT_REFRESH:
1505b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_REFRESH_MINLEN) {
151ee67461eSJoseph Mingrone 				ND_PRINT("(refresh: trunc)");
1525b0fe478SBruce M Simpson 				goto trunc;
1535b0fe478SBruce M Simpson 			}
1545b0fe478SBruce M Simpson 			/* units of 4 secs */
155ee67461eSJoseph Mingrone 			ND_PRINT("(refresh: %u)",
156ee67461eSJoseph Mingrone 				GET_BE_U_2(bp + i + 2) << 2);
1575b0fe478SBruce M Simpson 			break;
1585b0fe478SBruce M Simpson 		case IP6MOPT_ALTCOA:
1595b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_ALTCOA_MINLEN) {
160ee67461eSJoseph Mingrone 				ND_PRINT("(altcoa: trunc)");
1615b0fe478SBruce M Simpson 				goto trunc;
1625b0fe478SBruce M Simpson 			}
163ee67461eSJoseph Mingrone 			ND_PRINT("(alt-CoA: %s)", GET_IP6ADDR_STRING(bp + i + 2));
1645b0fe478SBruce M Simpson 			break;
1655b0fe478SBruce M Simpson 		case IP6MOPT_NONCEID:
1665b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_NONCEID_MINLEN) {
167ee67461eSJoseph Mingrone 				ND_PRINT("(ni: trunc)");
1685b0fe478SBruce M Simpson 				goto trunc;
1695b0fe478SBruce M Simpson 			}
170ee67461eSJoseph Mingrone 			ND_PRINT("(ni: ho=0x%04x co=0x%04x)",
171ee67461eSJoseph Mingrone 				GET_BE_U_2(bp + i + 2),
172ee67461eSJoseph Mingrone 				GET_BE_U_2(bp + i + 4));
1735b0fe478SBruce M Simpson 			break;
1745b0fe478SBruce M Simpson 		case IP6MOPT_AUTH:
1755b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_AUTH_MINLEN) {
176ee67461eSJoseph Mingrone 				ND_PRINT("(auth: trunc)");
1775b0fe478SBruce M Simpson 				goto trunc;
1785b0fe478SBruce M Simpson 			}
179ee67461eSJoseph Mingrone 			ND_PRINT("(auth)");
1805b0fe478SBruce M Simpson 			break;
1815b0fe478SBruce M Simpson 		default:
1825b0fe478SBruce M Simpson 			if (len - i < IP6MOPT_MINLEN) {
183ee67461eSJoseph Mingrone 				ND_PRINT("(sopt_type %u: trunc)",
184ee67461eSJoseph Mingrone 					 GET_U_1(bp + i));
1855b0fe478SBruce M Simpson 				goto trunc;
1865b0fe478SBruce M Simpson 			}
187ee67461eSJoseph Mingrone 			ND_PRINT("(type-0x%02x: len=%u)", GET_U_1(bp + i),
188ee67461eSJoseph Mingrone 				 GET_U_1(bp + i + 1));
1895b0fe478SBruce M Simpson 			break;
1905b0fe478SBruce M Simpson 		}
1915b0fe478SBruce M Simpson 	}
1923340d773SGleb Smirnoff 	return 0;
1935b0fe478SBruce M Simpson 
1945b0fe478SBruce M Simpson trunc:
1953340d773SGleb Smirnoff 	return 1;
1965b0fe478SBruce M Simpson }
1975b0fe478SBruce M Simpson 
1985b0fe478SBruce M Simpson /*
1995b0fe478SBruce M Simpson  * Mobility Header
2005b0fe478SBruce M Simpson  */
2015b0fe478SBruce M Simpson int
mobility_print(netdissect_options * ndo,const u_char * bp,const u_char * bp2 _U_)2023c602fabSXin LI mobility_print(netdissect_options *ndo,
2033c602fabSXin LI                const u_char *bp, const u_char *bp2 _U_)
2045b0fe478SBruce M Simpson {
2055b0fe478SBruce M Simpson 	const struct ip6_mobility *mh;
2065b0fe478SBruce M Simpson 	const u_char *ep;
2073c602fabSXin LI 	unsigned mhlen, hlen;
2083c602fabSXin LI 	uint8_t type;
2095b0fe478SBruce M Simpson 
210ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "mobility";
2113340d773SGleb Smirnoff 	mh = (const struct ip6_mobility *)bp;
2125b0fe478SBruce M Simpson 
2135b0fe478SBruce M Simpson 	/* 'ep' points to the end of available data. */
2143c602fabSXin LI 	ep = ndo->ndo_snapend;
2155b0fe478SBruce M Simpson 
216ee67461eSJoseph Mingrone 	if (!ND_TTEST_1(mh->ip6m_len)) {
2175b0fe478SBruce M Simpson 		/*
2185b0fe478SBruce M Simpson 		 * There's not enough captured data to include the
2195b0fe478SBruce M Simpson 		 * mobility header length.
2205b0fe478SBruce M Simpson 		 *
2215b0fe478SBruce M Simpson 		 * Our caller expects us to return the length, however,
2225b0fe478SBruce M Simpson 		 * so return a value that will run to the end of the
2235b0fe478SBruce M Simpson 		 * captured data.
2245b0fe478SBruce M Simpson 		 *
2255b0fe478SBruce M Simpson 		 * XXX - "ip6_print()" doesn't do anything with the
2265b0fe478SBruce M Simpson 		 * returned length, however, as it breaks out of the
2275b0fe478SBruce M Simpson 		 * header-processing loop.
2285b0fe478SBruce M Simpson 		 */
229ee67461eSJoseph Mingrone 		mhlen = (unsigned)(ep - bp);
2305b0fe478SBruce M Simpson 		goto trunc;
2315b0fe478SBruce M Simpson 	}
232ee67461eSJoseph Mingrone 	mhlen = (GET_U_1(mh->ip6m_len) + 1) << 3;
2335b0fe478SBruce M Simpson 
2345b0fe478SBruce M Simpson 	/* XXX ip6m_cksum */
2355b0fe478SBruce M Simpson 
236ee67461eSJoseph Mingrone 	type = GET_U_1(mh->ip6m_type);
2378bdc5a62SPatrick Kelsey 	if (type <= IP6M_MAX && mhlen < ip6m_hdrlen[type]) {
238ee67461eSJoseph Mingrone 		ND_PRINT("(header length %u is too small for type %u)", mhlen, type);
2398bdc5a62SPatrick Kelsey 		goto trunc;
2408bdc5a62SPatrick Kelsey 	}
241ee67461eSJoseph Mingrone 	ND_PRINT("mobility: %s", tok2str(ip6m_str, "type-#%u", type));
2425b0fe478SBruce M Simpson 	switch (type) {
2435b0fe478SBruce M Simpson 	case IP6M_BINDING_REQUEST:
2445b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
2455b0fe478SBruce M Simpson 		break;
2465b0fe478SBruce M Simpson 	case IP6M_HOME_TEST_INIT:
2475b0fe478SBruce M Simpson 	case IP6M_CAREOF_TEST_INIT:
2485b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
2493c602fabSXin LI 		if (ndo->ndo_vflag) {
250ee67461eSJoseph Mingrone 			ND_PRINT(" %s Init Cookie=%08x:%08x",
2515b0fe478SBruce M Simpson 			       type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of",
252ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen),
253ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen + 4));
2545b0fe478SBruce M Simpson 		}
2555b0fe478SBruce M Simpson 		hlen += 8;
2565b0fe478SBruce M Simpson 		break;
2575b0fe478SBruce M Simpson 	case IP6M_HOME_TEST:
2585b0fe478SBruce M Simpson 	case IP6M_CAREOF_TEST:
259ee67461eSJoseph Mingrone 		ND_PRINT(" nonce id=0x%x", GET_BE_U_2(mh->ip6m_data16[0]));
2605b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
2613c602fabSXin LI 		if (ndo->ndo_vflag) {
262ee67461eSJoseph Mingrone 			ND_PRINT(" %s Init Cookie=%08x:%08x",
2635b0fe478SBruce M Simpson 			       type == IP6M_HOME_TEST ? "Home" : "Care-of",
264ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen),
265ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen + 4));
2665b0fe478SBruce M Simpson 		}
2675b0fe478SBruce M Simpson 		hlen += 8;
2683c602fabSXin LI 		if (ndo->ndo_vflag) {
269ee67461eSJoseph Mingrone 			ND_PRINT(" %s Keygen Token=%08x:%08x",
2705b0fe478SBruce M Simpson 			       type == IP6M_HOME_TEST ? "Home" : "Care-of",
271ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen),
272ee67461eSJoseph Mingrone 			       GET_BE_U_4(bp + hlen + 4));
2735b0fe478SBruce M Simpson 		}
2745b0fe478SBruce M Simpson 		hlen += 8;
2755b0fe478SBruce M Simpson 		break;
2765b0fe478SBruce M Simpson 	case IP6M_BINDING_UPDATE:
277ee67461eSJoseph Mingrone 	    {
278ee67461eSJoseph Mingrone 		int bits;
279ee67461eSJoseph Mingrone 		ND_PRINT(" seq#=%u", GET_BE_U_2(mh->ip6m_data16[0]));
2805b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
281ee67461eSJoseph Mingrone 		ND_TCHECK_2(bp + hlen);
282ee67461eSJoseph Mingrone 		bits = (GET_U_1(bp + hlen) & 0xf0) >> 4;
283ee67461eSJoseph Mingrone 		if (bits) {
284ee67461eSJoseph Mingrone 			ND_PRINT(" ");
285ee67461eSJoseph Mingrone 			ND_PRINT("%s",
286ee67461eSJoseph Mingrone 				 bittok2str_nosep(ip6m_binding_update_bits,
287ee67461eSJoseph Mingrone 				 "bits-#0x%x", bits));
2880bff6a5aSEd Maste 		}
2895b0fe478SBruce M Simpson 		/* Reserved (4bits) */
2905b0fe478SBruce M Simpson 		hlen += 1;
2915b0fe478SBruce M Simpson 		/* Reserved (8bits) */
2925b0fe478SBruce M Simpson 		hlen += 1;
2935b0fe478SBruce M Simpson 		/* units of 4 secs */
294ee67461eSJoseph Mingrone 		ND_PRINT(" lifetime=%u", GET_BE_U_2(bp + hlen) << 2);
2955b0fe478SBruce M Simpson 		hlen += 2;
2965b0fe478SBruce M Simpson 		break;
297ee67461eSJoseph Mingrone 	    }
2985b0fe478SBruce M Simpson 	case IP6M_BINDING_ACK:
299ee67461eSJoseph Mingrone 		ND_PRINT(" status=%u", GET_U_1(mh->ip6m_data8[0]));
300ee67461eSJoseph Mingrone 		if (GET_U_1(mh->ip6m_data8[1]) & 0x80)
301ee67461eSJoseph Mingrone 			ND_PRINT(" K");
3025b0fe478SBruce M Simpson 		/* Reserved (7bits) */
3035b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
304ee67461eSJoseph Mingrone 		ND_PRINT(" seq#=%u", GET_BE_U_2(bp + hlen));
3055b0fe478SBruce M Simpson 		hlen += 2;
3065b0fe478SBruce M Simpson 		/* units of 4 secs */
307ee67461eSJoseph Mingrone 		ND_PRINT(" lifetime=%u", GET_BE_U_2(bp + hlen) << 2);
3085b0fe478SBruce M Simpson 		hlen += 2;
3095b0fe478SBruce M Simpson 		break;
3105b0fe478SBruce M Simpson 	case IP6M_BINDING_ERROR:
311ee67461eSJoseph Mingrone 		ND_PRINT(" status=%u", GET_U_1(mh->ip6m_data8[0]));
3125b0fe478SBruce M Simpson 		/* Reserved */
3135b0fe478SBruce M Simpson 		hlen = IP6M_MINLEN;
314ee67461eSJoseph Mingrone 		ND_PRINT(" homeaddr %s", GET_IP6ADDR_STRING(bp + hlen));
3155b0fe478SBruce M Simpson 		hlen += 16;
3165b0fe478SBruce M Simpson 		break;
3175b0fe478SBruce M Simpson 	default:
318ee67461eSJoseph Mingrone 		ND_PRINT(" len=%u", GET_U_1(mh->ip6m_len));
3195b0fe478SBruce M Simpson 		return(mhlen);
3205b0fe478SBruce M Simpson 		break;
3215b0fe478SBruce M Simpson 	}
3223c602fabSXin LI 	if (ndo->ndo_vflag)
323ee67461eSJoseph Mingrone 		if (mobility_opt_print(ndo, bp + hlen, mhlen - hlen))
324ee67461eSJoseph Mingrone 			goto trunc;
3255b0fe478SBruce M Simpson 
3265b0fe478SBruce M Simpson 	return(mhlen);
3275b0fe478SBruce M Simpson 
3285b0fe478SBruce M Simpson  trunc:
329ee67461eSJoseph Mingrone 	nd_print_trunc(ndo);
3300bff6a5aSEd Maste 	return(-1);
3315b0fe478SBruce M Simpson }
332