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_ =
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.79.2.6 2005/09/05 09:29:28 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
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_type_values[] = {
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH, "destination unreachable"},
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_PACKET_TOO_BIG, "packet too big"},
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"},
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_PARAM_PROB, "parameter problem"},
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ECHO_REQUEST, "echo request"},
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ECHO_REPLY, "echo reply"},
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_QUERY, "multicast listener query"},
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_REPORT, "multicast listener report"},
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_LISTENER_DONE, "multicast listener done"},
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_ROUTER_SOLICIT, "router solicitation"},
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_ROUTER_ADVERT, "router advertisement"},
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"},
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NEIGHBOR_ADVERT, "neighbor advertisement"},
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_REDIRECT, "redirect"},
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_ROUTER_RENUMBERING, "router renumbering"},
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { IND_SOLICIT, "inverse neighbor solicitation"},
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { IND_ADVERT, "inverse neighbor advertisement"},
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLDV2_LISTENER_REPORT, "multicast listener report v2"},
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_HADISCOV_REQUEST, "ha discovery request"},
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_HADISCOV_REPLY, "ha discovery reply"},
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"},
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"},
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_WRUREQUEST, "who-are-you request"},
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_WRUREPLY, "who-are-you reply"},
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_NI_QUERY, "node information query"},
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_NI_REPLY, "node information reply"},
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_MTRACE, "mtrace message"},
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MLD6_MTRACE_RESP, "mtrace response"},
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_dst_unreach_code_values[] = {
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" },
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"},
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"},
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_ADDR, "unreachable address"},
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ICMP6_DST_UNREACH_NOPORT, "unreachable port"},
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_opt_pi_flag_values[] = {
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_ONLINK, "onlink" },
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_AUTO, "auto" },
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_OPT_PI_FLAG_ROUTER, "router" },
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_opt_ra_flag_values[] = {
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_MANAGED, "managed" },
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_OTHER, "other stateful"},
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_RA_FLAG_HOME_AGENT, "home agent"},
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_nd_na_flag_values[] = {
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_ROUTER, "router" },
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_SOLICITED, "solicited" },
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { ND_NA_FLAG_OVERRIDE, "override" },
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0,	NULL }
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok icmp6_opt_values[] = {
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_SOURCE_LINKADDR, "source link-address"},
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_TARGET_LINKADDR, "destination link-address"},
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_PREFIX_INFORMATION, "prefix info"},
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_REDIRECTED_HEADER, "redirected header"},
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_MTU, "mtu"},
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_ADVINTERVAL, "advertisement interval"},
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_HOMEAGENT_INFO, "homeagent information"},
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { ND_OPT_ROUTE_INFO, "route info"},
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project   { 0,	NULL }
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* mldv2 report types */
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok mldv2report2str[] = {
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 1,	"is_in" },
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 2,	"is_ex" },
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 3,	"to_in" },
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 4,	"to_ex" },
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 5,	"allow" },
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 6,	"block" },
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 0,	NULL }
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_rtpref(u_int v)
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static const char *rtpref_str[] = {
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"medium",		/* 00 */
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"high",			/* 01 */
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"rsv",			/* 10 */
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		"low"			/* 11 */
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	};
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff];
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_lifetime(u_int32_t v)
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static char buf[20];
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (v == (u_int32_t)~0UL)
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return "infinity";
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else {
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		snprintf(buf, sizeof(buf), "%u", v);
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return buf;
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectprint_lladdr(const u_int8_t *p, size_t l)
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_int8_t *ep, *q;
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	q = p;
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = p + l;
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (l > 0 && q < ep) {
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (q > p)
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(":");
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("%02x", *q++);
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		l--;
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp,
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int len)
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	size_t i;
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register const u_int16_t *sp;
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int32_t sum;
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	union {
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		struct {
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct in6_addr ph_src;
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct in6_addr ph_dst;
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int32_t	ph_len;
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int8_t	ph_zero[3];
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int8_t	ph_nxt;
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} ph;
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		u_int16_t pa[20];
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} phu;
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* pseudo-header */
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&phu, 0, sizeof(phu));
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	phu.ph.ph_src = ip6->ip6_src;
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	phu.ph.ph_dst = ip6->ip6_dst;
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	phu.ph.ph_len = htonl(len);
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	phu.ph.ph_nxt = IPPROTO_ICMPV6;
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	sum = 0;
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		sum += phu.pa[i];
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	sp = (const u_int16_t *)icp;
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	for (i = 0; i < (len & ~1); i += 2)
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		sum += *sp++;
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len & 1)
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		sum += htons((*(const u_int8_t *)sp) << 8);
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (sum > 0xffff)
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		sum = (sum & 0xffff) + (sum >> 16);
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	sum = ~sum & 0xffff;
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (sum);
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_print(const u_char *bp, u_int length, const u_char *bp2, int fragmented)
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct icmp6_hdr *dp;
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct ip6_hdr *ip;
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct ip6_hdr *oip;
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct udphdr *ouh;
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int dport;
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int prot;
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dp = (struct icmp6_hdr *)bp;
2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ip = (struct ip6_hdr *)bp2;
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	oip = (struct ip6_hdr *)(dp + 1);
2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK(dp->icmp6_cksum);
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag && !fragmented) {
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		int sum = dp->icmp6_cksum;
2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (TTEST2(bp[0], length)) {
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			sum = icmp6_cksum(ip, dp, length);
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (sum != 0)
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				(void)printf("[bad icmp6 cksum %x!] ", sum);
2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				(void)printf("[icmp6 sum ok] ");
2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type));
2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        /* display cosmetics: print the packet length for printer that use the vflag now */
2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag && (dp->icmp6_type ==
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ND_ROUTER_SOLICIT ||
2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ND_ROUTER_ADVERT ||
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ND_NEIGHBOR_ADVERT ||
2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ND_NEIGHBOR_SOLICIT ||
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ND_REDIRECT ||
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ICMP6_HADISCOV_REPLY ||
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      ICMP6_MOBILEPREFIX_ADVERT ))
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", length %u", length);
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (dp->icmp6_type) {
2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_DST_UNREACH:
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
2822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code));
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
2862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_ADMIN:
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_ADDR:
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf(" %s",ip6addr_string(&oip->ip6_dst));
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
2902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_BEYONDSCOPE:
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %s, source address %s",
2922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       ip6addr_string(&oip->ip6_dst),
2932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       ip6addr_string(&oip->ip6_src));
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_DST_UNREACH_NOPORT:
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((ouh = get_upperlayer((u_char *)oip, &prot))
2972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    == NULL)
2982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
2992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			dport = EXTRACT_16BITS(&ouh->uh_dport);
3012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			switch (prot) {
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case IPPROTO_TCP:
3032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s tcp port %s",
3042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					tcpport_string(dport));
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case IPPROTO_UDP:
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s udp port %s",
3092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					udpport_string(dport));
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default:
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s protocol %d port %d unreachable",
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					ip6addr_string(&oip->ip6_dst),
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					oip->ip6_nxt, dport);
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (vflag <= 1) {
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            print_unknown_data(bp,"\n\t",length);
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            return;
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_PACKET_TOO_BIG:
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(dp->icmp6_mtu);
3292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu));
3302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_TIME_EXCEEDED:
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_TIME_EXCEED_TRANSIT:
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" for %s",
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				ip6addr_string(&oip->ip6_dst));
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_TIME_EXCEED_REASSEMBLY:
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" (reassembly)");
3402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", unknown code (%u)", dp->icmp6_code);
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_PARAM_PROB:
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(oip->ip6_dst);
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (dp->icmp6_code) {
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_HEADER:
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", errorneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_NEXTHEADER:
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_PARAMPROB_OPTION:
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
3572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", code-#%d",
3602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			       dp->icmp6_code);
3612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ECHO_REQUEST:
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ECHO_REPLY:
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(dp->icmp6_seq);
3672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq));
3682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_QUERY:
3702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (length == MLD_MINLEN) {
3712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			mld6_print((const u_char *)dp);
3722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else if (length >= MLDV2_MINLEN) {
3732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("v2 ");
3742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			mldv2_query_print((const u_char *)dp, length);
3752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" unknown-version (len %u) ", length);
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_REPORT:
3802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mld6_print((const u_char *)dp);
3812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MEMBERSHIP_REDUCTION:
3832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mld6_print((const u_char *)dp);
3842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_ROUTER_SOLICIT:
3862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RTSOLLEN 8
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
3882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + RTSOLLEN,
3892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - RTSOLLEN);
3902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_ROUTER_ADVERT:
3932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RTADVLEN 16
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
3952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct nd_router_advert *p;
3962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p = (struct nd_router_advert *)dp;
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(p->nd_ra_retransmit);
3992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("\n\thop limit %u, Flags [%s]" \
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ", pref %s, router lifetime %us, reachable time %us, retrans time %us",
4012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (u_int)p->nd_ra_curhoplimit,
4022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
4032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               get_rtpref(p->nd_ra_flags_reserved),
4042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&p->nd_ra_router_lifetime),
4052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&p->nd_ra_reachable),
4062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&p->nd_ra_retransmit));
4072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + RTADVLEN,
4092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - RTADVLEN);
4102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_NEIGHBOR_SOLICIT:
4132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    {
4142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		struct nd_neighbor_solicit *p;
4152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p = (struct nd_neighbor_solicit *)dp;
4162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(p->nd_ns_target);
4172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", who has %s", ip6addr_string(&p->nd_ns_target));
4182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NDSOLLEN 24
4202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + NDSOLLEN,
4212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - NDSOLLEN);
4222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
4242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_NEIGHBOR_ADVERT:
4262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    {
4272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		struct nd_neighbor_advert *p;
4282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p = (struct nd_neighbor_advert *)dp;
4302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(p->nd_na_target);
4312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", tgt is %s",
4322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ip6addr_string(&p->nd_na_target));
4332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf(", Flags [%s]",
4352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_nd_na_flag_values,
4362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                          "none",
4372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                          EXTRACT_32BITS(&p->nd_na_flags_reserved)));
4382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NDADVLEN 24
4392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + NDADVLEN,
4402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - NDADVLEN);
4412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef NDADVLEN
4422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
4442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ND_REDIRECT:
4462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define RDR(i) ((struct nd_redirect *)(i))
4472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(RDR(dp)->nd_rd_dst);
4482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst));
4492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(RDR(dp)->nd_rd_target);
4502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" to %s",
4512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    getname6((const u_char*)&RDR(dp)->nd_rd_target));
4522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define REDIRECTLEN 40
4532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
4552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - REDIRECTLEN);
4562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef REDIRECTLEN
4592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef RDR
4602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING:
4612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		icmp6_rrenum_print(bp, ep);
4622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_QUERY:
4642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_REPLY:
4652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		icmp6_nodeinfo_print(length, bp, ep);
4662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case IND_SOLICIT:
4682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case IND_ADVERT:
4692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_V2_MEMBERSHIP_REPORT:
4712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mldv2_report_print((const u_char *) dp, length);
4722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */
4742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_HADISCOV_REQUEST:
4752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                TCHECK(dp->icmp6_data16[0]);
4762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
4772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
4782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_HADISCOV_REPLY:
4792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			struct in6_addr *in6;
4812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_char *cp;
4822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(dp->icmp6_data16[0]);
4842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
4852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (u_char *)dp + length;
4862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			in6 = (struct in6_addr *)(dp + 1);
4872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			for (; (u_char *)in6 < cp; in6++) {
4882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK(*in6);
4892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", %s", ip6addr_string(in6));
4902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
4912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
4932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_MOBILEPREFIX_ADVERT:
4942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
4952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(dp->icmp6_data16[0]);
4962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
4972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0xc0)
4982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" ");
4992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0x80)
5002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("M");
5012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (dp->icmp6_data16[1] & 0x40)
5022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("O");
5032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MPADVLEN 8
5042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			icmp6_opt_print((const u_char *)dp + MPADVLEN,
5052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					length - MPADVLEN);
5062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
5082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
5092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", length %u", length);
5102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (vflag <= 1)
5112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    print_unknown_data(bp,"\n\t", length);
5122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                return;
5132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
5142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (!vflag)
5152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", length %u", length);
5162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
5172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
5182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
5192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct udphdr *
5222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectget_upperlayer(u_char *bp, u_int *prot)
5232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
5242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
5252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;
5262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct udphdr *uh;
5272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_hbh *hbh;
5282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ip6_frag *fragh;
5292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ah *ah;
5302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int nh;
5312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int hlen;
5322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
5342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
5352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!TTEST(ip6->ip6_nxt))
5372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return NULL;
5382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	nh = ip6->ip6_nxt;
5402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	hlen = sizeof(struct ip6_hdr);
5412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (bp < ep) {
5432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += hlen;
5442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch(nh) {
5462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_UDP:
5472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_TCP:
5482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			uh = (struct udphdr *)bp;
5492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (TTEST(uh->uh_dport)) {
5502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				*prot = nh;
5512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(uh);
5522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
5532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
5542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
5552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* NOTREACHED */
5562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_HOPOPTS:
5582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_DSTOPTS:
5592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_ROUTING:
5602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hbh = (struct ip6_hbh *)bp;
5612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(hbh->ip6h_len))
5622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
5632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = hbh->ip6h_nxt;
5642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = (hbh->ip6h_len + 1) << 3;
5652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
5662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */
5682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			fragh = (struct ip6_frag *)bp;
5692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(fragh->ip6f_offlg))
5702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
5712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* fragments with non-zero offset are meaningless */
5722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0)
5732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
5742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = fragh->ip6f_nxt;
5752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = sizeof(struct ip6_frag);
5762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
5772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case IPPROTO_AH:
5792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ah = (struct ah *)bp;
5802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST(ah->ah_len))
5812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return(NULL);
5822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			nh = ah->ah_nxt;
5832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			hlen = (ah->ah_len + 2) << 2;
5842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
5852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:	/* unknown or undecodable header */
5872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			*prot = nh; /* meaningless, but set here anyway */
5882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return(NULL);
5892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
5902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
5912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return(NULL);		/* should be notreached, though */
5932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
5962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_opt_print(const u_char *bp, int resid)
5972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
5982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_hdr *op;
5992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_hdr *opl;	/* why there's no struct? */
6002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_prefix_info *opp;
6012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct icmp6_opts_redirect *opr;
6022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_mtu *opm;
6032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_advinterval *opa;
6042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_homeagent_info *oph;
6052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct nd_opt_route_info *opri;
6062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *cp, *ep;
6072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in6_addr in6, *in6p;
6082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	size_t l;
6092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return
6112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	cp = bp;
6132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
6142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
6152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (cp < ep) {
6172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		op = (struct nd_opt_hdr *)cp;
6182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ECHECK(op->nd_opt_len);
6202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (resid <= 0)
6212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return;
6222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (op->nd_opt_len == 0)
6232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
6242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (cp + (op->nd_opt_len << 3) > ep)
6252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
6262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf("\n\t  %s option (%u), length %u (%u): ",
6282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2str(icmp6_opt_values, "unknown", op->nd_opt_type),
6292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_type,
6302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_len << 3,
6312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       op->nd_opt_len);
6322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (op->nd_opt_type) {
6342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_SOURCE_LINKADDR:
6352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opl = (struct nd_opt_hdr *)op;
6362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			l = (op->nd_opt_len << 3) - 2;
6372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			print_lladdr(cp + 2, l);
6382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_TARGET_LINKADDR:
6402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opl = (struct nd_opt_hdr *)op;
6412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			l = (op->nd_opt_len << 3) - 2;
6422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			print_lladdr(cp + 2, l);
6432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_PREFIX_INFORMATION:
6452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opp = (struct nd_opt_prefix_info *)op;
6462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opp->nd_opt_pi_prefix);
6472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf("%s/%u%s, Flags [%s], valid time %ss",
6482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ip6addr_string(&opp->nd_opt_pi_prefix),
6492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               opp->nd_opt_pi_prefix_len,
6502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (op->nd_opt_len != 4) ? "badlen" : "",
6512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved),
6522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)));
6532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf(", pref. time %ss", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)));
6542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_REDIRECTED_HEADER:
6562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opr = (struct icmp6_opts_redirect *)op;
6572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        print_unknown_data(bp,"\n\t    ",op->nd_opt_len<<3);
6582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* xxx */
6592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_MTU:
6612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opm = (struct nd_opt_mtu *)op;
6622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opm->nd_opt_mtu_mtu);
6632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %u%s",
6642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(&opm->nd_opt_mtu_mtu),
6652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               (op->nd_opt_len != 1) ? "bad option length" : "" );
6662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
6672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_ADVINTERVAL:
6682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opa = (struct nd_opt_advinterval *)op;
6692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opa->nd_opt_adv_interval);
6702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
6712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_HOMEAGENT_INFO:
6732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			oph = (struct nd_opt_homeagent_info *)op;
6742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(oph->nd_opt_hai_lifetime);
6752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" preference %u, lifetime %u",
6762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&oph->nd_opt_hai_preference),
6772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_16BITS(&oph->nd_opt_hai_lifetime));
6782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ND_OPT_ROUTE_INFO:
6802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			opri = (struct nd_opt_route_info *)op;
6812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(opri->nd_opt_rti_lifetime);
6822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			memset(&in6, 0, sizeof(in6));
6832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			in6p = (struct in6_addr *)(opri + 1);
6842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			switch (op->nd_opt_len) {
6852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 1:
6862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
6872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 2:
6882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK2(*in6p, 8);
6892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				memcpy(&in6, opri + 1, 8);
6902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
6912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			case 3:
6922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				TCHECK(*in6p);
6932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				memcpy(&in6, opri + 1, sizeof(in6));
6942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
6952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default:
6962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
6972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
6982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" %s/%u", ip6addr_string(&in6),
6992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    opri->nd_opt_rti_prefixlen);
7002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags));
7012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", lifetime=%s",
7022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)));
7032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
7042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
7052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (vflag <= 1) {
7062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            print_unknown_data(cp+2,"\n\t  ", (op->nd_opt_len << 3) - 2); /* skip option header */
7072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            return;
7082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        }
7092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
7102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
7112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* do we want to see an additional hexdump ? */
7122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (vflag> 1)
7132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    print_unknown_data(cp+2,"\n\t    ", (op->nd_opt_len << 3) - 2); /* skip option header */
7142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		cp += op->nd_opt_len << 3;
7162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		resid -= op->nd_opt_len << 3;
7172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
7182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
7192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
7212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[ndp opt]", stdout);
7222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
7232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef ECHECK
7242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
7272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmld6_print(const u_char *bp)
7282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
7292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct mld6_hdr *mp = (struct mld6_hdr *)bp;
7302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ep;
7312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* 'ep' points to the end of available data. */
7332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ep = snapend;
7342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((u_char *)mp + sizeof(*mp) > ep)
7362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
7372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay));
7392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("addr: %s", ip6addr_string(&mp->mld6_addr));
7402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
7432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmldv2_report_print(const u_char *bp, u_int len)
7442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
7452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
7462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int group, nsrcs, ngroups;
7472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int i, j;
7482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* Minimum len is 8 */
7502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (len < 8) {
7512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" [invalid len %d]", len);
7522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
7532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
7542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK(icp->icmp6_data16[1]);
7562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    ngroups = ntohs(icp->icmp6_data16[1]);
7572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf(", %d group record(s)", ngroups);
7582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag > 0) {
7592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Print the group records */
7602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	group = 8;
7612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        for (i = 0; i < ngroups; i++) {
7622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* type(1) + auxlen(1) + numsrc(2) + grp(16) */
7632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (len < group + 20) {
7642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" [invalid number of groups]");
7652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
7662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
7672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            TCHECK2(bp[group + 4], sizeof(struct in6_addr));
7682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(" [gaddr %s", ip6addr_string(&bp[group + 4]));
7692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]",
7702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project								bp[group]));
7712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            nsrcs = (bp[group + 2] << 8) + bp[group + 3];
7722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* Check the number of sources and print them */
7732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) {
7742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" [invalid number of sources %d]", nsrcs);
7752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
7762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
7772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            if (vflag == 1)
7782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", %d source(s)", nsrcs);
7792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            else {
7802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print the sources */
7812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (void)printf(" {");
7822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                for (j = 0; j < nsrcs; j++) {
7832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)],
7842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            sizeof(struct in6_addr));
7852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)]));
7862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
7872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (void)printf(" }");
7882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            }
7892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* Next group record */
7902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            group += 20 + nsrcs * sizeof(struct in6_addr);
7912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("]");
7922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
7932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
7942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
7952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
7962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("[|icmp6]");
7972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
7982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
7992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
8012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectmldv2_query_print(const u_char *bp, u_int len)
8022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
8042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int mrc;
8052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int mrt, qqi;
8062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int nsrcs;
8072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    register u_int i;
8082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* Minimum len is 28 */
8102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (len < 28) {
8112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" [invalid len %d]", len);
8122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
8132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK(icp->icmp6_data16[0]);
8152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    mrc = ntohs(icp->icmp6_data16[0]);
8162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (mrc < 32768) {
8172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	mrt = mrc;
8182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    } else {
8192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
8202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag) {
8222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(void)printf(" [max resp delay=%d]", mrt);
8232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK2(bp[8], sizeof(struct in6_addr));
8252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf(" [gaddr %s", ip6addr_string(&bp[8]));
8262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (vflag) {
8282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        TCHECK(bp[25]);
8292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[24] & 0x08) {
8302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" sflag");
8312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
8322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[24] & 0x07) {
8332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" robustness=%d", bp[24] & 0x07);
8342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
8352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (bp[25] < 128) {
8362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		qqi = bp[25];
8372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else {
8382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3);
8392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
8402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" qqi=%d", qqi);
8412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    TCHECK2(bp[26], 2);
8442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    nsrcs = ntohs(*(u_short *)&bp[26]);
8452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (nsrcs > 0) {
8462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 28 + nsrcs * sizeof(struct in6_addr))
8472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" [invalid number of sources]");
8482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else if (vflag > 1) {
8492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" {");
8502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    for (i = 0; i < nsrcs; i++) {
8512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(bp[28 + i * sizeof(struct in6_addr)],
8522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        sizeof(struct in6_addr));
8532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)]));
8542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
8552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(" }");
8562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else
8572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf(", %d source(s)", nsrcs);
8582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
8592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf("]");
8602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
8612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
8622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("[|icmp6]");
8632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
8642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
8652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
8672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectdnsname_print(const u_char *cp, const u_char *ep)
8682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int i;
8702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* DNS name decoding - no decompression */
8722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(", \"");
8732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (cp < ep) {
8742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		i = *cp++;
8752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (i) {
8762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i > ep - cp) {
8772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("???");
8782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
8792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
8802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (i-- && cp < ep) {
8812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				safeputchar(*cp);
8822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
8832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
8842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp + 1 < ep && *cp)
8852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(".");
8862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
8872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp == ep) {
8882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* FQDN */
8892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(".");
8902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else if (cp + 1 == ep && *cp == '\0') {
8912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* truncated */
8922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else {
8932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* invalid */
8942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("???");
8952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
8962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
8972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
8982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
8992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("\"");
9002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
9012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
9032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep)
9042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
9052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_nodeinfo *ni6;
9062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_hdr *dp;
9072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *cp;
9082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	size_t siz, i;
9092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int needcomma;
9102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (ep < bp)
9122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
9132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dp = (struct icmp6_hdr *)bp;
9142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ni6 = (struct icmp6_nodeinfo *)bp;
9152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	siz = ep - bp;
9162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (ni6->ni_type) {
9182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_QUERY:
9192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (siz == sizeof(*dp) + 4) {
9202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* KAME who-are-you */
9212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" who-are-you request");
9222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
9242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" node information query");
9252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(*dp, sizeof(*ni6));
9272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ni6 = (struct icmp6_nodeinfo *)dp;
9282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" (");	/*)*/
9292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
9302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NOOP:
9312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("noop");
9322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_SUPTYPES:
9342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("supported qtypes");
9352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = EXTRACT_16BITS(&ni6->ni_flags);
9362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i)
9372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [%s]", (i & 0x01) ? "C" : "");
9382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_FQDN:
9412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("DNS name");
9422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NODEADDR:
9442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("node addresses");
9452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = ni6->ni_flags;
9462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!i)
9472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
9482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* NI_NODEADDR_FLAG_TRUNCATE undefined for query */
9492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" [%s%s%s%s%s%s]",
9502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
9512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
9522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
9532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
9542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
9552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "");
9562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
9582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
9592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
9612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (ni6->ni_qtype == NI_QTYPE_NOOP ||
9632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    ni6->ni_qtype == NI_QTYPE_SUPTYPES) {
9642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
9652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
9662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid len");
9672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
9682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
9692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
9712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* XXX backward compat, icmp-name-lookup-03 */
9742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (siz == sizeof(*ni6)) {
9752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", 03 draft");
9762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
9772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
9782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
9802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (ni6->ni_code) {
9822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_IPV6:
9832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST2(*dp,
9842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(*ni6) + sizeof(struct in6_addr)))
9852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
9862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) {
9872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
9882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid subject len");
9892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
9902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
9912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=%s",
9922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    getname6((const u_char *)(ni6 + 1)));
9932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
9942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_FQDN:
9952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=DNS name");
9962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const u_char *)(ni6 + 1);
9972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp[0] == ep - cp - 1) {
9982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* icmp-name-lookup-03, pascal string */
9992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", 03 draft");
10012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
10022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", \"");
10032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				while (cp < ep) {
10042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					safeputchar(*cp);
10052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					cp++;
10062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				}
10072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\"");
10082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else
10092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				dnsname_print(cp, ep);
10102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUBJ_IPV4:
10122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr)))
10132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
10142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6) + sizeof(struct in_addr)) {
10152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid subject len");
10172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
10182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
10192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", subject=%s",
10202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    getname((const u_char *)(ni6 + 1)));
10212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
10232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", unknown subject");
10242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
10282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
10292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
10302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_NI_REPLY:
10322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (icmp6len > siz) {
10332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("[|icmp6: node information reply]");
10342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		needcomma = 0;
10382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ni6 = (struct icmp6_nodeinfo *)dp;
10402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" node information reply");
10412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" (");	/*)*/
10422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (ni6->ni_code) {
10432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_SUCCESS:
10442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag) {
10452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("success");
10462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				needcomma++;
10472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
10482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_REFUSED:
10502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("refused");
10512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			needcomma++;
10522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
10532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
10552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case ICMP6_NI_UNKNOWN:
10572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
10582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			needcomma++;
10592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
10602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
10622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (ni6->ni_code != ICMP6_NI_SUCCESS) {
10662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
10672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
10682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
10712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
10722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NOOP:
10732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
10742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
10752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("noop");
10762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (siz != sizeof(*ni6))
10772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", invalid length");
10792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_SUPTYPES:
10812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
10822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
10832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("supported qtypes");
10842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = EXTRACT_16BITS(&ni6->ni_flags);
10852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (i)
10862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [%s]", (i & 0x01) ? "C" : "");
10872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
10882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_FQDN:
10892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
10902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
10912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("DNS name");
10922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const u_char *)(ni6 + 1) + 4;
10932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cp[0] == ep - cp - 1) {
10942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* icmp-name-lookup-03, pascal string */
10952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (vflag)
10962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf(", 03 draft");
10972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				cp++;
10982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", \"");
10992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				while (cp < ep) {
11002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					safeputchar(*cp);
11012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					cp++;
11022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				}
11032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\"");
11042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			} else
11052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				dnsname_print(cp, ep);
11062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0)
11072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1));
11082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case NI_QTYPE_NODEADDR:
11102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
11112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
11122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("node addresses");
11132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = sizeof(*ni6);
11142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (i < siz) {
11152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz)
11162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					break;
11172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" %s", getname6(bp + i));
11182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				i += sizeof(struct in6_addr);
11192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i));
11202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				i += sizeof(int32_t);
11212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
11222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			i = ni6->ni_flags;
11232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!i)
11242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
11252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" [%s%s%s%s%s%s%s]",
11262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
11272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
11282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
11292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
11302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
11312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "",
11322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "");
11332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:
11352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (needcomma)
11362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(", ");
11372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("unknown");
11382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
11392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
11422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
11432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
11452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
11462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
11482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
11492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
11502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
11522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecticmp6_rrenum_print(const u_char *bp, const u_char *ep)
11532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
11542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct icmp6_router_renum *rr6;
11552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const char *cp;
11562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct rr_pco_match *match;
11572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct rr_pco_use *use;
11582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char hbuf[NI_MAXHOST];
11592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int n;
11602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (ep < bp)
11622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
11632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	rr6 = (struct icmp6_router_renum *)bp;
11642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	cp = (const char *)(rr6 + 1);
11652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK(rr6->rr_reserved);
11672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (rr6->rr_code) {
11682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_COMMAND:
11692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: command");
11702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_RESULT:
11722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: result");
11732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
11752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: sequence number reset");
11762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
11782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("router renum: code-#%d", rr6->rr_code);
11792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
11802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
11812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum));
11832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
11842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag) {
11852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define F(x, y)	((rr6->rr_flags) & (x) ? (y) : "")
11862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[");	/*]*/
11872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (rr6->rr_flags) {
11882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"),
11892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_REQRESULT, "R"),
11902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"),
11912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_SPECSITE, "S"),
11922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    F(ICMP6_RR_FLAGS_PREVDONE, "P"));
11932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("seg=%u,", rr6->rr_segnum);
11952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("maxdelay=%u", rr6->rr_maxdelay);
11962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (rr6->rr_reserved)
11972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("rsvd=0x%x", EXTRACT_16BITS(&rr6->rr_reserved));
11982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*[*/
11992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("]");
12002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef F
12012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) {
12042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		match = (struct rr_pco_match *)cp;
12052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		cp = (const char *)(match + 1);
12062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(match->rpm_prefix);
12082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag > 1)
12102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("\n\t");
12112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else
12122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" ");
12132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("match(");	/*)*/
12142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		switch (match->rpm_code) {
12152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_ADD:	printf("add"); break;
12162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_CHANGE:	printf("change"); break;
12172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		case RPM_PCO_SETGLOBAL:	printf("setglobal"); break;
12182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		default:		printf("#%u", match->rpm_code); break;
12192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
12202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
12222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",ord=%u", match->rpm_ordinal);
12232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",min=%u", match->rpm_minlen);
12242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",max=%u", match->rpm_maxlen);
12252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
12262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf)))
12272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",%s/%u", hbuf, match->rpm_matchlen);
12282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else
12292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(",?/%u", match->rpm_matchlen);
12302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*(*/
12312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(")");
12322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n = match->rpm_len - 3;
12342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (n % 4)
12352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
12362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n /= 4;
12372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (n-- > 0) {
12382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			use = (struct rr_pco_use *)cp;
12392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			cp = (const char *)(use + 1);
12402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK(use->rpu_prefix);
12422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag > 1)
12442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("\n\t");
12452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
12462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" ");
12472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("use(");	/*)*/
12482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (use->rpu_flags) {
12492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define F(x, y)	((use->rpu_flags) & (x) ? (y) : "")
12502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("%s%s,",
12512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"),
12522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P"));
12532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef F
12542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
12552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (vflag) {
12562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("mask=0x%x,", use->rpu_ramask);
12572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("raflags=0x%x,", use->rpu_raflags);
12582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (~use->rpu_vltime == 0)
12592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("vltime=infty,");
12602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				else
12612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("vltime=%u,",
12622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					    EXTRACT_32BITS(&use->rpu_vltime));
12632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				if (~use->rpu_pltime == 0)
12642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("pltime=infty,");
12652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				else
12662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					printf("pltime=%u,",
12672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project					    EXTRACT_32BITS(&use->rpu_pltime));
12682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
12692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf,
12702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(hbuf)))
12712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("%s/%u/%u", hbuf, use->rpu_uselen,
12722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    use->rpu_keeplen);
12732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			else
12742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("?/%u/%u", use->rpu_uselen,
12752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    use->rpu_keeplen);
12762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*(*/
12772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(")");
12782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
12792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
12802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
12822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
12842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs("[|icmp6]", stdout);
12852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
12862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
12872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* INET6 */
1288