Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/ping6/ping6.c
Show First 20 Lines • Show All 301 Lines • ▼ Show 20 Lines | main(int argc, char *argv[]) | ||||
/* For control (ancillary) data received from recvmsg() */ | /* For control (ancillary) data received from recvmsg() */ | ||||
struct cmsghdr cm[CONTROLLEN]; | struct cmsghdr cm[CONTROLLEN]; | ||||
#if defined(SO_SNDBUF) && defined(SO_RCVBUF) | #if defined(SO_SNDBUF) && defined(SO_RCVBUF) | ||||
u_long lsockbufsize; | u_long lsockbufsize; | ||||
int sockbufsize = 0; | int sockbufsize = 0; | ||||
#endif | #endif | ||||
int usepktinfo = 0; | int usepktinfo = 0; | ||||
struct in6_pktinfo *pktinfo = NULL; | struct in6_pktinfo *pktinfo = NULL; | ||||
#ifdef USE_RFC2292BIS | |||||
struct ip6_rthdr *rthdr = NULL; | struct ip6_rthdr *rthdr = NULL; | ||||
#endif | |||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
char *policy_in = NULL; | char *policy_in = NULL; | ||||
char *policy_out = NULL; | char *policy_out = NULL; | ||||
#endif | #endif | ||||
double t; | double t; | ||||
u_long alarmtimeout; | u_long alarmtimeout; | ||||
size_t rthlen; | size_t rthlen; | ||||
#ifdef IPV6_USE_MIN_MTU | #ifdef IPV6_USE_MIN_MTU | ||||
▲ Show 20 Lines • Show All 576 Lines • ▼ Show 20 Lines | if (hoplimit != -1) { | ||||
scmsgp->cmsg_type = IPV6_HOPLIMIT; | scmsgp->cmsg_type = IPV6_HOPLIMIT; | ||||
*(int *)(CMSG_DATA(scmsgp)) = hoplimit; | *(int *)(CMSG_DATA(scmsgp)) = hoplimit; | ||||
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | ||||
} | } | ||||
if (argc > 1) { /* some intermediate addrs are specified */ | if (argc > 1) { /* some intermediate addrs are specified */ | ||||
int hops; | int hops; | ||||
#ifdef USE_RFC2292BIS | |||||
int rthdrlen; | int rthdrlen; | ||||
#endif | |||||
#ifdef USE_RFC2292BIS | |||||
rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1); | rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1); | ||||
scmsgp->cmsg_len = CMSG_LEN(rthdrlen); | scmsgp->cmsg_len = CMSG_LEN(rthdrlen); | ||||
scmsgp->cmsg_level = IPPROTO_IPV6; | scmsgp->cmsg_level = IPPROTO_IPV6; | ||||
scmsgp->cmsg_type = IPV6_RTHDR; | scmsgp->cmsg_type = IPV6_RTHDR; | ||||
rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp); | rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp); | ||||
rthdr = inet6_rth_init((void *)rthdr, rthdrlen, | rthdr = inet6_rth_init((void *)rthdr, rthdrlen, | ||||
IPV6_RTHDR_TYPE_0, argc - 1); | IPV6_RTHDR_TYPE_0, argc - 1); | ||||
if (rthdr == NULL) | if (rthdr == NULL) | ||||
errx(1, "can't initialize rthdr"); | errx(1, "can't initialize rthdr"); | ||||
#else /* old advanced API */ | |||||
if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp, | |||||
IPV6_RTHDR_TYPE_0)) == NULL) | |||||
errx(1, "can't initialize rthdr"); | |||||
#endif /* USE_RFC2292BIS */ | |||||
for (hops = 0; hops < argc - 1; hops++) { | for (hops = 0; hops < argc - 1; hops++) { | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
if ((error = getaddrinfo(argv[hops], NULL, &hints, | if ((error = getaddrinfo(argv[hops], NULL, &hints, | ||||
&res))) | &res))) | ||||
errx(1, "%s", gai_strerror(error)); | errx(1, "%s", gai_strerror(error)); | ||||
if (res->ai_addr->sa_family != AF_INET6) | if (res->ai_addr->sa_family != AF_INET6) | ||||
errx(1, | errx(1, | ||||
"bad addr family of an intermediate addr"); | "bad addr family of an intermediate addr"); | ||||
sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr; | sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr; | ||||
#ifdef USE_RFC2292BIS | |||||
if (inet6_rth_add(rthdr, &sin6->sin6_addr)) | if (inet6_rth_add(rthdr, &sin6->sin6_addr)) | ||||
errx(1, "can't add an intermediate node"); | errx(1, "can't add an intermediate node"); | ||||
#else /* old advanced API */ | |||||
if (inet6_rthdr_add(scmsg, &sin6->sin6_addr, | |||||
IPV6_RTHDR_LOOSE)) | |||||
errx(1, "can't add an intermediate node"); | |||||
#endif /* USE_RFC2292BIS */ | |||||
freeaddrinfo(res); | freeaddrinfo(res); | ||||
} | } | ||||
#ifndef USE_RFC2292BIS | |||||
if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE)) | |||||
errx(1, "can't set the last flag"); | |||||
#endif | |||||
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | ||||
} | } | ||||
if (!(options & F_SRCADDR)) { | if (!(options & F_SRCADDR)) { | ||||
/* | /* | ||||
* get the source address. XXX since we revoked the root | * get the source address. XXX since we revoked the root | ||||
* privilege, we cannot use a raw socket for this. | * privilege, we cannot use a raw socket for this. | ||||
*/ | */ | ||||
int dummy; | int dummy; | ||||
socklen_t len = sizeof(src); | socklen_t len = sizeof(src); | ||||
if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) | ||||
err(1, "UDP socket"); | err(1, "UDP socket"); | ||||
src.sin6_family = AF_INET6; | src.sin6_family = AF_INET6; | ||||
src.sin6_addr = dst.sin6_addr; | src.sin6_addr = dst.sin6_addr; | ||||
src.sin6_port = ntohs(DUMMY_PORT); | src.sin6_port = ntohs(DUMMY_PORT); | ||||
src.sin6_scope_id = dst.sin6_scope_id; | src.sin6_scope_id = dst.sin6_scope_id; | ||||
#ifdef USE_RFC2292BIS | |||||
if (pktinfo && | if (pktinfo && | ||||
setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, | setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, | ||||
(void *)pktinfo, sizeof(*pktinfo))) | (void *)pktinfo, sizeof(*pktinfo))) | ||||
err(1, "UDP setsockopt(IPV6_PKTINFO)"); | err(1, "UDP setsockopt(IPV6_PKTINFO)"); | ||||
if (hoplimit != -1 && | if (hoplimit != -1 && | ||||
setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS, | setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS, | ||||
(void *)&hoplimit, sizeof(hoplimit))) | (void *)&hoplimit, sizeof(hoplimit))) | ||||
err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)"); | err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)"); | ||||
if (hoplimit != -1 && | if (hoplimit != -1 && | ||||
setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, | setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, | ||||
(void *)&hoplimit, sizeof(hoplimit))) | (void *)&hoplimit, sizeof(hoplimit))) | ||||
err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)"); | err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)"); | ||||
if (rthdr && | if (rthdr && | ||||
setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, | setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, | ||||
(void *)rthdr, (rthdr->ip6r_len + 1) << 3)) | (void *)rthdr, (rthdr->ip6r_len + 1) << 3)) | ||||
err(1, "UDP setsockopt(IPV6_RTHDR)"); | err(1, "UDP setsockopt(IPV6_RTHDR)"); | ||||
#else /* old advanced API */ | |||||
if (smsghdr.msg_control && | |||||
setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTOPTIONS, | |||||
(void *)smsghdr.msg_control, smsghdr.msg_controllen)) | |||||
err(1, "UDP setsockopt(IPV6_PKTOPTIONS)"); | |||||
#endif | |||||
if (connect(dummy, (struct sockaddr *)&src, len) < 0) | if (connect(dummy, (struct sockaddr *)&src, len) < 0) | ||||
err(1, "UDP connect"); | err(1, "UDP connect"); | ||||
if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) | if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) | ||||
err(1, "getsockname"); | err(1, "getsockname"); | ||||
close(dummy); | close(dummy); | ||||
▲ Show 20 Lines • Show All 775 Lines • ▼ Show 20 Lines | #endif | ||||
case IPV6_RTHDR: | case IPV6_RTHDR: | ||||
printf(" Routing: "); | printf(" Routing: "); | ||||
pr_rthdr(CMSG_DATA(cm), (size_t)bufsize); | pr_rthdr(CMSG_DATA(cm), (size_t)bufsize); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#ifdef USE_RFC2292BIS | |||||
static void | static void | ||||
pr_ip6opt(void *extbuf, size_t bufsize) | pr_ip6opt(void *extbuf, size_t bufsize) | ||||
{ | { | ||||
struct ip6_hbh *ext; | struct ip6_hbh *ext; | ||||
int currentlen; | int currentlen; | ||||
u_int8_t type; | u_int8_t type; | ||||
socklen_t extlen, len; | socklen_t extlen, len; | ||||
void *databuf; | void *databuf; | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | while (1) { | ||||
default: | default: | ||||
printf(" Received Opt %u len %lu\n", | printf(" Received Opt %u len %lu\n", | ||||
type, (unsigned long)len); | type, (unsigned long)len); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
#else /* !USE_RFC2292BIS */ | |||||
/* ARGSUSED */ | |||||
static void | |||||
pr_ip6opt(void *extbuf, size_t bufsize __unused) | |||||
{ | |||||
putchar('\n'); | |||||
return; | |||||
} | |||||
#endif /* USE_RFC2292BIS */ | |||||
#ifdef USE_RFC2292BIS | |||||
static void | static void | ||||
pr_rthdr(void *extbuf, size_t bufsize) | pr_rthdr(void *extbuf, size_t bufsize) | ||||
{ | { | ||||
struct in6_addr *in6; | struct in6_addr *in6; | ||||
char ntopbuf[INET6_ADDRSTRLEN]; | char ntopbuf[INET6_ADDRSTRLEN]; | ||||
struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; | struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; | ||||
int i, segments, origsegs, rthsize, size0, size1; | int i, segments, origsegs, rthsize, size0, size1; | ||||
Show All 38 Lines | else { | ||||
strlcpy(ntopbuf, "?", sizeof(ntopbuf)); | strlcpy(ntopbuf, "?", sizeof(ntopbuf)); | ||||
printf(" [%d]%s\n", i, ntopbuf); | printf(" [%d]%s\n", i, ntopbuf); | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
#else /* !USE_RFC2292BIS */ | |||||
/* ARGSUSED */ | |||||
static void | |||||
pr_rthdr(void *extbuf, size_t bufsize __unused) | |||||
{ | |||||
putchar('\n'); | |||||
return; | |||||
} | |||||
#endif /* USE_RFC2292BIS */ | |||||
static int | static int | ||||
pr_bitrange(u_int32_t v, int soff, int ii) | pr_bitrange(u_int32_t v, int soff, int ii) | ||||
{ | { | ||||
int off; | int off; | ||||
int i; | int i; | ||||
off = 0; | off = 0; | ||||
▲ Show 20 Lines • Show All 847 Lines • Show Last 20 Lines |