12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
2453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.86 2008-02-05 19:36:13 guy Exp $";
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ip6.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "icmp6.h"
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipproto.h"
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "udp.h"
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ah.h"
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *get_rtpref(u_int);
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *get_lifetime(u_int32_t);
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void print_lladdr(const u_char *, size_t);
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void icmp6_opt_print(const u_char *, int);
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void mld6_print(const u_char *);
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void mldv2_report_print(const u_char *, u_int);
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void mldv2_query_print(const u_char *, u_int);
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct udphdr *get_upperlayer(u_char *, u_int *);
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void dnsname_print(const u_char *, const u_char *);
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *);
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void icmp6_rrenum_print(const u_char *, const u_char *);
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef abs
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define abs(a)	((0 < (a)) ? (a) : -(a))
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6553f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* inline the various RPL definitions */
6653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ND_RPL_MESSAGE 0x9B
6753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_type_values[] = {
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH, "destination unreachable"},
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_PACKET_TOO_BIG, "packet too big"},
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"},
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_PARAM_PROB, "parameter problem"},
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ECHO_REQUEST, "echo request"},
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ECHO_REPLY, "echo reply"},
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_QUERY, "multicast listener query"},
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_REPORT, "multicast listener report"},
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_DONE, "multicast listener done"},
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_ROUTER_SOLICIT, "router solicitation"},
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_ROUTER_ADVERT, "router advertisement"},
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"},
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NEIGHBOR_ADVERT, "neighbor advertisement"},
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_REDIRECT, "redirect"},
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ROUTER_RENUMBERING, "router renumbering"},
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { IND_SOLICIT, "inverse neighbor solicitation"},
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { IND_ADVERT, "inverse neighbor advertisement"},
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLDV2_LISTENER_REPORT, "multicast listener report v2"},
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_HADISCOV_REQUEST, "ha discovery request"},
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_HADISCOV_REPLY, "ha discovery reply"},
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"},
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"},
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_WRUREQUEST, "who-are-you request"},
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_WRUREPLY, "who-are-you reply"},
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_NI_QUERY, "node information query"},
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_NI_REPLY, "node information reply"},
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_MTRACE, "mtrace message"},
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_MTRACE_RESP, "mtrace response"},
9753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { ND_RPL_MESSAGE,   "RPL"},
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_dst_unreach_code_values[] = {
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" },
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"},
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"},
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_ADDR, "unreachable address"},
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_NOPORT, "unreachable port"},
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_opt_pi_flag_values[] = {
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_ONLINK, "onlink" },
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_AUTO, "auto" },
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_ROUTER, "router" },
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_opt_ra_flag_values[] = {
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_MANAGED, "managed" },
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_OTHER, "other stateful"},
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_HOME_AGENT, "home agent"},
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_nd_na_flag_values[] = {
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_ROUTER, "router" },
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_SOLICITED, "solicited" },
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_OVERRIDE, "override" },
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok icmp6_opt_values[] = {
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_SOURCE_LINKADDR, "source link-address"},
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_TARGET_LINKADDR, "destination link-address"},
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_PREFIX_INFORMATION, "prefix info"},
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_REDIRECTED_HEADER, "redirected header"},
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_MTU, "mtu"},
13853f17a9db278d33517d9888dd77848f554522a38JP Abgrall   { ND_OPT_RDNSS, "rdnss"},
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrall   { ND_OPT_DNSSL, "dnssl"},
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_ADVINTERVAL, "advertisement interval"},
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_HOMEAGENT_INFO, "homeagent information"},
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_ROUTE_INFO, "route info"},
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { 0,	NULL }
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* mldv2 report types */
14753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok mldv2report2str[] = {
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 1,	"is_in" },
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 2,	"is_ex" },
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 3,	"to_in" },
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 4,	"to_ex" },
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 5,	"allow" },
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 6,	"block" },
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 0,	NULL }
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_rtpref(u_int v)
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static const char *rtpref_str[] = {
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"medium",		/* 00 */
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"high",			/* 01 */
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"rsv",			/* 10 */
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"low"			/* 11 */
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	};
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff];
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_lifetime(u_int32_t v)
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static char buf[20];
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (v == (u_int32_t)~0UL)
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return "infinity";
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else {
17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		snprintf(buf, sizeof(buf), "%us", v);
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return buf;
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectprint_lladdr(const u_int8_t *p, size_t l)
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_int8_t *ep, *q;
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	q = p;
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = p + l;
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (l > 0 && q < ep) {
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (q > p)
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(":");
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("%02x", *q++);
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		l--;
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp,
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int len)
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
20153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len,
20253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    IPPROTO_ICMPV6));
20353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
20453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
20553f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum ND_RPL_CODE {
20653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIS   =0x00,
20753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO   =0x01,
20853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DAO   =0x02,
20953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DAO_ACK=0x03,
21053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_SDIS  =0x80,
21153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_SDIO  =0x81,
21253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_SDAO  =0x82,
21353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_SDAO_ACK=0x83,
21453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_SCC   =0x8A,
21553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
21653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
21753f17a9db278d33517d9888dd77848f554522a38JP Abgrallenum ND_RPL_DIO_FLAGS {
21853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_GROUNDED = 0x80,
21953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_DATRIG   = 0x40,
22053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_DASUPPORT= 0x20,
22153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_RES4     = 0x10,
22253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_RES3     = 0x08,
22353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_RPL_DIO_PRF_MASK = 0x07,  /* 3-bit preference */
22453f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
22553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
22653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct nd_rpl_dio {
22753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int8_t rpl_flags;
22853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int8_t rpl_seq;
22953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int8_t rpl_instanceid;
23053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int8_t rpl_dagrank;
23153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int8_t rpl_dagid[16];
23253f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
23353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
23453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void
23553f17a9db278d33517d9888dd77848f554522a38JP Abgrallrpl_print(netdissect_options *ndo,
23653f17a9db278d33517d9888dd77848f554522a38JP Abgrall          const struct icmp6_hdr *hdr,
23753f17a9db278d33517d9888dd77848f554522a38JP Abgrall          const u_char *bp, u_int length _U_)
23853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
23953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp;
24053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        int secured = hdr->icmp6_code & 0x80;
24153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        int basecode= hdr->icmp6_code & 0x7f;
24253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ND_TCHECK(dio->rpl_dagid);
24453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(secured) {
24653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, ", (SEC)"));
24753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        } else {
24853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, ", (CLR)"));
24953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
25053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(basecode) {
25253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case ND_RPL_DIS:
25353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, "DODAG Information Solicitation"));
25453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(ndo->ndo_vflag) {
25553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
25653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
25753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case ND_RPL_DIO:
25853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, "DODAG Information Object"));
25953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(ndo->ndo_vflag) {
26053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        char dagid[65];
26153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        char *d = dagid;
26253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        int  i;
26353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        for(i=0;i<16;i++) {
26453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                if(isprint(dio->rpl_dagid[i])) {
26553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                        *d++ = dio->rpl_dagid[i];
26653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                } else {
26753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                        int cnt=snprintf(d,4,"0x%02x",
26853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                                         dio->rpl_dagid[i]);
26953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                        d += cnt;
27053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                }
27153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        }
27253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        *d++ = '\0';
27353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]",
27453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                  dio->rpl_seq,
27553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                  dio->rpl_instanceid,
27653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                  dio->rpl_dagrank,
27753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                  dagid));
27853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
27953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
28053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case ND_RPL_DAO:
28153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, "Destination Advertisement Object"));
28253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(ndo->ndo_vflag) {
28353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
28453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
28553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case ND_RPL_DAO_ACK:
28653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, "Destination Advertisement Object Ack"));
28753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(ndo->ndo_vflag) {
28853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
28953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
29053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
29153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                ND_PRINT((ndo, "RPL message, unknown code %u",hdr->icmp6_code));
29253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
29353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
29453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return;
29553f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
29653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	ND_PRINT((ndo," [|truncated]"));
29753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return;
29853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
30153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
30353f17a9db278d33517d9888dd77848f554522a38JP Abgrallicmp6_print(netdissect_options *ndo,
30453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            const u_char *bp, u_int length, const u_char *bp2, int fragmented)
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct icmp6_hdr *dp;
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct ip6_hdr *ip;
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct ip6_hdr *oip;
3092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct udphdr *ouh;
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int dport;
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int prot;
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dp = (struct icmp6_hdr *)bp;
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ip = (struct ip6_hdr *)bp2;
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	oip = (struct ip6_hdr *)(dp + 1);
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK(dp->icmp6_cksum);
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag && !fragmented) {
32353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		u_int16_t sum, udp_sum;
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (TTEST2(bp[0], length)) {
32653f17a9db278d33517d9888dd77848f554522a38JP Abgrall			udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum);
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			sum = icmp6_cksum(ip, dp, length);
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (sum != 0)
32953f17a9db278d33517d9888dd77848f554522a38JP Abgrall				(void)printf("[bad icmp6 cksum 0x%04x -> 0x%04x!] ",
33053f17a9db278d33517d9888dd77848f554522a38JP Abgrall				    udp_sum,
33153f17a9db278d33517d9888dd77848f554522a38JP Abgrall				    in_cksum_shouldbe(udp_sum, sum));
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				(void)printf("[icmp6 sum ok] ");
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type));
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* display cosmetics: print the packet length for printer that use the vflag now */
34053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (vflag && (dp->icmp6_type == ND_ROUTER_SOLICIT ||
34153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ND_ROUTER_ADVERT ||
34253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ND_NEIGHBOR_ADVERT ||
34353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ND_NEIGHBOR_SOLICIT ||
34453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ND_REDIRECT ||
34553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ICMP6_HADISCOV_REPLY ||
34653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                      dp->icmp6_type == ICMP6_MOBILEPREFIX_ADVERT ))
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", length %u", length);
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (dp->icmp6_type) {
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_DST_UNREACH:
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code));
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_ADMIN:
3572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_ADDR:
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf(" %s",ip6addr_string(&oip->ip6_dst));
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
3602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_BEYONDSCOPE:
3612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %s, source address %s",
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       ip6addr_string(&oip->ip6_dst),
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       ip6addr_string(&oip->ip6_src));
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_NOPORT:
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((ouh = get_upperlayer((u_char *)oip, &prot))
3672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    == NULL)
3682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
3692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			dport = EXTRACT_16BITS(&ouh->uh_dport);
3712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			switch (prot) {
3722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case IPPROTO_TCP:
3732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s tcp port %s",
3742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					tcpport_string(dport));
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case IPPROTO_UDP:
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s udp port %s",
3792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					udpport_string(dport));
3812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default:
3832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s protocol %d port %d unreachable",
3842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					oip->ip6_nxt, dport);
3862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
3882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
3902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (vflag <= 1) {
3912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            print_unknown_data(bp,"\n\t",length);
3922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            return;
3932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
3952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_PACKET_TOO_BIG:
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(dp->icmp6_mtu);
3992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu));
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_TIME_EXCEEDED:
4022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
4032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
4042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_TIME_EXCEED_TRANSIT:
4052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" for %s",
4062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				ip6addr_string(&oip->ip6_dst));
4072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_TIME_EXCEED_REASSEMBLY:
4092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" (reassembly)");
4102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
4122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", unknown code (%u)", dp->icmp6_code);
4132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_PARAM_PROB:
4172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
4182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
4192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_HEADER:
42053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf(", erroneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
4212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_NEXTHEADER:
4232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
4242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_OPTION:
4262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
4272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
4292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", code-#%d",
4302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       dp->icmp6_code);
4312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
4322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ECHO_REQUEST:
4352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ECHO_REPLY:
4362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(dp->icmp6_seq);
4372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq));
4382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_QUERY:
4402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (length == MLD_MINLEN) {
4412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			mld6_print((const u_char *)dp);
4422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else if (length >= MLDV2_MINLEN) {
44353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf(" v2");
4442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			mldv2_query_print((const u_char *)dp, length);
4452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
4462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" unknown-version (len %u) ", length);
4472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_REPORT:
4502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mld6_print((const u_char *)dp);
4512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_REDUCTION:
4532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mld6_print((const u_char *)dp);
4542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_ROUTER_SOLICIT:
4562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RTSOLLEN 8
4572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + RTSOLLEN,
4592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - RTSOLLEN);
4602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_ROUTER_ADVERT:
4632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RTADVLEN 16
4642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct nd_router_advert *p;
4662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p = (struct nd_router_advert *)dp;
4682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(p->nd_ra_retransmit);
4692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("\n\thop limit %u, Flags [%s]" \
4702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ", pref %s, router lifetime %us, reachable time %us, retrans time %us",
4712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (u_int)p->nd_ra_curhoplimit,
4722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
4732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               get_rtpref(p->nd_ra_flags_reserved),
4742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&p->nd_ra_router_lifetime),
4752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&p->nd_ra_reachable),
4762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&p->nd_ra_retransmit));
4772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + RTADVLEN,
4792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - RTADVLEN);
4802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_NEIGHBOR_SOLICIT:
4832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    {
4842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		struct nd_neighbor_solicit *p;
4852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p = (struct nd_neighbor_solicit *)dp;
4862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(p->nd_ns_target);
4872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", who has %s", ip6addr_string(&p->nd_ns_target));
4882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NDSOLLEN 24
4902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + NDSOLLEN,
4912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - NDSOLLEN);
4922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
4942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_NEIGHBOR_ADVERT:
4962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    {
4972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		struct nd_neighbor_advert *p;
4982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p = (struct nd_neighbor_advert *)dp;
5002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(p->nd_na_target);
5012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", tgt is %s",
5022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ip6addr_string(&p->nd_na_target));
5032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
5042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf(", Flags [%s]",
5052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_nd_na_flag_values,
5062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                          "none",
5072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                          EXTRACT_32BITS(&p->nd_na_flags_reserved)));
5082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NDADVLEN 24
5092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + NDADVLEN,
5102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - NDADVLEN);
5112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef NDADVLEN
5122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
5142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_REDIRECT:
5162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RDR(i) ((struct nd_redirect *)(i))
5172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(RDR(dp)->nd_rd_dst);
5182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst));
5192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(RDR(dp)->nd_rd_target);
5202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" to %s",
5212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    getname6((const u_char*)&RDR(dp)->nd_rd_target));
5222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define REDIRECTLEN 40
5232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
5242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
5252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - REDIRECTLEN);
5262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef REDIRECTLEN
5292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef RDR
5302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING:
5312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		icmp6_rrenum_print(bp, ep);
5322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_QUERY:
5342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_REPLY:
5352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		icmp6_nodeinfo_print(length, bp, ep);
5362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case IND_SOLICIT:
5382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case IND_ADVERT:
5392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_V2_MEMBERSHIP_REPORT:
5412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mldv2_report_print((const u_char *) dp, length);
5422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */
5442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_HADISCOV_REQUEST:
5452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                TCHECK(dp->icmp6_data16[0]);
5462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
5472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
5482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_HADISCOV_REPLY:
5492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
5502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct in6_addr *in6;
5512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_char *cp;
5522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(dp->icmp6_data16[0]);
5542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
5552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (u_char *)dp + length;
5562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			in6 = (struct in6_addr *)(dp + 1);
5572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			for (; (u_char *)in6 < cp; in6++) {
5582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK(*in6);
5592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s", ip6addr_string(in6));
5602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
5612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MOBILEPREFIX_ADVERT:
5642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
5652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(dp->icmp6_data16[0]);
5662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
5672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0xc0)
5682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" ");
5692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0x80)
5702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("M");
5712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0x40)
5722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("O");
5732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MPADVLEN 8
5742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + MPADVLEN,
5752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - MPADVLEN);
5762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
57853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case ND_RPL_MESSAGE:
57953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rpl_print(ndo, dp, &dp->icmp6_data8[0], length);
58053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
5812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
5822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", length %u", length);
5832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (vflag <= 1)
5842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    print_unknown_data(bp,"\n\t", length);
5852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                return;
5862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
5872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (!vflag)
5882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", length %u", length);
5892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
5902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
5912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
5922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct udphdr *
5952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_upperlayer(u_char *bp, u_int *prot)
5962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
5972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
5982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;
5992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct udphdr *uh;
6002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_hbh *hbh;
6012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_frag *fragh;
6022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ah *ah;
6032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int nh;
6042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int hlen;
6052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
6072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
6082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!TTEST(ip6->ip6_nxt))
6102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return NULL;
6112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	nh = ip6->ip6_nxt;
6132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	hlen = sizeof(struct ip6_hdr);
6142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (bp < ep) {
6162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += hlen;
6172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch(nh) {
6192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_UDP:
6202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_TCP:
6212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			uh = (struct udphdr *)bp;
6222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (TTEST(uh->uh_dport)) {
6232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				*prot = nh;
6242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(uh);
6252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
6262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
6272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
6282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* NOTREACHED */
6292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_HOPOPTS:
6312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_DSTOPTS:
6322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_ROUTING:
6332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hbh = (struct ip6_hbh *)bp;
6342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(hbh->ip6h_len))
6352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
6362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = hbh->ip6h_nxt;
6372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = (hbh->ip6h_len + 1) << 3;
6382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */
6412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			fragh = (struct ip6_frag *)bp;
6422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(fragh->ip6f_offlg))
6432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
6442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* fragments with non-zero offset are meaningless */
6452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0)
6462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
6472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = fragh->ip6f_nxt;
6482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = sizeof(struct ip6_frag);
6492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_AH:
6522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ah = (struct ah *)bp;
6532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(ah->ah_len))
6542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
6552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = ah->ah_nxt;
6562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = (ah->ah_len + 2) << 2;
6572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:	/* unknown or undecodable header */
6602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			*prot = nh; /* meaningless, but set here anyway */
6612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return(NULL);
6622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
6632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
6642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return(NULL);		/* should be notreached, though */
6662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
6672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
6692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_opt_print(const u_char *bp, int resid)
6702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
6712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_hdr *op;
6722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_prefix_info *opp;
6732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_mtu *opm;
67453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct nd_opt_rdnss *oprd;
67553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const struct nd_opt_dnssl *opds;
6762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_advinterval *opa;
6772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_homeagent_info *oph;
6782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_route_info *opri;
67953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	const u_char *cp, *ep, *domp;
6802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in6_addr in6, *in6p;
6812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	size_t l;
68253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_int i;
6832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return
6852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	cp = bp;
6872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
6882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
6892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (cp < ep) {
6912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		op = (struct nd_opt_hdr *)cp;
6922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ECHECK(op->nd_opt_len);
6942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (resid <= 0)
6952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return;
6962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (op->nd_opt_len == 0)
6972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
6982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (cp + (op->nd_opt_len << 3) > ep)
6992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
7002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf("\n\t  %s option (%u), length %u (%u): ",
7022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2str(icmp6_opt_values, "unknown", op->nd_opt_type),
7032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_type,
7042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_len << 3,
7052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_len);
7062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (op->nd_opt_type) {
7082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_SOURCE_LINKADDR:
7092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			l = (op->nd_opt_len << 3) - 2;
7102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			print_lladdr(cp + 2, l);
7112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_TARGET_LINKADDR:
7132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			l = (op->nd_opt_len << 3) - 2;
7142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			print_lladdr(cp + 2, l);
7152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_PREFIX_INFORMATION:
7172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opp = (struct nd_opt_prefix_info *)op;
7182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opp->nd_opt_pi_prefix);
71953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        printf("%s/%u%s, Flags [%s], valid time %s",
7202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ip6addr_string(&opp->nd_opt_pi_prefix),
7212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               opp->nd_opt_pi_prefix_len,
7222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (op->nd_opt_len != 4) ? "badlen" : "",
7232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved),
7242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)));
72553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        printf(", pref. time %s", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)));
7262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_REDIRECTED_HEADER:
7282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        print_unknown_data(bp,"\n\t    ",op->nd_opt_len<<3);
7292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* xxx */
7302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_MTU:
7322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opm = (struct nd_opt_mtu *)op;
7332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opm->nd_opt_mtu_mtu);
7342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %u%s",
7352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&opm->nd_opt_mtu_mtu),
7362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (op->nd_opt_len != 1) ? "bad option length" : "" );
7372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
73853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case ND_OPT_RDNSS:
73953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			oprd = (struct nd_opt_rdnss *)op;
74053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			l = (op->nd_opt_len - 1) / 2;
74153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf(" lifetime %us,",
74253f17a9db278d33517d9888dd77848f554522a38JP Abgrall				EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime));
74353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			for (i = 0; i < l; i++) {
74453f17a9db278d33517d9888dd77848f554522a38JP Abgrall				TCHECK(oprd->nd_opt_rdnss_addr[i]);
74553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				printf(" addr: %s",
74653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				    ip6addr_string(&oprd->nd_opt_rdnss_addr[i]));
74753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
74853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
74953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		case ND_OPT_DNSSL:
75053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			opds = (struct nd_opt_dnssl *)op;
75153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf(" lifetime %us, domain(s):",
75253f17a9db278d33517d9888dd77848f554522a38JP Abgrall				EXTRACT_32BITS(&opds->nd_opt_dnssl_lifetime));
75353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */
75453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			while (domp < cp + (op->nd_opt_len << 3) && *domp != '\0')
75553f17a9db278d33517d9888dd77848f554522a38JP Abgrall			{
75653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				printf (" ");
75753f17a9db278d33517d9888dd77848f554522a38JP Abgrall				if ((domp = ns_nprint (domp, bp)) == NULL)
75853f17a9db278d33517d9888dd77848f554522a38JP Abgrall					goto trunc;
75953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
76053f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
7612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_ADVINTERVAL:
7622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opa = (struct nd_opt_advinterval *)op;
7632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opa->nd_opt_adv_interval);
76453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf(" %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
7652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_HOMEAGENT_INFO:
7672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			oph = (struct nd_opt_homeagent_info *)op;
7682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(oph->nd_opt_hai_lifetime);
7692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" preference %u, lifetime %u",
7702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&oph->nd_opt_hai_preference),
7712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&oph->nd_opt_hai_lifetime));
7722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_ROUTE_INFO:
7742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opri = (struct nd_opt_route_info *)op;
7752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opri->nd_opt_rti_lifetime);
7762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			memset(&in6, 0, sizeof(in6));
7772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			in6p = (struct in6_addr *)(opri + 1);
7782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			switch (op->nd_opt_len) {
7792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 1:
7802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
7812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 2:
7822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK2(*in6p, 8);
7832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				memcpy(&in6, opri + 1, 8);
7842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
7852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 3:
7862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK(*in6p);
7872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				memcpy(&in6, opri + 1, sizeof(in6));
7882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
7892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default:
7902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
7912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
7922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %s/%u", ip6addr_string(&in6),
7932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    opri->nd_opt_rti_prefixlen);
7942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags));
7952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", lifetime=%s",
7962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)));
7972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
7992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (vflag <= 1) {
8002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            print_unknown_data(cp+2,"\n\t  ", (op->nd_opt_len << 3) - 2); /* skip option header */
8012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            return;
8022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        }
8032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
8042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
8052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* do we want to see an additional hexdump ? */
8062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (vflag> 1)
8072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    print_unknown_data(cp+2,"\n\t    ", (op->nd_opt_len << 3) - 2); /* skip option header */
8082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		cp += op->nd_opt_len << 3;
8102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		resid -= op->nd_opt_len << 3;
8112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
8122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
8132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
8152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[ndp opt]", stdout);
8162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
8172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef ECHECK
8182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
8192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
8212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmld6_print(const u_char *bp)
8222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct mld6_hdr *mp = (struct mld6_hdr *)bp;
8242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
8252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
8272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
8282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((u_char *)mp + sizeof(*mp) > ep)
8302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
8312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay));
8332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("addr: %s", ip6addr_string(&mp->mld6_addr));
8342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
8352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
8372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmldv2_report_print(const u_char *bp, u_int len)
8382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
8402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int group, nsrcs, ngroups;
8412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int i, j;
8422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* Minimum len is 8 */
8442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (len < 8) {
8452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" [invalid len %d]", len);
8462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
8472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK(icp->icmp6_data16[1]);
85053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]);
8512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf(", %d group record(s)", ngroups);
8522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag > 0) {
8532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Print the group records */
8542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	group = 8;
8552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        for (i = 0; i < ngroups; i++) {
8562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* type(1) + auxlen(1) + numsrc(2) + grp(16) */
8572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (len < group + 20) {
8582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" [invalid number of groups]");
8592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
8602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
8612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            TCHECK2(bp[group + 4], sizeof(struct in6_addr));
8622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(" [gaddr %s", ip6addr_string(&bp[group + 4]));
8632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]",
8642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project								bp[group]));
8652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            nsrcs = (bp[group + 2] << 8) + bp[group + 3];
8662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* Check the number of sources and print them */
8672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) {
8682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" [invalid number of sources %d]", nsrcs);
8692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
8702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
8712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            if (vflag == 1)
8722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", %d source(s)", nsrcs);
8732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            else {
8742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print the sources */
8752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (void)printf(" {");
8762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                for (j = 0; j < nsrcs; j++) {
8772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)],
8782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            sizeof(struct in6_addr));
8792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)]));
8802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
8812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (void)printf(" }");
8822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            }
8832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* Next group record */
8842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            group += 20 + nsrcs * sizeof(struct in6_addr);
8852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("]");
8862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
8872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
8892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
8902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("[|icmp6]");
8912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
8922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
8932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
8952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmldv2_query_print(const u_char *bp, u_int len)
8962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
8982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int mrc;
8992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int mrt, qqi;
9002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int nsrcs;
9012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    register u_int i;
9022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* Minimum len is 28 */
9042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (len < 28) {
9052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" [invalid len %d]", len);
9062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
9072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK(icp->icmp6_data16[0]);
90953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]);
9102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (mrc < 32768) {
9112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	mrt = mrc;
9122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    } else {
9132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
9142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag) {
9162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(void)printf(" [max resp delay=%d]", mrt);
9172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK2(bp[8], sizeof(struct in6_addr));
9192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf(" [gaddr %s", ip6addr_string(&bp[8]));
9202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag) {
9222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        TCHECK(bp[25]);
9232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[24] & 0x08) {
9242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" sflag");
9252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[24] & 0x07) {
9272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" robustness=%d", bp[24] & 0x07);
9282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[25] < 128) {
9302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		qqi = bp[25];
9312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else {
9322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3);
9332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" qqi=%d", qqi);
9352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK2(bp[26], 2);
93853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    nsrcs = EXTRACT_16BITS(&bp[26]);
9392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (nsrcs > 0) {
9402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 28 + nsrcs * sizeof(struct in6_addr))
9412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" [invalid number of sources]");
9422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else if (vflag > 1) {
9432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" {");
9442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    for (i = 0; i < nsrcs; i++) {
9452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(bp[28 + i * sizeof(struct in6_addr)],
9462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        sizeof(struct in6_addr));
9472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)]));
9482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
9492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" }");
9502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else
9512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(", %d source(s)", nsrcs);
9522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
9532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf("]");
9542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
9552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
9562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("[|icmp6]");
9572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
9582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
9592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
96053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void
9612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectdnsname_print(const u_char *cp, const u_char *ep)
9622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
9632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int i;
9642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* DNS name decoding - no decompression */
9662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(", \"");
9672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (cp < ep) {
9682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		i = *cp++;
9692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (i) {
9702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i > ep - cp) {
9712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("???");
9722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
9732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
9742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (i-- && cp < ep) {
9752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				safeputchar(*cp);
9762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
9772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
9782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp + 1 < ep && *cp)
9792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(".");
9802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
9812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp == ep) {
9822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* FQDN */
9832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(".");
9842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else if (cp + 1 == ep && *cp == '\0') {
9852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* truncated */
9862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else {
9872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* invalid */
9882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("???");
9892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
9902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
9922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("\"");
9942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
9952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
9972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep)
9982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
9992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_nodeinfo *ni6;
10002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_hdr *dp;
10012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *cp;
10022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	size_t siz, i;
10032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int needcomma;
10042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (ep < bp)
10062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
10072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dp = (struct icmp6_hdr *)bp;
10082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ni6 = (struct icmp6_nodeinfo *)bp;
10092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	siz = ep - bp;
10102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (ni6->ni_type) {
10122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_QUERY:
10132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (siz == sizeof(*dp) + 4) {
10142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* KAME who-are-you */
10152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" who-are-you request");
10162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" node information query");
10192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(*dp, sizeof(*ni6));
10212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ni6 = (struct icmp6_nodeinfo *)dp;
10222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" (");	/*)*/
10232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
10242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NOOP:
10252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("noop");
10262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_SUPTYPES:
10282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("supported qtypes");
10292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = EXTRACT_16BITS(&ni6->ni_flags);
10302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i)
10312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [%s]", (i & 0x01) ? "C" : "");
10322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_FQDN:
10352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("DNS name");
10362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NODEADDR:
10382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("node addresses");
10392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = ni6->ni_flags;
10402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!i)
10412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
10422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* NI_NODEADDR_FLAG_TRUNCATE undefined for query */
10432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" [%s%s%s%s%s%s]",
10442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
10452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
10462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
10472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
10482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
10492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "");
10502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
10522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
10532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (ni6->ni_qtype == NI_QTYPE_NOOP ||
10572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    ni6->ni_qtype == NI_QTYPE_SUPTYPES) {
10582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
10592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid len");
10612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
10622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
10632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* XXX backward compat, icmp-name-lookup-03 */
10682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (siz == sizeof(*ni6)) {
10692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", 03 draft");
10702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
10712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
10722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (ni6->ni_code) {
10762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_IPV6:
10772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST2(*dp,
10782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(*ni6) + sizeof(struct in6_addr)))
10792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
10802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) {
10812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid subject len");
10832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
10842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
10852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=%s",
10862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    getname6((const u_char *)(ni6 + 1)));
10872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_FQDN:
10892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=DNS name");
10902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const u_char *)(ni6 + 1);
10912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp[0] == ep - cp - 1) {
10922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* icmp-name-lookup-03, pascal string */
10932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", 03 draft");
10952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
10962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", \"");
10972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				while (cp < ep) {
10982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					safeputchar(*cp);
10992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					cp++;
11002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				}
11012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\"");
11022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else
11032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				dnsname_print(cp, ep);
11042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_IPV4:
11062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr)))
11072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
11082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6) + sizeof(struct in_addr)) {
11092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
11102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid subject len");
11112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
11122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
11132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=%s",
11142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    getname((const u_char *)(ni6 + 1)));
11152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
11172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", unknown subject");
11182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
11222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
11232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_REPLY:
11262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (icmp6len > siz) {
11272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("[|icmp6: node information reply]");
11282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		needcomma = 0;
11322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ni6 = (struct icmp6_nodeinfo *)dp;
11342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" node information reply");
11352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" (");	/*)*/
11362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (ni6->ni_code) {
11372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUCCESS:
11382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag) {
11392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("success");
11402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				needcomma++;
11412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
11422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_REFUSED:
11442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("refused");
11452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			needcomma++;
11462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
11472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
11482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
11492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_UNKNOWN:
11512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
11522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			needcomma++;
11532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
11542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
11552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
11562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (ni6->ni_code != ICMP6_NI_SUCCESS) {
11602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
11612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
11622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
11662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NOOP:
11672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
11682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
11692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("noop");
11702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
11712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
11722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
11732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_SUPTYPES:
11752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
11762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
11772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("supported qtypes");
11782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = EXTRACT_16BITS(&ni6->ni_flags);
11792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i)
11802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [%s]", (i & 0x01) ? "C" : "");
11812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_FQDN:
11832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
11842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
11852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("DNS name");
11862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const u_char *)(ni6 + 1) + 4;
11872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp[0] == ep - cp - 1) {
11882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* icmp-name-lookup-03, pascal string */
11892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
11902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", 03 draft");
11912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
11922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", \"");
11932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				while (cp < ep) {
11942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					safeputchar(*cp);
11952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					cp++;
11962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				}
11972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\"");
11982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else
11992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				dnsname_print(cp, ep);
12002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0)
12012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1));
12022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
12032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NODEADDR:
12042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
12052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
12062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("node addresses");
12072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = sizeof(*ni6);
12082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (i < siz) {
12092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz)
12102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					break;
12112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" %s", getname6(bp + i));
12122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				i += sizeof(struct in6_addr);
12132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i));
12142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				i += sizeof(int32_t);
12152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
12162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = ni6->ni_flags;
12172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!i)
12182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
12192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" [%s%s%s%s%s%s%s]",
12202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
12212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
12222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
12232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
12242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
12252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "",
12262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "");
12272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
12282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
12292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
12302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
12312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
12322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
12332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
12342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
12362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
12372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
12382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
12402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
12422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
12432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
12442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
12462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_rrenum_print(const u_char *bp, const u_char *ep)
12472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
12482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_router_renum *rr6;
12492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const char *cp;
12502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct rr_pco_match *match;
12512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct rr_pco_use *use;
12522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char hbuf[NI_MAXHOST];
12532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int n;
12542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (ep < bp)
12562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
12572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	rr6 = (struct icmp6_router_renum *)bp;
12582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	cp = (const char *)(rr6 + 1);
12592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK(rr6->rr_reserved);
12612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (rr6->rr_code) {
12622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_COMMAND:
12632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: command");
12642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
12652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_RESULT:
12662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: result");
12672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
12682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
12692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: sequence number reset");
12702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
12712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
12722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: code-#%d", rr6->rr_code);
12732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
12742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum));
12772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag) {
12792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define F(x, y)	((rr6->rr_flags) & (x) ? (y) : "")
12802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[");	/*]*/
12812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (rr6->rr_flags) {
12822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"),
12832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_REQRESULT, "R"),
12842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"),
12852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_SPECSITE, "S"),
12862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_PREVDONE, "P"));
12872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
12882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("seg=%u,", rr6->rr_segnum);
128953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		printf("maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay));
12902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (rr6->rr_reserved)
129153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf("rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved));
12922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*[*/
12932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("]");
12942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef F
12952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) {
12982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		match = (struct rr_pco_match *)cp;
12992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		cp = (const char *)(match + 1);
13002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(match->rpm_prefix);
13022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag > 1)
13042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("\n\t");
13052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else
13062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" ");
13072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("match(");	/*)*/
13082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (match->rpm_code) {
13092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_ADD:	printf("add"); break;
13102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_CHANGE:	printf("change"); break;
13112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_SETGLOBAL:	printf("setglobal"); break;
13122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:		printf("#%u", match->rpm_code); break;
13132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
13162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",ord=%u", match->rpm_ordinal);
13172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",min=%u", match->rpm_minlen);
13182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",max=%u", match->rpm_maxlen);
13192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf)))
13212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",%s/%u", hbuf, match->rpm_matchlen);
13222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else
13232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",?/%u", match->rpm_matchlen);
13242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
13252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
13262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n = match->rpm_len - 3;
13282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (n % 4)
13292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
13302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n /= 4;
13312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (n-- > 0) {
13322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			use = (struct rr_pco_use *)cp;
13332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const char *)(use + 1);
13342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(use->rpu_prefix);
13362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag > 1)
13382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\n\t");
13392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
13402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" ");
13412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("use(");	/*)*/
13422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (use->rpu_flags) {
13432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define F(x, y)	((use->rpu_flags) & (x) ? (y) : "")
13442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("%s%s,",
13452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"),
13462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P"));
13472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef F
13482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
13492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag) {
13502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("mask=0x%x,", use->rpu_ramask);
13512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("raflags=0x%x,", use->rpu_raflags);
13522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (~use->rpu_vltime == 0)
13532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("vltime=infty,");
13542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				else
13552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("vltime=%u,",
13562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					    EXTRACT_32BITS(&use->rpu_vltime));
13572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (~use->rpu_pltime == 0)
13582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("pltime=infty,");
13592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				else
13602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("pltime=%u,",
13612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					    EXTRACT_32BITS(&use->rpu_pltime));
13622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
13632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf,
13642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(hbuf)))
13652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("%s/%u/%u", hbuf, use->rpu_uselen,
13662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    use->rpu_keeplen);
13672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
13682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("?/%u/%u", use->rpu_uselen,
13692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    use->rpu_keeplen);
13702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
13712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
13722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
13732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
13742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
13762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
13782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
13792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
13802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* INET6 */
1382