DNS compression support.
be more picky about DNS label validation. (sync with kame)
This commit is contained in:
parent
f714bfb0d8
commit
1b2be13d48
@ -1,5 +1,5 @@
|
||||
.\" $NetBSD: ping6.8,v 1.8 2000/06/12 16:21:04 itojun Exp $
|
||||
.\" $KAME: ping6.8,v 1.23 2000/06/12 16:16:09 itojun Exp $
|
||||
.\" $NetBSD: ping6.8,v 1.9 2000/08/09 14:36:00 itojun Exp $
|
||||
.\" $KAME: ping6.8,v 1.26 2000/08/03 15:26:34 jinmei Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
@ -39,9 +39,9 @@ packets to network hosts
|
||||
.Sh SYNOPSIS
|
||||
.Nm ping6
|
||||
.\" without ipsec, or new ipsec
|
||||
.Op Fl dfHnNqRvw
|
||||
.Op Fl dfHnNqRtvw
|
||||
.\" old ipsec
|
||||
.\" .Op Fl AdEfnNqRvw
|
||||
.\" .Op Fl AdEfnNqRtvw
|
||||
.Bk -words
|
||||
.Op Fl a Ar addrtype
|
||||
.Ek
|
||||
@ -258,6 +258,13 @@ header data.
|
||||
You may need to specify
|
||||
.Fl b
|
||||
as well to extend socket buffer size.
|
||||
.It Fl t
|
||||
Generate ICMPv6 Node Information supported query types query,
|
||||
rather than echo-request.
|
||||
.Fl s
|
||||
has no effect if
|
||||
.Fl t
|
||||
is specified.
|
||||
.It Fl v
|
||||
Verbose output.
|
||||
.Tn ICMP
|
||||
@ -265,7 +272,7 @@ packets other than
|
||||
.Tn ECHO_RESPONSE
|
||||
that are received are listed.
|
||||
.It Fl w
|
||||
Generate ICMPv6 Node Information FQDN query, rather than echo-request.
|
||||
Generate ICMPv6 Node Information DNS Name query, rather than echo-request.
|
||||
.Fl s
|
||||
has no effect if
|
||||
.Fl w
|
||||
@ -402,8 +409,8 @@ and non-zero if the arguments are incorrect or the host is not responding.
|
||||
.Rs
|
||||
.%A Matt Crawford
|
||||
.%T "IPv6 Node Information Queries"
|
||||
.%N draft-ietf-ipngwg-icmp-name-lookups-05.txt
|
||||
.%D October 22, 1999
|
||||
.%N draft-ietf-ipngwg-icmp-name-lookups-06.txt
|
||||
.%D July 2000
|
||||
.%O work in progress material
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: ping6.c,v 1.16 2000/07/07 12:29:10 itojun Exp $ */
|
||||
/* $KAME: ping6.c,v 1.56 2000/07/07 12:17:15 itojun Exp $ */
|
||||
/* $NetBSD: ping6.c,v 1.17 2000/08/09 14:36:01 itojun Exp $ */
|
||||
/* $KAME: ping6.c,v 1.66 2000/08/09 14:34:15 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -81,7 +81,7 @@ static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ping6.c,v 1.16 2000/07/07 12:29:10 itojun Exp $");
|
||||
__RCSID("$NetBSD: ping6.c,v 1.17 2000/08/09 14:36:01 itojun Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -123,6 +123,7 @@ __RCSID("$NetBSD: ping6.c,v 1.16 2000/07/07 12:29:10 itojun Exp $");
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <ctype.h>
|
||||
@ -147,7 +148,8 @@ __RCSID("$NetBSD: ping6.c,v 1.16 2000/07/07 12:29:10 itojun Exp $");
|
||||
#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */
|
||||
#define ICMP6ECHOTMLEN sizeof(struct timeval)
|
||||
#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8)
|
||||
#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) /* 64 bits of nonce + 32 bits ttl */
|
||||
/* FQDN case, 64 bits of nonce + 32 bits ttl */
|
||||
#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12)
|
||||
#define EXTRA 256 /* for AH and various other headers. weird. */
|
||||
#define DEFDATALEN ICMP6ECHOTMLEN
|
||||
#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN
|
||||
@ -185,6 +187,8 @@ __RCSID("$NetBSD: ping6.c,v 1.16 2000/07/07 12:29:10 itojun Exp $");
|
||||
#define F_HOSTNAME 0x10000
|
||||
#define F_FQDNOLD 0x20000
|
||||
#define F_NIGROUP 0x40000
|
||||
#define F_SUPTYPES 0x80000
|
||||
#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
|
||||
u_int options;
|
||||
|
||||
#define IN6LEN sizeof(struct in6_addr)
|
||||
@ -212,6 +216,7 @@ char BSPACE = '\b'; /* characters written for flood */
|
||||
char DOT = '.';
|
||||
char *hostname;
|
||||
int ident; /* process id to identify our packets */
|
||||
u_int8_t nonce[8]; /* nonce field for node information */
|
||||
struct in6_addr srcaddr;
|
||||
|
||||
/* counters */
|
||||
@ -248,6 +253,10 @@ const char *pr_addr __P((struct sockaddr_in6 *));
|
||||
void pr_icmph __P((struct icmp6_hdr *, u_char *));
|
||||
void pr_iph __P((struct ip6_hdr *));
|
||||
void pr_nodeaddr __P((struct icmp6_nodeinfo *, int));
|
||||
int myechoreply __P((const struct icmp6_hdr *));
|
||||
int mynireply __P((const struct icmp6_nodeinfo *));
|
||||
char *dnsdecode __P((const u_char **, const u_char *, const u_char *,
|
||||
u_char *, size_t));
|
||||
void pr_pack __P((u_char *, int, struct msghdr *));
|
||||
void pr_exthdrs __P((struct msghdr *));
|
||||
void pr_ip6opt __P((void *));
|
||||
@ -281,6 +290,7 @@ main(argc, argv)
|
||||
#ifdef USE_RFC2292BIS
|
||||
struct ip6_rthdr *rthdr = NULL;
|
||||
#endif
|
||||
struct timeval tv;
|
||||
#ifdef IPSEC_POLICY_IPSEC
|
||||
char *policy_in = NULL;
|
||||
char *policy_out = NULL;
|
||||
@ -293,24 +303,24 @@ main(argc, argv)
|
||||
preload = 0;
|
||||
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
|
||||
#ifndef IPSEC
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwW")) != EOF)
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:tvwW")) != EOF)
|
||||
#else
|
||||
#ifdef IPSEC_POLICY_IPSEC
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwWP:")) != EOF)
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:tvwWP:")) != EOF)
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwWAE")) != EOF)
|
||||
while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:tvwWAE")) != EOF)
|
||||
#endif /*IPSEC_POLICY_IPSEC*/
|
||||
#endif
|
||||
{
|
||||
switch(ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
{
|
||||
char *cp;
|
||||
|
||||
options &= ~F_NOUSERDATA;
|
||||
options |= F_NODEADDR;
|
||||
datalen = 2048; /* XXX: enough? */
|
||||
for (cp = optarg; *cp != '\0'; cp++) {
|
||||
switch(*cp) {
|
||||
switch (*cp) {
|
||||
case 'a':
|
||||
naflags |= NI_NODEADDR_FLAG_ALL;
|
||||
break;
|
||||
@ -428,18 +438,25 @@ main(argc, argv)
|
||||
datalen = strtol(optarg, &e, 10);
|
||||
if (datalen <= 0 || *optarg == '\0' || *e != '\0')
|
||||
errx(1, "illegal datalen value -- %s", optarg);
|
||||
if (datalen > MAXDATALEN)
|
||||
if (datalen > MAXDATALEN) {
|
||||
errx(1,
|
||||
"datalen value too large, maximum is %d",
|
||||
MAXDATALEN);
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
options &= ~F_NOUSERDATA;
|
||||
options |= F_SUPTYPES;
|
||||
break;
|
||||
case 'v':
|
||||
options |= F_VERBOSE;
|
||||
break;
|
||||
case 'w':
|
||||
options &= ~F_NOUSERDATA;
|
||||
options |= F_FQDN;
|
||||
break;
|
||||
case 'W':
|
||||
options &= ~F_NOUSERDATA;
|
||||
options |= F_FQDNOLD;
|
||||
break;
|
||||
#ifdef IPSEC
|
||||
@ -476,9 +493,10 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
#ifdef USE_SIN6_SCOPE_ID
|
||||
ip6optlen += CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1));
|
||||
#else /* old advanced API */
|
||||
#ifdef IPV6_RECVRTHDR /* 2292bis */
|
||||
ip6optlen += CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0,
|
||||
argc - 1));
|
||||
#else /* RFC2292 */
|
||||
ip6optlen += inet6_rthdr_space(IPV6_RTHDR_TYPE_0, argc - 1);
|
||||
#endif
|
||||
}
|
||||
@ -518,16 +536,28 @@ main(argc, argv)
|
||||
if (options & F_FLOOD && options & F_INTERVAL)
|
||||
errx(1, "-f and -i incompatible options");
|
||||
|
||||
if (datalen >= sizeof(struct timeval)) /* can we time transfer */
|
||||
if ((options & F_NOUSERDATA) == 0 &&
|
||||
datalen >= sizeof(struct timeval)) {
|
||||
/* can we time transfer */
|
||||
timing = 1;
|
||||
} else {
|
||||
/* suppress timing for node information query */
|
||||
timing = 0;
|
||||
datalen = 2048;
|
||||
}
|
||||
packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA;
|
||||
if (!(packet = (u_char *)malloc((u_int)packlen)))
|
||||
err(1, "Unable to allocate packet");
|
||||
if (!(options & F_PINGFILLED))
|
||||
for (i = 8; i < datalen; ++i)
|
||||
for (i = ICMP6ECHOLEN; i < packlen; ++i)
|
||||
*datap++ = i;
|
||||
|
||||
ident = getpid() & 0xFFFF;
|
||||
gettimeofday(&tv, NULL);
|
||||
srand((unsigned int)(tv.tv_sec ^ tv.tv_usec ^ (long)ident));
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
for (i = 0; i < sizeof(nonce); i += sizeof(int))
|
||||
*((int *)&nonce[i]) = rand();
|
||||
|
||||
if ((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
|
||||
err(1, "socket");
|
||||
@ -579,7 +609,7 @@ main(argc, argv)
|
||||
if (!(options & F_VERBOSE)) {
|
||||
ICMP6_FILTER_SETBLOCKALL(&filt);
|
||||
if ((options & F_FQDN) || (options & F_FQDNOLD) ||
|
||||
(options & F_NODEADDR))
|
||||
(options & F_NODEADDR) || (options & F_SUPTYPES))
|
||||
ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt);
|
||||
else
|
||||
ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt);
|
||||
@ -963,26 +993,25 @@ pinger()
|
||||
struct icmp6_hdr *icp;
|
||||
struct iovec iov[2];
|
||||
int i, cc;
|
||||
struct icmp6_nodeinfo *nip;
|
||||
int seq;
|
||||
|
||||
icp = (struct icmp6_hdr *)outpack;
|
||||
nip = (struct icmp6_nodeinfo *)outpack;
|
||||
memset(icp, 0, sizeof(*icp));
|
||||
icp->icmp6_code = 0;
|
||||
icp->icmp6_cksum = 0;
|
||||
icp->icmp6_seq = ntransmitted++; /* htons later */
|
||||
icp->icmp6_id = htons(ident); /* ID */
|
||||
|
||||
CLR(icp->icmp6_seq % mx_dup_ck);
|
||||
icp->icmp6_seq = htons(icp->icmp6_seq);
|
||||
seq = ntransmitted++;
|
||||
CLR(seq % mx_dup_ck);
|
||||
|
||||
if (options & F_FQDN) {
|
||||
icp->icmp6_type = ICMP6_NI_QUERY;
|
||||
icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
|
||||
/* XXX: overwrite icmp6_id */
|
||||
((struct icmp6_nodeinfo *)icp)->ni_qtype = htons(NI_QTYPE_FQDN);
|
||||
((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0);
|
||||
if (timing)
|
||||
(void)gettimeofday((struct timeval *)
|
||||
&outpack[ICMP6ECHOLEN], NULL);
|
||||
nip->ni_qtype = htons(NI_QTYPE_FQDN);
|
||||
nip->ni_flags = htons(0);
|
||||
|
||||
memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce));
|
||||
*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
|
||||
|
||||
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
|
||||
sizeof(dst.sin6_addr));
|
||||
cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
|
||||
@ -990,33 +1019,43 @@ pinger()
|
||||
} else if (options & F_FQDNOLD) {
|
||||
/* packet format in 03 draft - no Subject data on queries */
|
||||
icp->icmp6_type = ICMP6_NI_QUERY;
|
||||
/* code field is always 0 */
|
||||
/* XXX: overwrite icmp6_id */
|
||||
((struct icmp6_nodeinfo *)icp)->ni_qtype = htons(NI_QTYPE_FQDN);
|
||||
((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0);
|
||||
if (timing)
|
||||
(void)gettimeofday((struct timeval *)
|
||||
&outpack[ICMP6ECHOLEN], NULL);
|
||||
icp->icmp6_code = 0; /* code field is always 0 */
|
||||
nip->ni_qtype = htons(NI_QTYPE_FQDN);
|
||||
nip->ni_flags = htons(0);
|
||||
|
||||
memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce));
|
||||
*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
|
||||
|
||||
cc = ICMP6_NIQLEN;
|
||||
datalen = 0;
|
||||
} else if (options & F_NODEADDR) {
|
||||
icp->icmp6_type = ICMP6_NI_QUERY;
|
||||
icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
|
||||
/* XXX: overwrite icmp6_id */
|
||||
((struct icmp6_nodeinfo *)icp)->ni_qtype =
|
||||
htons(NI_QTYPE_NODEADDR);
|
||||
((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0);
|
||||
if (timing)
|
||||
(void)gettimeofday((struct timeval *)
|
||||
&outpack[ICMP6ECHOLEN], NULL);
|
||||
nip->ni_qtype = htons(NI_QTYPE_NODEADDR);
|
||||
nip->ni_flags = naflags;
|
||||
|
||||
memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce));
|
||||
*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
|
||||
|
||||
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
|
||||
sizeof(dst.sin6_addr));
|
||||
cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
|
||||
datalen = 0;
|
||||
((struct icmp6_nodeinfo *)icp)->ni_flags = naflags;
|
||||
}
|
||||
else {
|
||||
} else if (options & F_SUPTYPES) {
|
||||
icp->icmp6_type = ICMP6_NI_QUERY;
|
||||
icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/
|
||||
nip->ni_qtype = htons(NI_QTYPE_SUPTYPES);
|
||||
nip->ni_flags = 0; /* do not support compressed bitmap */
|
||||
|
||||
memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce));
|
||||
*(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
|
||||
cc = ICMP6_NIQLEN;
|
||||
datalen = 0;
|
||||
} else {
|
||||
icp->icmp6_type = ICMP6_ECHO_REQUEST;
|
||||
icp->icmp6_code = 0;
|
||||
icp->icmp6_id = htons(ident);
|
||||
icp->icmp6_seq = ntohs(seq);
|
||||
if (timing)
|
||||
(void)gettimeofday((struct timeval *)
|
||||
&outpack[ICMP6ECHOLEN], NULL);
|
||||
@ -1043,6 +1082,98 @@ pinger()
|
||||
(void)write(STDOUT_FILENO, &DOT, 1);
|
||||
}
|
||||
|
||||
int
|
||||
myechoreply(icp)
|
||||
const struct icmp6_hdr *icp;
|
||||
{
|
||||
if (ntohs(icp->icmp6_id) == ident)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mynireply(nip)
|
||||
const struct icmp6_nodeinfo *nip;
|
||||
{
|
||||
if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t),
|
||||
nonce + sizeof(u_int16_t),
|
||||
sizeof(nonce) - sizeof(u_int16_t)) == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
dnsdecode(sp, ep, base, buf, bufsiz)
|
||||
const u_char **sp;
|
||||
const u_char *ep;
|
||||
const u_char *base; /*base for compressed name*/
|
||||
u_char *buf;
|
||||
size_t bufsiz;
|
||||
{
|
||||
int i, l;
|
||||
const u_char *cp;
|
||||
char *q;
|
||||
const char *eq;
|
||||
char cresult[MAXDNAME + 1];
|
||||
const u_char *comp;
|
||||
|
||||
cp = *sp;
|
||||
q = buf;
|
||||
eq = buf + bufsiz;
|
||||
|
||||
if (cp >= ep)
|
||||
return NULL;
|
||||
while (cp < ep) {
|
||||
i = *cp;
|
||||
if (i == 0 || cp != *sp) {
|
||||
if (q >= eq - 1)
|
||||
return NULL; /*result overrun*/
|
||||
*q++ = '.';
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
cp++;
|
||||
|
||||
if ((i & 0xc0) == 0xc0 && cp - base > (i & 0x3f)) {
|
||||
/* DNS compression */
|
||||
if (!base)
|
||||
return NULL;
|
||||
|
||||
comp = base + (i & 0x3f);
|
||||
if (dnsdecode(&comp, cp, base, cresult,
|
||||
sizeof(cresult)) == NULL)
|
||||
return NULL;
|
||||
if (eq - q < strlen(cresult) + 1)
|
||||
return NULL; /*result overrun*/
|
||||
strcpy(q, cresult); /*XXX should be strlcpy*/
|
||||
q += strlen(q);
|
||||
break;
|
||||
} else if ((i & 0x3f) == i) {
|
||||
if (i > ep - cp)
|
||||
return NULL; /*source overrun*/
|
||||
while (i-- > 0 && cp < ep) {
|
||||
if (eq - q < (isprint(*cp) ? 2 : 5))
|
||||
return NULL; /*result overrun*/
|
||||
l = snprintf(q, eq - q,
|
||||
isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff);
|
||||
cp++;
|
||||
q += l;
|
||||
}
|
||||
} else
|
||||
return NULL; /*invalid label*/
|
||||
}
|
||||
if (q >= eq)
|
||||
return NULL; /*result overrun*/
|
||||
if (i != 0)
|
||||
return NULL; /*not terminated*/
|
||||
cp++;
|
||||
*q = '\0';
|
||||
*sp = cp;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* pr_pack --
|
||||
* Print out the packet, if it came from us. This logic is necessary
|
||||
@ -1058,6 +1189,7 @@ pr_pack(buf, cc, mhdr)
|
||||
{
|
||||
#define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c)
|
||||
struct icmp6_hdr *icp;
|
||||
struct icmp6_nodeinfo *ni;
|
||||
int i;
|
||||
int hoplim;
|
||||
struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
|
||||
@ -1068,6 +1200,8 @@ pr_pack(buf, cc, mhdr)
|
||||
int dupflag;
|
||||
size_t off;
|
||||
int oldfqdn;
|
||||
u_int16_t seq;
|
||||
char dnsname[MAXDNAME + 1];
|
||||
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
|
||||
@ -1078,6 +1212,7 @@ pr_pack(buf, cc, mhdr)
|
||||
return;
|
||||
}
|
||||
icp = (struct icmp6_hdr *)buf;
|
||||
ni = (struct icmp6_nodeinfo *)buf;
|
||||
off = 0;
|
||||
|
||||
if ((hoplim = get_hoplim(mhdr)) == -1) {
|
||||
@ -1089,11 +1224,8 @@ pr_pack(buf, cc, mhdr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (icp->icmp6_type == ICMP6_ECHO_REPLY) {
|
||||
/* XXX the following line overwrites the original packet */
|
||||
icp->icmp6_seq = ntohs(icp->icmp6_seq);
|
||||
if (ntohs(icp->icmp6_id) != ident)
|
||||
return; /* It was not our ECHO */
|
||||
if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) {
|
||||
seq = ntohs(icp->icmp6_seq);
|
||||
++nreceived;
|
||||
if (timing) {
|
||||
tp = (struct timeval *)(icp + 1);
|
||||
@ -1107,12 +1239,12 @@ pr_pack(buf, cc, mhdr)
|
||||
tmax = triptime;
|
||||
}
|
||||
|
||||
if (TST(icp->icmp6_seq % mx_dup_ck)) {
|
||||
if (TST(seq % mx_dup_ck)) {
|
||||
++nrepeats;
|
||||
--nreceived;
|
||||
dupflag = 1;
|
||||
} else {
|
||||
SET(icp->icmp6_seq % mx_dup_ck);
|
||||
SET(seq % mx_dup_ck);
|
||||
dupflag = 0;
|
||||
}
|
||||
|
||||
@ -1123,8 +1255,7 @@ pr_pack(buf, cc, mhdr)
|
||||
(void)write(STDOUT_FILENO, &BSPACE, 1);
|
||||
else {
|
||||
(void)printf("%d bytes from %s, icmp_seq=%u", cc,
|
||||
pr_addr(from),
|
||||
icp->icmp6_seq);
|
||||
pr_addr(from), seq);
|
||||
(void)printf(" hlim=%d", hoplim);
|
||||
if ((options & F_VERBOSE) != 0) {
|
||||
struct sockaddr_in6 dstsa;
|
||||
@ -1150,18 +1281,54 @@ pr_pack(buf, cc, mhdr)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (icp->icmp6_type == ICMP6_NI_REPLY) { /* ICMP6_NI_REPLY */
|
||||
struct icmp6_nodeinfo *ni = (struct icmp6_nodeinfo *)(buf + off);
|
||||
} else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) {
|
||||
seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce);
|
||||
++nreceived;
|
||||
if (TST(seq % mx_dup_ck)) {
|
||||
++nrepeats;
|
||||
--nreceived;
|
||||
dupflag = 1;
|
||||
} else {
|
||||
SET(seq % mx_dup_ck);
|
||||
dupflag = 0;
|
||||
}
|
||||
|
||||
(void)printf("%d bytes from %s: ", cc,
|
||||
pr_addr(from));
|
||||
if (options & F_QUIET)
|
||||
return;
|
||||
|
||||
switch(ntohs(ni->ni_qtype)) {
|
||||
(void)printf("%d bytes from %s: ", cc, pr_addr(from));
|
||||
|
||||
switch (ntohs(ni->ni_code)) {
|
||||
case ICMP6_NI_SUCCESS:
|
||||
break;
|
||||
case ICMP6_NI_REFUSED:
|
||||
printf("refused, type 0x%x", ntohs(ni->ni_type));
|
||||
goto fqdnend;
|
||||
case ICMP6_NI_UNKNOWN:
|
||||
printf("unknown, type 0x%x", ntohs(ni->ni_type));
|
||||
goto fqdnend;
|
||||
default:
|
||||
printf("unknown code 0x%x, type 0x%x",
|
||||
ntohs(ni->ni_code), ntohs(ni->ni_type));
|
||||
goto fqdnend;
|
||||
}
|
||||
|
||||
switch (ntohs(ni->ni_qtype)) {
|
||||
case NI_QTYPE_NOOP:
|
||||
printf("NodeInfo NOOP");
|
||||
break;
|
||||
case NI_QTYPE_SUPTYPES:
|
||||
printf("NodeInfo Supported Qtypes");
|
||||
if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) != 0) {
|
||||
printf(", compressed bitmap");
|
||||
break;
|
||||
}
|
||||
cp = (u_char *)(ni + 1);
|
||||
if (cp + 4 != end) {
|
||||
printf(", invalid length");
|
||||
break;
|
||||
}
|
||||
printf(", bitmap = 0x%08x", ntohl(*(u_int32_t *)cp));
|
||||
break;
|
||||
case NI_QTYPE_NODEADDR:
|
||||
pr_nodeaddr(ni, end - (u_char *)ni);
|
||||
@ -1175,38 +1342,31 @@ pr_pack(buf, cc, mhdr)
|
||||
else
|
||||
oldfqdn = 0;
|
||||
if (oldfqdn) {
|
||||
cp++;
|
||||
cp++; /* skip length */
|
||||
while (cp < end) {
|
||||
safeputc(*cp & 0xff);
|
||||
cp++;
|
||||
}
|
||||
} else {
|
||||
i = 0;
|
||||
while (cp < end) {
|
||||
i = *cp++;
|
||||
if (i) {
|
||||
if (i > end - cp) {
|
||||
if (dnsdecode((const u_char **)&cp, end,
|
||||
(const u_char *)(ni + 1), dnsname,
|
||||
sizeof(dnsname)) == NULL) {
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
while (i-- && cp < end) {
|
||||
safeputc(*cp & 0xff);
|
||||
/*
|
||||
* name-lookup special handling for
|
||||
* truncated name
|
||||
*/
|
||||
if (cp + 1 < end && !*cp &&
|
||||
strlen(dnsname) > 0) {
|
||||
dnsname[strlen(dnsname) - 1] = '\0';
|
||||
cp++;
|
||||
}
|
||||
if (cp + 1 < end && *cp)
|
||||
printf(".");
|
||||
} else {
|
||||
if (cp == end) {
|
||||
/* FQDN */
|
||||
printf(".");
|
||||
} else if (cp + 1 == end &&
|
||||
*cp == '\0') {
|
||||
/* truncated */
|
||||
} else {
|
||||
/* invalid */
|
||||
printf("???");
|
||||
}
|
||||
break;
|
||||
}
|
||||
printf("%s%s", i > 0 ? "," : "",
|
||||
dnsname);
|
||||
}
|
||||
}
|
||||
if (options & F_VERBOSE) {
|
||||
@ -1215,7 +1375,7 @@ pr_pack(buf, cc, mhdr)
|
||||
|
||||
(void)printf(" ("); /*)*/
|
||||
|
||||
switch(ni->ni_code) {
|
||||
switch (ni->ni_code) {
|
||||
case ICMP6_NI_REFUSED:
|
||||
(void)printf("refused");
|
||||
comma++;
|
||||
@ -1233,10 +1393,10 @@ pr_pack(buf, cc, mhdr)
|
||||
ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]);
|
||||
if (comma)
|
||||
printf(",");
|
||||
if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL))
|
||||
if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) {
|
||||
(void)printf("TTL=%d:meaningless",
|
||||
(int)ttl);
|
||||
else {
|
||||
} else {
|
||||
if (ttl < 0) {
|
||||
(void)printf("TTL=%d:invalid",
|
||||
ttl);
|
||||
@ -1279,8 +1439,7 @@ pr_pack(buf, cc, mhdr)
|
||||
/* We've got something other than an ECHOREPLY */
|
||||
if (!(options & F_VERBOSE))
|
||||
return;
|
||||
(void)printf("%d bytes from %s: ", cc,
|
||||
pr_addr(from));
|
||||
(void)printf("%d bytes from %s: ", cc, pr_addr(from));
|
||||
pr_icmph(icp, end);
|
||||
}
|
||||
|
||||
@ -1304,7 +1463,7 @@ pr_exthdrs(mhdr)
|
||||
if (cm->cmsg_level != IPPROTO_IPV6)
|
||||
continue;
|
||||
|
||||
switch(cm->cmsg_type) {
|
||||
switch (cm->cmsg_type) {
|
||||
case IPV6_HOPOPTS:
|
||||
printf(" HbH Options: ");
|
||||
pr_ip6opt(CMSG_DATA(cm));
|
||||
@ -1437,7 +1596,7 @@ pr_nodeaddr(ni, nilen)
|
||||
nilen -= sizeof(struct icmp6_nodeinfo);
|
||||
|
||||
if (options & F_VERBOSE) {
|
||||
switch(ni->ni_code) {
|
||||
switch (ni->ni_code) {
|
||||
case ICMP6_NI_REFUSED:
|
||||
(void)printf("refused");
|
||||
break;
|
||||
@ -1569,21 +1728,18 @@ summary()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
static char *ttab[] = {
|
||||
"Echo Reply", /* ip + seq + udata */
|
||||
"Dest Unreachable", /* net, host, proto, port, frag, sr + IP */
|
||||
"Source Quench", /* IP */
|
||||
"Redirect", /* redirect type, gateway, + IP */
|
||||
"Echo",
|
||||
"Time Exceeded", /* transit, frag reassem + IP */
|
||||
"Parameter Problem", /* pointer + IP */
|
||||
"Timestamp", /* id + seq + three timestamps */
|
||||
"Timestamp Reply", /* " */
|
||||
"Info Request", /* id + sq */
|
||||
"Info Reply" /* " */
|
||||
/*subject type*/
|
||||
static char *niqcode[] = {
|
||||
"IPv6 address",
|
||||
"DNS label", /*or empty*/
|
||||
"IPv4 address",
|
||||
};
|
||||
#endif
|
||||
|
||||
/*result code*/
|
||||
static char *nircode[] = {
|
||||
"Success", "Refused", "Unknown",
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* pr_icmph --
|
||||
@ -1595,10 +1751,15 @@ pr_icmph(icp, end)
|
||||
u_char *end;
|
||||
{
|
||||
char ntop_buf[INET6_ADDRSTRLEN];
|
||||
struct nd_redirect *red;
|
||||
struct icmp6_nodeinfo *ni;
|
||||
char dnsname[MAXDNAME + 1];
|
||||
const u_char *cp;
|
||||
size_t l;
|
||||
|
||||
switch(icp->icmp6_type) {
|
||||
switch (icp->icmp6_type) {
|
||||
case ICMP6_DST_UNREACH:
|
||||
switch(icp->icmp6_code) {
|
||||
switch (icp->icmp6_code) {
|
||||
case ICMP6_DST_UNREACH_NOROUTE:
|
||||
(void)printf("No Route to Destination\n");
|
||||
break;
|
||||
@ -1629,7 +1790,7 @@ pr_icmph(icp, end)
|
||||
pr_retip((struct ip6_hdr *)(icp + 1), end);
|
||||
break;
|
||||
case ICMP6_TIME_EXCEEDED:
|
||||
switch(icp->icmp6_code) {
|
||||
switch (icp->icmp6_code) {
|
||||
case ICMP6_TIME_EXCEED_TRANSIT:
|
||||
(void)printf("Time to live exceeded\n");
|
||||
break;
|
||||
@ -1645,7 +1806,7 @@ pr_icmph(icp, end)
|
||||
break;
|
||||
case ICMP6_PARAM_PROB:
|
||||
(void)printf("Parameter problem: ");
|
||||
switch(icp->icmp6_code) {
|
||||
switch (icp->icmp6_code) {
|
||||
case ICMP6_PARAMPROB_HEADER:
|
||||
(void)printf("Erroneous Header ");
|
||||
break;
|
||||
@ -1693,9 +1854,7 @@ pr_icmph(icp, end)
|
||||
(void)printf("Neighbor Advertisement");
|
||||
break;
|
||||
case ND_REDIRECT:
|
||||
{
|
||||
struct nd_redirect *red = (struct nd_redirect *)icp;
|
||||
|
||||
red = (struct nd_redirect *)icp;
|
||||
(void)printf("Redirect\n");
|
||||
(void)printf("Destination: %s",
|
||||
inet_ntop(AF_INET6, &red->nd_rd_dst,
|
||||
@ -1704,14 +1863,105 @@ pr_icmph(icp, end)
|
||||
inet_ntop(AF_INET6, &red->nd_rd_target,
|
||||
ntop_buf, sizeof(ntop_buf)));
|
||||
break;
|
||||
}
|
||||
case ICMP6_NI_QUERY:
|
||||
(void)printf("Node Information Query");
|
||||
/* XXX ID + Seq + Data */
|
||||
ni = (struct icmp6_nodeinfo *)icp;
|
||||
l = end - (u_char *)(ni + 1);
|
||||
printf(", ");
|
||||
switch (ntohs(ni->ni_qtype)) {
|
||||
case NI_QTYPE_NOOP:
|
||||
(void)printf("NOOP");
|
||||
break;
|
||||
case NI_QTYPE_SUPTYPES:
|
||||
(void)printf("Supported qtypes");
|
||||
break;
|
||||
case NI_QTYPE_FQDN:
|
||||
(void)printf("DNS name");
|
||||
break;
|
||||
case NI_QTYPE_NODEADDR:
|
||||
(void)printf("nodeaddr");
|
||||
break;
|
||||
case NI_QTYPE_IPV4ADDR:
|
||||
(void)printf("IPv4 nodeaddr");
|
||||
break;
|
||||
default:
|
||||
(void)printf("unknown qtype");
|
||||
break;
|
||||
}
|
||||
if (options & F_VERBOSE) {
|
||||
switch (ni->ni_code) {
|
||||
case ICMP6_NI_SUBJ_IPV6:
|
||||
if (l == sizeof(struct in6_addr) &&
|
||||
inet_ntop(AF_INET6, ni + 1, ntop_buf, sizeof(ntop_buf)) != NULL) {
|
||||
(void)printf(", subject=%s(%s)",
|
||||
niqcode[ni->ni_code], ntop_buf);
|
||||
} else {
|
||||
#if 1
|
||||
/* backward compat to -W */
|
||||
(void)printf(", oldfqdn");
|
||||
#else
|
||||
(void)printf(", invalid");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case ICMP6_NI_SUBJ_FQDN:
|
||||
if (end == (u_char *)(ni + 1)) {
|
||||
(void)printf(", no subject");
|
||||
break;
|
||||
}
|
||||
printf(", subject=%s", niqcode[ni->ni_code]);
|
||||
cp = (const u_char *)(ni + 1);
|
||||
if (dnsdecode(&cp, end, NULL, dnsname, sizeof(dnsname)) != NULL)
|
||||
printf("(%s)", dnsname);
|
||||
else
|
||||
printf("(invalid)");
|
||||
break;
|
||||
case ICMP6_NI_SUBJ_IPV4:
|
||||
if (l == sizeof(struct in_addr) &&
|
||||
inet_ntop(AF_INET, ni + 1, ntop_buf, sizeof(ntop_buf)) != NULL) {
|
||||
(void)printf(", subject=%s(%s)",
|
||||
niqcode[ni->ni_code], ntop_buf);
|
||||
} else
|
||||
(void)printf(", invalid");
|
||||
break;
|
||||
default:
|
||||
(void)printf(", invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ICMP6_NI_REPLY:
|
||||
(void)printf("Node Information Reply");
|
||||
/* XXX ID + Seq + Data */
|
||||
ni = (struct icmp6_nodeinfo *)icp;
|
||||
printf(", ");
|
||||
switch (ntohs(ni->ni_qtype)) {
|
||||
case NI_QTYPE_NOOP:
|
||||
(void)printf("NOOP");
|
||||
break;
|
||||
case NI_QTYPE_SUPTYPES:
|
||||
(void)printf("Supported qtypes");
|
||||
break;
|
||||
case NI_QTYPE_FQDN:
|
||||
(void)printf("DNS name");
|
||||
break;
|
||||
case NI_QTYPE_NODEADDR:
|
||||
(void)printf("nodeaddr");
|
||||
break;
|
||||
case NI_QTYPE_IPV4ADDR:
|
||||
(void)printf("IPv4 nodeaddr");
|
||||
break;
|
||||
default:
|
||||
(void)printf("unknown qtype");
|
||||
break;
|
||||
}
|
||||
if (options & F_VERBOSE) {
|
||||
if (ni->ni_code > sizeof(nircode) / sizeof(nircode[0]))
|
||||
printf(", invalid");
|
||||
else
|
||||
printf(", %s", nircode[ni->ni_code]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void)printf("Bad ICMP type: %d", icp->icmp6_type);
|
||||
@ -1759,14 +2009,15 @@ pr_addr(addr)
|
||||
|
||||
if ((options & F_HOSTNAME) == 0)
|
||||
flag |= NI_NUMERICHOST;
|
||||
#ifdef KAME_SCOPEID
|
||||
#ifdef NI_WITHSCOPEID
|
||||
flag |= NI_WITHSCOPEID;
|
||||
#endif
|
||||
|
||||
getnameinfo((struct sockaddr *)addr, addr->sin6_len, buf, sizeof(buf),
|
||||
NULL, 0, flag);
|
||||
|
||||
if (getnameinfo((struct sockaddr *)addr, addr->sin6_len,
|
||||
buf, sizeof(buf), NULL, 0, flag) == 0)
|
||||
return (buf);
|
||||
else
|
||||
return "?";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1820,8 +2071,7 @@ pr_retip(ip6, end)
|
||||
break;
|
||||
#endif
|
||||
case IPPROTO_ICMPV6:
|
||||
printf("ICMP6: type = %d, code = %d\n",
|
||||
*cp, *(cp + 1));
|
||||
printf("ICMP6: type = %d, code = %d\n", *cp, *(cp + 1));
|
||||
return;
|
||||
case IPPROTO_ESP:
|
||||
printf("ESP\n");
|
||||
@ -1937,10 +2187,8 @@ nigroup(name)
|
||||
MD5Update(&ctxt, name, p - name);
|
||||
MD5Final(digest, &ctxt);
|
||||
|
||||
bzero(&in6, sizeof(in6));
|
||||
in6.s6_addr[0] = 0xff;
|
||||
in6.s6_addr[1] = 0x02;
|
||||
in6.s6_addr[11] = 0x02;
|
||||
if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1)
|
||||
return NULL; /*XXX*/
|
||||
bcopy(digest, &in6.s6_addr[12], 4);
|
||||
|
||||
if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user