ping6.c (69571) | ping6.c (78064) |
---|---|
1/* $KAME: ping6.c,v 1.54 2000/06/12 16:16:44 itojun Exp $ */ | 1/* $KAME: ping6.c,v 1.126 2001/05/17 03:39:08 itojun Exp $ */ |
2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: --- 63 unchanged lines hidden (view full) --- 73 The Regents of the University of California. All rights reserved.\n"; 74#endif /* not lint */ 75 76#ifndef lint 77#if 0 78static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 79#endif 80static const char rcsid[] = | 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: --- 63 unchanged lines hidden (view full) --- 73 The Regents of the University of California. All rights reserved.\n"; 74#endif /* not lint */ 75 76#ifndef lint 77#if 0 78static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 79#endif 80static const char rcsid[] = |
81 "$FreeBSD: head/sbin/ping6/ping6.c 69571 2000-12-04 13:38:59Z ume $"; | 81 "$FreeBSD: head/sbin/ping6/ping6.c 78064 2001-06-11 12:39:29Z ume $"; |
82#endif /* not lint */ 83 84/* 85 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 86 * measure round-trip-delays and packet loss across network paths. 87 * 88 * Author - 89 * Mike Muuss --- 4 unchanged lines hidden (view full) --- 94 * Public Domain. Distribution Unlimited. 95 * Bugs - 96 * More statistics could always be gathered. 97 * This program has to run SUID to ROOT to access the ICMP socket. 98 */ 99/* 100 * NOTE: 101 * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics | 82#endif /* not lint */ 83 84/* 85 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 86 * measure round-trip-delays and packet loss across network paths. 87 * 88 * Author - 89 * Mike Muuss --- 4 unchanged lines hidden (view full) --- 94 * Public Domain. Distribution Unlimited. 95 * Bugs - 96 * More statistics could always be gathered. 97 * This program has to run SUID to ROOT to access the ICMP socket. 98 */ 99/* 100 * NOTE: 101 * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics |
102 * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* while 103 * IPV6_PKTINFO specifies *interface*. Link is defined as collection of | 102 * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* 103 * while IPV6_PKTINFO specifies *interface*. Link is defined as collection of |
104 * network attached to 1 or more interfaces) 105 */ 106 107#include <sys/param.h> 108#include <sys/uio.h> 109#include <sys/socket.h> 110#include <sys/time.h> 111 112#include <net/if.h> 113#include <net/route.h> 114 115#include <netinet/in.h> 116#include <netinet/ip6.h> 117#include <netinet/icmp6.h> 118#include <arpa/inet.h> | 104 * network attached to 1 or more interfaces) 105 */ 106 107#include <sys/param.h> 108#include <sys/uio.h> 109#include <sys/socket.h> 110#include <sys/time.h> 111 112#include <net/if.h> 113#include <net/route.h> 114 115#include <netinet/in.h> 116#include <netinet/ip6.h> 117#include <netinet/icmp6.h> 118#include <arpa/inet.h> |
119#include <arpa/nameser.h> |
|
119#include <netdb.h> 120 121#include <ctype.h> 122#include <err.h> 123#include <errno.h> 124#include <fcntl.h> | 120#include <netdb.h> 121 122#include <ctype.h> 123#include <err.h> 124#include <errno.h> 125#include <fcntl.h> |
126#if defined(__OpenBSD__) || defined(__NetBSD__) 127#include <math.h> 128#endif |
|
125#include <signal.h> 126#include <stdio.h> 127#include <stdlib.h> 128#include <string.h> 129#include <unistd.h> 130 131#ifdef IPSEC 132#include <netinet6/ah.h> --- 6 unchanged lines hidden (view full) --- 139#include "md5.h" 140#endif 141 142#define MAXPACKETLEN 131072 143#define IP6LEN 40 144#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 145#define ICMP6ECHOTMLEN sizeof(struct timeval) 146#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) | 129#include <signal.h> 130#include <stdio.h> 131#include <stdlib.h> 132#include <string.h> 133#include <unistd.h> 134 135#ifdef IPSEC 136#include <netinet6/ah.h> --- 6 unchanged lines hidden (view full) --- 143#include "md5.h" 144#endif 145 146#define MAXPACKETLEN 131072 147#define IP6LEN 40 148#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 149#define ICMP6ECHOTMLEN sizeof(struct timeval) 150#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) |
147#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) /* 64 bits of nonce + 32 bits ttl */ | 151/* FQDN case, 64 bits of nonce + 32 bits ttl */ 152#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) |
148#define EXTRA 256 /* for AH and various other headers. weird. */ 149#define DEFDATALEN ICMP6ECHOTMLEN 150#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 151#define NROUTES 9 /* number of record route slots */ 152 153#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 154#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 155#define SET(bit) (A(bit) |= B(bit)) 156#define CLR(bit) (A(bit) &= (~B(bit))) 157#define TST(bit) (A(bit) & B(bit)) 158 159#define F_FLOOD 0x0001 160#define F_INTERVAL 0x0002 | 153#define EXTRA 256 /* for AH and various other headers. weird. */ 154#define DEFDATALEN ICMP6ECHOTMLEN 155#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 156#define NROUTES 9 /* number of record route slots */ 157 158#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 159#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 160#define SET(bit) (A(bit) |= B(bit)) 161#define CLR(bit) (A(bit) &= (~B(bit))) 162#define TST(bit) (A(bit) & B(bit)) 163 164#define F_FLOOD 0x0001 165#define F_INTERVAL 0x0002 |
161#define F_NUMERIC 0x0004 | |
162#define F_PINGFILLED 0x0008 163#define F_QUIET 0x0010 164#define F_RROUTE 0x0020 165#define F_SO_DEBUG 0x0040 166#define F_VERBOSE 0x0100 167#ifdef IPSEC 168#ifdef IPSEC_POLICY_IPSEC 169#define F_POLICY 0x0400 --- 7 unchanged lines hidden (view full) --- 177#define F_INTERFACE 0x2000 178#define F_SRCADDR 0x4000 179#ifdef IPV6_REACHCONF 180#define F_REACHCONF 0x8000 181#endif 182#define F_HOSTNAME 0x10000 183#define F_FQDNOLD 0x20000 184#define F_NIGROUP 0x40000 | 166#define F_PINGFILLED 0x0008 167#define F_QUIET 0x0010 168#define F_RROUTE 0x0020 169#define F_SO_DEBUG 0x0040 170#define F_VERBOSE 0x0100 171#ifdef IPSEC 172#ifdef IPSEC_POLICY_IPSEC 173#define F_POLICY 0x0400 --- 7 unchanged lines hidden (view full) --- 181#define F_INTERFACE 0x2000 182#define F_SRCADDR 0x4000 183#ifdef IPV6_REACHCONF 184#define F_REACHCONF 0x8000 185#endif 186#define F_HOSTNAME 0x10000 187#define F_FQDNOLD 0x20000 188#define F_NIGROUP 0x40000 |
189#define F_SUPTYPES 0x80000 190#define F_NOMINMTU 0x100000 191#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES) |
|
185u_int options; 186 187#define IN6LEN sizeof(struct in6_addr) 188#define SA6LEN sizeof(struct sockaddr_in6) | 192u_int options; 193 194#define IN6LEN sizeof(struct in6_addr) 195#define SA6LEN sizeof(struct sockaddr_in6) |
189#define DUMMY_PORT 10101 | 196#define DUMMY_PORT 10101 |
190 | 197 |
191#define SIN6(s) ((struct sockaddr_in6 *)(s)) | 198#define SIN6(s) ((struct sockaddr_in6 *)(s)) |
192 193/* 194 * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum 195 * number of received sequence numbers we can keep track of. Change 128 196 * to 8192 for complete accuracy... 197 */ 198#define MAX_DUP_CHK (8 * 8192) 199int mx_dup_ck = MAX_DUP_CHK; 200char rcvd_tbl[MAX_DUP_CHK / 8]; 201 | 199 200/* 201 * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum 202 * number of received sequence numbers we can keep track of. Change 128 203 * to 8192 for complete accuracy... 204 */ 205#define MAX_DUP_CHK (8 * 8192) 206int mx_dup_ck = MAX_DUP_CHK; 207char rcvd_tbl[MAX_DUP_CHK / 8]; 208 |
202struct addrinfo *res; 203struct sockaddr_in6 dst; /* who to ping6 */ 204struct sockaddr_in6 src; /* src addr of this packet */ | 209struct addrinfo *res; 210struct sockaddr_in6 dst; /* who to ping6 */ 211struct sockaddr_in6 src; /* src addr of this packet */ |
205int datalen = DEFDATALEN; 206int s; /* socket file descriptor */ 207u_char outpack[MAXPACKETLEN]; 208char BSPACE = '\b'; /* characters written for flood */ 209char DOT = '.'; 210char *hostname; 211int ident; /* process id to identify our packets */ | 212int datalen = DEFDATALEN; 213int s; /* socket file descriptor */ 214u_char outpack[MAXPACKETLEN]; 215char BSPACE = '\b'; /* characters written for flood */ 216char DOT = '.'; 217char *hostname; 218int ident; /* process id to identify our packets */ |
219u_int8_t nonce[8]; /* nonce field for node information */ |
|
212struct in6_addr srcaddr; | 220struct in6_addr srcaddr; |
221int hoplimit = -1; /* hoplimit */ 222int pathmtu = 0; /* path MTU for the destination. 0 = unspec. */ |
|
213 214/* counters */ 215long npackets; /* max packets to transmit */ 216long nreceived; /* # of packets we got back */ 217long nrepeats; /* number of duplicates */ 218long ntransmitted; /* sequence # for outbound packets = #sent */ | 223 224/* counters */ 225long npackets; /* max packets to transmit */ 226long nreceived; /* # of packets we got back */ 227long nrepeats; /* number of duplicates */ 228long ntransmitted; /* sequence # for outbound packets = #sent */ |
219int interval = 1; /* interval between packets */ 220int hoplimit = -1; /* hoplimit */ | 229struct timeval interval = {1, 0}; /* interval between packets */ |
221 222/* timing */ 223int timing; /* flag to do timing */ 224double tmin = 999999999.0; /* minimum round trip time */ 225double tmax = 0.0; /* maximum round trip time */ 226double tsum = 0.0; /* sum of all times, for doing average */ | 230 231/* timing */ 232int timing; /* flag to do timing */ 233double tmin = 999999999.0; /* minimum round trip time */ 234double tmax = 0.0; /* maximum round trip time */ 235double tsum = 0.0; /* sum of all times, for doing average */ |
236#if defined(__OpenBSD__) || defined(__NetBSD__) 237double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ 238#endif |
|
227 228/* for node addresses */ 229u_short naflags; 230 231/* for ancillary data(advanced API) */ 232struct msghdr smsghdr; 233struct iovec smsgiov; 234char *scmsg = 0; 235 | 239 240/* for node addresses */ 241u_short naflags; 242 243/* for ancillary data(advanced API) */ 244struct msghdr smsghdr; 245struct iovec smsgiov; 246char *scmsg = 0; 247 |
248volatile int signo; 249volatile sig_atomic_t seenalrm; 250volatile sig_atomic_t seenint; 251#ifdef SIGINFO 252volatile sig_atomic_t seeninfo; 253#endif 254 |
|
236int main __P((int, char *[])); 237void fill __P((char *, char *)); 238int get_hoplim __P((struct msghdr *)); | 255int main __P((int, char *[])); 256void fill __P((char *, char *)); 257int get_hoplim __P((struct msghdr *)); |
258int get_pathmtu __P((struct msghdr *)); 259void set_pathmtu __P((int)); |
|
239struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *)); | 260struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *)); |
240void onalrm __P((int)); 241void oninfo __P((int)); | 261void onsignal __P((int)); 262void retransmit __P((void)); |
242void onint __P((int)); | 263void onint __P((int)); |
264size_t pingerlen __P((void)); |
|
243void pinger __P((void)); | 265void pinger __P((void)); |
244const char *pr_addr __P((struct sockaddr_in6 *)); | 266const char *pr_addr __P((struct sockaddr *, int)); |
245void pr_icmph __P((struct icmp6_hdr *, u_char *)); 246void pr_iph __P((struct ip6_hdr *)); | 267void pr_icmph __P((struct icmp6_hdr *, u_char *)); 268void pr_iph __P((struct ip6_hdr *)); |
269void pr_suptypes __P((struct icmp6_nodeinfo *, size_t)); |
|
247void pr_nodeaddr __P((struct icmp6_nodeinfo *, int)); | 270void pr_nodeaddr __P((struct icmp6_nodeinfo *, int)); |
271int myechoreply __P((const struct icmp6_hdr *)); 272int mynireply __P((const struct icmp6_nodeinfo *)); 273char *dnsdecode __P((const u_char **, const u_char *, const u_char *, 274 u_char *, size_t)); |
|
248void pr_pack __P((u_char *, int, struct msghdr *)); 249void pr_exthdrs __P((struct msghdr *)); 250void pr_ip6opt __P((void *)); 251void pr_rthdr __P((void *)); | 275void pr_pack __P((u_char *, int, struct msghdr *)); 276void pr_exthdrs __P((struct msghdr *)); 277void pr_ip6opt __P((void *)); 278void pr_rthdr __P((void *)); |
279int pr_bitrange __P((u_int32_t, int, int)); |
|
252void pr_retip __P((struct ip6_hdr *, u_char *)); 253void summary __P((void)); 254void tvsub __P((struct timeval *, struct timeval *)); 255int setpolicy __P((int, char *)); 256char *nigroup __P((char *)); 257void usage __P((void)); 258 259int 260main(argc, argv) 261 int argc; 262 char *argv[]; 263{ 264 struct itimerval itimer; 265 struct sockaddr_in6 from; | 280void pr_retip __P((struct ip6_hdr *, u_char *)); 281void summary __P((void)); 282void tvsub __P((struct timeval *, struct timeval *)); 283int setpolicy __P((int, char *)); 284char *nigroup __P((char *)); 285void usage __P((void)); 286 287int 288main(argc, argv) 289 int argc; 290 char *argv[]; 291{ 292 struct itimerval itimer; 293 struct sockaddr_in6 from; |
266 struct timeval timeout; | 294 struct timeval timeout, *tv; |
267 struct addrinfo hints; 268 fd_set *fdmaskp; 269 int fdmasks; 270 register int cc, i; 271 int ch, fromlen, hold, packlen, preload, optval, ret_ga; 272 u_char *datap, *packet; 273 char *e, *target, *ifname = NULL; 274 int ip6optlen = 0; 275 struct cmsghdr *scmsgp = NULL; 276 int sockbufsize = 0; 277 int usepktinfo = 0; 278 struct in6_pktinfo *pktinfo = NULL; 279#ifdef USE_RFC2292BIS 280 struct ip6_rthdr *rthdr = NULL; 281#endif 282#ifdef IPSEC_POLICY_IPSEC 283 char *policy_in = NULL; 284 char *policy_out = NULL; 285#endif | 295 struct addrinfo hints; 296 fd_set *fdmaskp; 297 int fdmasks; 298 register int cc, i; 299 int ch, fromlen, hold, packlen, preload, optval, ret_ga; 300 u_char *datap, *packet; 301 char *e, *target, *ifname = NULL; 302 int ip6optlen = 0; 303 struct cmsghdr *scmsgp = NULL; 304 int sockbufsize = 0; 305 int usepktinfo = 0; 306 struct in6_pktinfo *pktinfo = NULL; 307#ifdef USE_RFC2292BIS 308 struct ip6_rthdr *rthdr = NULL; 309#endif 310#ifdef IPSEC_POLICY_IPSEC 311 char *policy_in = NULL; 312 char *policy_out = NULL; 313#endif |
314 double intval; 315 size_t rthlen; |
|
286 287 /* just to be sure */ 288 memset(&smsghdr, 0, sizeof(&smsghdr)); 289 memset(&smsgiov, 0, sizeof(&smsgiov)); 290 291 preload = 0; 292 datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; 293#ifndef IPSEC | 316 317 /* just to be sure */ 318 memset(&smsghdr, 0, sizeof(&smsghdr)); 319 memset(&smsgiov, 0, sizeof(&smsgiov)); 320 321 preload = 0; 322 datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; 323#ifndef IPSEC |
294 while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwW")) != EOF) | 324#define ADDOPTS |
295#else 296#ifdef IPSEC_POLICY_IPSEC | 325#else 326#ifdef IPSEC_POLICY_IPSEC |
297 while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwWP:")) != EOF) | 327#define ADDOPTS "P:" |
298#else | 328#else |
299 while ((ch = getopt(argc, argv, "a:b:c:dfHh:I:i:l:nNp:qRS:s:vwWAE")) != EOF) | 329#define ADDOPTS "AE" |
300#endif /*IPSEC_POLICY_IPSEC*/ 301#endif | 330#endif /*IPSEC_POLICY_IPSEC*/ 331#endif |
302 { 303 switch(ch) { 304 case 'a': 305 { 306 char *cp; | 332 while ((ch = getopt(argc, argv, 333 "a:b:c:dfHh:I:i:l:mnNp:qRS:s:tvwW" ADDOPTS)) != -1) { 334#undef ADDOPTS 335 switch (ch) { 336 case 'a': 337 { 338 char *cp; |
307 | 339 |
308 options |= F_NODEADDR; 309 datalen = 2048; /* XXX: enough? */ 310 for (cp = optarg; *cp != '\0'; cp++) { 311 switch(*cp) { 312 case 'a': 313 naflags |= NI_NODEADDR_FLAG_ALL; 314 break; 315 case 'c': 316 case 'C': 317 naflags |= NI_NODEADDR_FLAG_COMPAT; 318 break; 319 case 'l': 320 case 'L': 321 naflags |= NI_NODEADDR_FLAG_LINKLOCAL; 322 break; 323 case 's': 324 case 'S': 325 naflags |= NI_NODEADDR_FLAG_SITELOCAL; 326 break; 327 case 'g': 328 case 'G': 329 naflags |= NI_NODEADDR_FLAG_GLOBAL; 330 break; 331 case 'A': /* experimental. not in the spec */ 332 naflags |= NI_NODEADDR_FLAG_ANYCAST; 333 break; 334 default: 335 usage(); 336 /*NOTREACHED*/ 337 } 338 } 339 break; 340 } 341 case 'b': | 340 options &= ~F_NOUSERDATA; 341 options |= F_NODEADDR; 342 for (cp = optarg; *cp != '\0'; cp++) { 343 switch (*cp) { 344 case 'a': 345 naflags |= NI_NODEADDR_FLAG_ALL; 346 break; 347 case 'c': 348 case 'C': 349 naflags |= NI_NODEADDR_FLAG_COMPAT; 350 break; 351 case 'l': 352 case 'L': 353 naflags |= NI_NODEADDR_FLAG_LINKLOCAL; 354 break; 355 case 's': 356 case 'S': 357 naflags |= NI_NODEADDR_FLAG_SITELOCAL; 358 break; 359 case 'g': 360 case 'G': 361 naflags |= NI_NODEADDR_FLAG_GLOBAL; 362 break; 363 case 'A': /* experimental. not in the spec */ 364#ifdef NI_NODEADDR_FLAG_ANYCAST 365 naflags |= NI_NODEADDR_FLAG_ANYCAST; 366 break; 367#else 368 errx(1, 369"-a A is not supported on the platform"); 370 /*NOTREACHED*/ 371#endif 372 default: 373 usage(); 374 /*NOTREACHED*/ 375 } 376 } 377 break; 378 } 379 case 'b': |
342#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 343 sockbufsize = atoi(optarg); 344#else 345 err(1, 346"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported"); 347#endif 348 break; 349 case 'c': --- 25 unchanged lines hidden (view full) --- 375 case 'I': 376 ifname = optarg; 377 options |= F_INTERFACE; 378#ifndef USE_SIN6_SCOPE_ID 379 usepktinfo++; 380#endif 381 break; 382 case 'i': /* wait between sending packets */ | 380#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 381 sockbufsize = atoi(optarg); 382#else 383 err(1, 384"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported"); 385#endif 386 break; 387 case 'c': --- 25 unchanged lines hidden (view full) --- 413 case 'I': 414 ifname = optarg; 415 options |= F_INTERFACE; 416#ifndef USE_SIN6_SCOPE_ID 417 usepktinfo++; 418#endif 419 break; 420 case 'i': /* wait between sending packets */ |
383 interval = strtol(optarg, &e, 10); 384 if (interval <= 0 || *optarg == '\0' || *e != '\0') 385 errx(1, 386 "illegal timing interval -- %s", optarg); | 421 intval = strtod(optarg, &e); 422 if (*optarg == '\0' || *e != '\0') 423 errx(1, "illegal timing interval %s", optarg); 424 if (intval < 1 && getuid()) { 425 errx(1, "%s: only root may use interval < 1s", 426 strerror(EPERM)); 427 } 428 interval.tv_sec = (long)intval; 429 interval.tv_usec = 430 (long)((intval - interval.tv_sec) * 1000000); 431 if (interval.tv_sec < 0) 432 errx(1, "illegal timing interval %s", optarg); 433 /* less than 1/hz does not make sense */ 434 if (interval.tv_sec == 0 && interval.tv_usec < 10000) { 435 warnx("too small interval, raised to 0.01"); 436 interval.tv_usec = 10000; 437 } |
387 options |= F_INTERVAL; 388 break; 389 case 'l': 390 if (getuid()) { 391 errno = EPERM; 392 errx(1, "Must be superuser to preload"); 393 } 394 preload = strtol(optarg, &e, 10); 395 if (preload < 0 || *optarg == '\0' || *e != '\0') 396 errx(1, "illegal preload value -- %s", optarg); 397 break; | 438 options |= F_INTERVAL; 439 break; 440 case 'l': 441 if (getuid()) { 442 errno = EPERM; 443 errx(1, "Must be superuser to preload"); 444 } 445 preload = strtol(optarg, &e, 10); 446 if (preload < 0 || *optarg == '\0' || *e != '\0') 447 errx(1, "illegal preload value -- %s", optarg); 448 break; |
449 case 'm': 450#ifdef IPV6_USE_MIN_MTU 451 options |= F_NOMINMTU; 452 break; 453#else 454 errx(1, "-%c is not supported on this platform", ch); 455 /*NOTREACHED*/ 456#endif |
|
398 case 'n': | 457 case 'n': |
399 options |= F_NUMERIC; | 458 options &= ~F_HOSTNAME; |
400 break; 401 case 'N': 402 options |= F_NIGROUP; 403 break; 404 case 'p': /* fill buffer with user pattern */ 405 options |= F_PINGFILLED; 406 fill((char *)datap, optarg); 407 break; --- 13 unchanged lines hidden (view full) --- 421 errx(1, "invalid IPv6 address: %s", optarg); 422 options |= F_SRCADDR; 423 usepktinfo++; 424 break; 425 case 's': /* size of packet to send */ 426 datalen = strtol(optarg, &e, 10); 427 if (datalen <= 0 || *optarg == '\0' || *e != '\0') 428 errx(1, "illegal datalen value -- %s", optarg); | 459 break; 460 case 'N': 461 options |= F_NIGROUP; 462 break; 463 case 'p': /* fill buffer with user pattern */ 464 options |= F_PINGFILLED; 465 fill((char *)datap, optarg); 466 break; --- 13 unchanged lines hidden (view full) --- 480 errx(1, "invalid IPv6 address: %s", optarg); 481 options |= F_SRCADDR; 482 usepktinfo++; 483 break; 484 case 's': /* size of packet to send */ 485 datalen = strtol(optarg, &e, 10); 486 if (datalen <= 0 || *optarg == '\0' || *e != '\0') 487 errx(1, "illegal datalen value -- %s", optarg); |
429 if (datalen > MAXDATALEN) | 488 if (datalen > MAXDATALEN) { |
430 errx(1, 431 "datalen value too large, maximum is %d", 432 MAXDATALEN); | 489 errx(1, 490 "datalen value too large, maximum is %d", 491 MAXDATALEN); |
492 } |
|
433 break; | 493 break; |
494 case 't': 495 options &= ~F_NOUSERDATA; 496 options |= F_SUPTYPES; 497 break; |
|
434 case 'v': 435 options |= F_VERBOSE; 436 break; 437 case 'w': | 498 case 'v': 499 options |= F_VERBOSE; 500 break; 501 case 'w': |
502 options &= ~F_NOUSERDATA; |
|
438 options |= F_FQDN; 439 break; 440 case 'W': | 503 options |= F_FQDN; 504 break; 505 case 'W': |
506 options &= ~F_NOUSERDATA; |
|
441 options |= F_FQDNOLD; 442 break; 443#ifdef IPSEC 444#ifdef IPSEC_POLICY_IPSEC 445 case 'P': 446 options |= F_POLICY; 447 if (!strncmp("in", optarg, 2)) { 448 if ((policy_in = strdup(optarg)) == NULL) --- 22 unchanged lines hidden (view full) --- 471 argv += optind; 472 473 if (argc < 1) { 474 usage(); 475 /*NOTREACHED*/ 476 } 477 478 if (argc > 1) { | 507 options |= F_FQDNOLD; 508 break; 509#ifdef IPSEC 510#ifdef IPSEC_POLICY_IPSEC 511 case 'P': 512 options |= F_POLICY; 513 if (!strncmp("in", optarg, 2)) { 514 if ((policy_in = strdup(optarg)) == NULL) --- 22 unchanged lines hidden (view full) --- 537 argv += optind; 538 539 if (argc < 1) { 540 usage(); 541 /*NOTREACHED*/ 542 } 543 544 if (argc > 1) { |
479#ifdef USE_SIN6_SCOPE_ID 480 ip6optlen += CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1)); 481#else /* old advanced API */ 482 ip6optlen += inet6_rthdr_space(IPV6_RTHDR_TYPE_0, argc - 1); | 545#ifdef IPV6_RECVRTHDR /* 2292bis */ 546 rthlen = CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0, 547 argc - 1)); 548#else /* RFC2292 */ 549 rthlen = inet6_rthdr_space(IPV6_RTHDR_TYPE_0, argc - 1); |
483#endif | 550#endif |
551 if (rthlen == 0) { 552 errx(1, "too many intermediate hops"); 553 /*NOTREACHED*/ 554 } 555 ip6optlen += rthlen; |
|
484 } 485 486 if (options & F_NIGROUP) { 487 target = nigroup(argv[argc - 1]); 488 if (target == NULL) { 489 usage(); 490 /*NOTREACHED*/ 491 } 492 } else 493 target = argv[argc - 1]; 494 495 /* getaddrinfo */ 496 bzero(&hints, sizeof(struct addrinfo)); | 556 } 557 558 if (options & F_NIGROUP) { 559 target = nigroup(argv[argc - 1]); 560 if (target == NULL) { 561 usage(); 562 /*NOTREACHED*/ 563 } 564 } else 565 target = argv[argc - 1]; 566 567 /* getaddrinfo */ 568 bzero(&hints, sizeof(struct addrinfo)); |
497 if ((options & F_NUMERIC) != 0) 498 hints.ai_flags = AI_CANONNAME; | 569 hints.ai_flags = AI_CANONNAME; |
499 hints.ai_family = AF_INET6; 500 hints.ai_socktype = SOCK_RAW; 501 hints.ai_protocol = IPPROTO_ICMPV6; 502 503 ret_ga = getaddrinfo(target, NULL, &hints, &res); 504 if (ret_ga) { 505 fprintf(stderr, "ping6: %s\n", gai_strerror(ret_ga)); 506 exit(1); 507 } 508 if (res->ai_canonname) 509 hostname = res->ai_canonname; 510 else 511 hostname = target; | 570 hints.ai_family = AF_INET6; 571 hints.ai_socktype = SOCK_RAW; 572 hints.ai_protocol = IPPROTO_ICMPV6; 573 574 ret_ga = getaddrinfo(target, NULL, &hints, &res); 575 if (ret_ga) { 576 fprintf(stderr, "ping6: %s\n", gai_strerror(ret_ga)); 577 exit(1); 578 } 579 if (res->ai_canonname) 580 hostname = res->ai_canonname; 581 else 582 hostname = target; |
512 | 583 |
513 if (!res->ai_addr) 514 errx(1, "getaddrinfo failed"); 515 516 (void)memcpy(&dst, res->ai_addr, res->ai_addrlen); 517 | 584 if (!res->ai_addr) 585 errx(1, "getaddrinfo failed"); 586 587 (void)memcpy(&dst, res->ai_addr, res->ai_addrlen); 588 |
589 if ((s = socket(res->ai_family, res->ai_socktype, 590 res->ai_protocol)) < 0) 591 err(1, "socket"); 592 593 /* 594 * let the kerel pass extension headers of incoming packets, 595 * for privileged socket options 596 */ 597 if ((options & F_VERBOSE) != 0) { 598 int opton = 1; 599 600#ifdef IPV6_RECVHOPOPTS 601 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, 602 sizeof(opton))) 603 err(1, "setsockopt(IPV6_RECVHOPOPTS)"); 604#else /* old adv. API */ 605 if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton, 606 sizeof(opton))) 607 err(1, "setsockopt(IPV6_HOPOPTS)"); 608#endif 609#ifdef IPV6_RECVDSTOPTS 610 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, 611 sizeof(opton))) 612 err(1, "setsockopt(IPV6_RECVDSTOPTS)"); 613#else /* old adv. API */ 614 if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton, 615 sizeof(opton))) 616 err(1, "setsockopt(IPV6_DSTOPTS)"); 617#endif 618#ifdef IPV6_RECVRTHDRDSTOPTS 619 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, 620 sizeof(opton))) 621 err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); 622#endif 623 } 624 625 /* revoke root privilege */ 626 seteuid(getuid()); 627 setuid(getuid()); 628 |
|
518 if (options & F_FLOOD && options & F_INTERVAL) 519 errx(1, "-f and -i incompatible options"); 520 | 629 if (options & F_FLOOD && options & F_INTERVAL) 630 errx(1, "-f and -i incompatible options"); 631 |
521 if (datalen >= sizeof(struct timeval)) /* can we time transfer */ 522 timing = 1; 523 packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; | 632 if ((options & F_NOUSERDATA) == 0) { 633 if (datalen >= sizeof(struct timeval)) { 634 /* we can time transfer */ 635 timing = 1; 636 } else 637 timing = 0; 638 /* in F_VERBOSE case, we may get non-echoreply packets*/ 639 if (options & F_VERBOSE) 640 packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 641 else 642 packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; 643 } else { 644 /* suppress timing for node information query */ 645 timing = 0; 646 datalen = 2048; 647 packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 648 } 649 |
524 if (!(packet = (u_char *)malloc((u_int)packlen))) 525 err(1, "Unable to allocate packet"); 526 if (!(options & F_PINGFILLED)) | 650 if (!(packet = (u_char *)malloc((u_int)packlen))) 651 err(1, "Unable to allocate packet"); 652 if (!(options & F_PINGFILLED)) |
527 for (i = 8; i < datalen; ++i) | 653 for (i = ICMP6ECHOLEN; i < packlen; ++i) |
528 *datap++ = i; 529 530 ident = getpid() & 0xFFFF; | 654 *datap++ = i; 655 656 ident = getpid() & 0xFFFF; |
657#ifndef __OpenBSD__ 658 gettimeofday(&timeout, NULL); 659 srand((unsigned int)(timeout.tv_sec ^ timeout.tv_usec ^ (long)ident)); 660 memset(nonce, 0, sizeof(nonce)); 661 for (i = 0; i < sizeof(nonce); i += sizeof(int)) 662 *((int *)&nonce[i]) = rand(); 663#else 664 memset(nonce, 0, sizeof(nonce)); 665 for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t)) 666 *((u_int32_t *)&nonce[i]) = arc4random(); 667#endif |
|
531 | 668 |
532 if ((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) 533 err(1, "socket"); 534 | |
535 hold = 1; 536 537 if (options & F_SO_DEBUG) 538 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, 539 sizeof(hold)); 540 optval = IPV6_DEFHLIM; 541 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 542 if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, | 669 hold = 1; 670 671 if (options & F_SO_DEBUG) 672 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, 673 sizeof(hold)); 674 optval = IPV6_DEFHLIM; 675 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 676 if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, |
543 &optval, sizeof(optval)) == -1) | 677 &optval, sizeof(optval)) == -1) |
544 err(1, "IPV6_MULTICAST_HOPS"); | 678 err(1, "IPV6_MULTICAST_HOPS"); |
679#ifdef IPV6_USE_MIN_MTU 680 if ((options & F_NOMINMTU) == 0) { 681 optval = 1; 682 if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU, 683 &optval, sizeof(optval)) == -1) 684 err(1, "setsockopt(IPV6_USE_MIN_MTU)"); 685 } 686#ifdef IPV6_RECVPATHMTU 687 else { 688 optval = 1; 689 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU, 690 &optval, sizeof(optval)) == -1) 691 err(1, "setsockopt(IPV6_RECVPATHMTU)"); 692 } 693#endif /* IPV6_RECVPATHMTU */ 694#endif /* IPV6_USE_MIN_MTU */ |
|
545 546#ifdef IPSEC 547#ifdef IPSEC_POLICY_IPSEC 548 if (options & F_POLICY) { 549 if (setpolicy(s, policy_in) < 0) 550 errx(1, "%s", ipsec_strerror()); 551 if (setpolicy(s, policy_out) < 0) 552 errx(1, "%s", ipsec_strerror()); 553 } 554#else 555 if (options & F_AUTHHDR) { 556 optval = IPSEC_LEVEL_REQUIRE; 557#ifdef IPV6_AUTH_TRANS_LEVEL 558 if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, | 695 696#ifdef IPSEC 697#ifdef IPSEC_POLICY_IPSEC 698 if (options & F_POLICY) { 699 if (setpolicy(s, policy_in) < 0) 700 errx(1, "%s", ipsec_strerror()); 701 if (setpolicy(s, policy_out) < 0) 702 errx(1, "%s", ipsec_strerror()); 703 } 704#else 705 if (options & F_AUTHHDR) { 706 optval = IPSEC_LEVEL_REQUIRE; 707#ifdef IPV6_AUTH_TRANS_LEVEL 708 if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, |
559 &optval, sizeof(optval)) == -1) | 709 &optval, sizeof(optval)) == -1) |
560 err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); 561#else /* old def */ 562 if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL, | 710 err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); 711#else /* old def */ 712 if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL, |
563 &optval, sizeof(optval)) == -1) | 713 &optval, sizeof(optval)) == -1) |
564 err(1, "setsockopt(IPV6_AUTH_LEVEL)"); 565#endif 566 } 567 if (options & F_ENCRYPT) { 568 optval = IPSEC_LEVEL_REQUIRE; 569 if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, | 714 err(1, "setsockopt(IPV6_AUTH_LEVEL)"); 715#endif 716 } 717 if (options & F_ENCRYPT) { 718 optval = IPSEC_LEVEL_REQUIRE; 719 if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, |
570 &optval, sizeof(optval)) == -1) | 720 &optval, sizeof(optval)) == -1) |
571 err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); 572 } 573#endif /*IPSEC_POLICY_IPSEC*/ 574#endif 575 576#ifdef ICMP6_FILTER 577 { 578 struct icmp6_filter filt; 579 if (!(options & F_VERBOSE)) { 580 ICMP6_FILTER_SETBLOCKALL(&filt); 581 if ((options & F_FQDN) || (options & F_FQDNOLD) || | 721 err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); 722 } 723#endif /*IPSEC_POLICY_IPSEC*/ 724#endif 725 726#ifdef ICMP6_FILTER 727 { 728 struct icmp6_filter filt; 729 if (!(options & F_VERBOSE)) { 730 ICMP6_FILTER_SETBLOCKALL(&filt); 731 if ((options & F_FQDN) || (options & F_FQDNOLD) || |
582 (options & F_NODEADDR)) | 732 (options & F_NODEADDR) || (options & F_SUPTYPES)) |
583 ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); 584 else 585 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); 586 } else { 587 ICMP6_FILTER_SETPASSALL(&filt); 588 } 589 if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, | 733 ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); 734 else 735 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); 736 } else { 737 ICMP6_FILTER_SETPASSALL(&filt); 738 } 739 if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, |
590 sizeof(filt)) < 0) | 740 sizeof(filt)) < 0) |
591 err(1, "setsockopt(ICMP6_FILTER)"); 592 } 593#endif /*ICMP6_FILTER*/ 594 595 /* let the kerel pass extension headers of incoming packets */ | 741 err(1, "setsockopt(ICMP6_FILTER)"); 742 } 743#endif /*ICMP6_FILTER*/ 744 745 /* let the kerel pass extension headers of incoming packets */ |
596 /* TODO: implement parsing routine */ | |
597 if ((options & F_VERBOSE) != 0) { 598 int opton = 1; 599 600#ifdef IPV6_RECVRTHDR 601 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, | 746 if ((options & F_VERBOSE) != 0) { 747 int opton = 1; 748 749#ifdef IPV6_RECVRTHDR 750 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, |
602 sizeof(opton))) | 751 sizeof(opton))) |
603 err(1, "setsockopt(IPV6_RECVRTHDR)"); 604#else /* old adv. API */ 605 if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton, | 752 err(1, "setsockopt(IPV6_RECVRTHDR)"); 753#else /* old adv. API */ 754 if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton, |
606 sizeof(opton))) | 755 sizeof(opton))) |
607 err(1, "setsockopt(IPV6_RTHDR)"); 608#endif | 756 err(1, "setsockopt(IPV6_RTHDR)"); 757#endif |
609#ifdef IPV6_RECVHOPOPTS 610 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, 611 sizeof(opton))) 612 err(1, "setsockopt(IPV6_RECVHOPOPTS)"); 613#else /* old adv. API */ 614 if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton, 615 sizeof(opton))) 616 err(1, "setsockopt(IPV6_HOPOPTS)"); 617#endif 618#ifdef IPV6_RECVDSTOPTS 619 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, 620 sizeof(opton))) 621 err(1, "setsockopt(IPV6_RECVDSTOPTS)"); 622#else /* olad adv. API */ 623 if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton, 624 sizeof(opton))) 625 err(1, "setsockopt(IPV6_DSTOPTS)"); 626#endif 627#ifdef IPV6_RECVRTHDRDSTOPTS 628 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, 629 sizeof(opton))) 630 err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); 631#endif | |
632 } 633 634/* 635 optval = 1; 636 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 637 if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, | 758 } 759 760/* 761 optval = 1; 762 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 763 if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, |
638 &optval, sizeof(optval)) == -1) | 764 &optval, sizeof(optval)) == -1) |
639 err(1, "IPV6_MULTICAST_LOOP"); 640*/ 641 642 /* Specify the outgoing interface and/or the source address */ 643 if (usepktinfo) 644 ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); 645 646 if (hoplimit != -1) --- 21 unchanged lines hidden (view full) --- 668 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 669 } 670 671 /* set the outgoing interface */ 672 if (ifname) { 673#ifndef USE_SIN6_SCOPE_ID 674 /* pktinfo must have already been allocated */ 675 if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0) | 765 err(1, "IPV6_MULTICAST_LOOP"); 766*/ 767 768 /* Specify the outgoing interface and/or the source address */ 769 if (usepktinfo) 770 ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); 771 772 if (hoplimit != -1) --- 21 unchanged lines hidden (view full) --- 794 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 795 } 796 797 /* set the outgoing interface */ 798 if (ifname) { 799#ifndef USE_SIN6_SCOPE_ID 800 /* pktinfo must have already been allocated */ 801 if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0) |
676 errx(1, "%s: invalid interface name", ifname); | 802 errx(1, "%s: invalid interface name", ifname); |
677#else 678 if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0) 679 errx(1, "%s: invalid interface name", ifname); 680#endif 681 } 682 /* set the source address */ 683 if (options & F_SRCADDR)/* pktinfo must be valid */ 684 pktinfo->ipi6_addr = srcaddr; --- 24 unchanged lines hidden (view full) --- 709 710#ifdef USE_RFC2292BIS 711 rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1); 712 scmsgp->cmsg_len = CMSG_LEN(rthdrlen); 713 scmsgp->cmsg_level = IPPROTO_IPV6; 714 scmsgp->cmsg_type = IPV6_RTHDR; 715 rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp); 716 rthdr = inet6_rth_init((void *)rthdr, rthdrlen, | 803#else 804 if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0) 805 errx(1, "%s: invalid interface name", ifname); 806#endif 807 } 808 /* set the source address */ 809 if (options & F_SRCADDR)/* pktinfo must be valid */ 810 pktinfo->ipi6_addr = srcaddr; --- 24 unchanged lines hidden (view full) --- 835 836#ifdef USE_RFC2292BIS 837 rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1); 838 scmsgp->cmsg_len = CMSG_LEN(rthdrlen); 839 scmsgp->cmsg_level = IPPROTO_IPV6; 840 scmsgp->cmsg_type = IPV6_RTHDR; 841 rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp); 842 rthdr = inet6_rth_init((void *)rthdr, rthdrlen, |
717 IPV6_RTHDR_TYPE_0, argc - 1); | 843 IPV6_RTHDR_TYPE_0, argc - 1); |
718 if (rthdr == NULL) 719 errx(1, "can't initialize rthdr"); 720#else /* old advanced API */ 721 if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp, | 844 if (rthdr == NULL) 845 errx(1, "can't initialize rthdr"); 846#else /* old advanced API */ 847 if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp, |
722 IPV6_RTHDR_TYPE_0)) == 0) | 848 IPV6_RTHDR_TYPE_0)) == 0) |
723 errx(1, "can't initialize rthdr"); 724#endif /* USE_RFC2292BIS */ 725 726 for (hops = 0; hops < argc - 1; hops++) { 727 struct addrinfo *iaip; 728 | 849 errx(1, "can't initialize rthdr"); 850#endif /* USE_RFC2292BIS */ 851 852 for (hops = 0; hops < argc - 1; hops++) { 853 struct addrinfo *iaip; 854 |
729 if ((error = getaddrinfo(argv[hops], NULL, &hints, &iaip))) | 855 if ((error = getaddrinfo(argv[hops], NULL, &hints, 856 &iaip))) |
730 errx(1, "%s", gai_strerror(error)); | 857 errx(1, "%s", gai_strerror(error)); |
731 if (SIN6(res->ai_addr)->sin6_family != AF_INET6) | 858 if (SIN6(iaip->ai_addr)->sin6_family != AF_INET6) |
732 errx(1, | 859 errx(1, |
733 "bad addr family of an intermediate addr"); | 860 "bad addr family of an intermediate addr"); |
734 735#ifdef USE_RFC2292BIS 736 if (inet6_rth_add(rthdr, | 861 862#ifdef USE_RFC2292BIS 863 if (inet6_rth_add(rthdr, |
737 &(SIN6(iaip->ai_addr))->sin6_addr)) | 864 &(SIN6(iaip->ai_addr))->sin6_addr)) |
738 errx(1, "can't add an intermediate node"); 739#else /* old advanced API */ 740 if (inet6_rthdr_add(scmsgp, | 865 errx(1, "can't add an intermediate node"); 866#else /* old advanced API */ 867 if (inet6_rthdr_add(scmsgp, |
741 &(SIN6(iaip->ai_addr))->sin6_addr, 742 IPV6_RTHDR_LOOSE)) | 868 &(SIN6(iaip->ai_addr))->sin6_addr, 869 IPV6_RTHDR_LOOSE)) |
743 errx(1, "can't add an intermediate node"); 744#endif /* USE_RFC2292BIS */ | 870 errx(1, "can't add an intermediate node"); 871#endif /* USE_RFC2292BIS */ |
872 freeaddrinfo(iaip); |
|
745 } 746 747#ifndef USE_RFC2292BIS 748 if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE)) 749 errx(1, "can't set the last flag"); 750#endif 751 752 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 753 } 754 755 { 756 /* 757 * source selection 758 */ 759 int dummy, len = sizeof(src); | 873 } 874 875#ifndef USE_RFC2292BIS 876 if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE)) 877 errx(1, "can't set the last flag"); 878#endif 879 880 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 881 } 882 883 { 884 /* 885 * source selection 886 */ 887 int dummy, len = sizeof(src); |
760 | 888 |
761 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 762 err(1, "UDP socket"); 763 764 src.sin6_family = AF_INET6; 765 src.sin6_addr = dst.sin6_addr; 766 src.sin6_port = ntohs(DUMMY_PORT); 767 src.sin6_scope_id = dst.sin6_scope_id; 768 | 889 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 890 err(1, "UDP socket"); 891 892 src.sin6_family = AF_INET6; 893 src.sin6_addr = dst.sin6_addr; 894 src.sin6_port = ntohs(DUMMY_PORT); 895 src.sin6_scope_id = dst.sin6_scope_id; 896 |
769 770#ifdef USE_SIN6_SCOPE_ID 771 src.sin6_scope_id = dst.sin6_scope_id; 772#endif 773 | |
774#ifdef USE_RFC2292BIS 775 if (pktinfo && 776 setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, | 897#ifdef USE_RFC2292BIS 898 if (pktinfo && 899 setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, |
777 (void *)pktinfo, sizeof(*pktinfo))) | 900 (void *)pktinfo, sizeof(*pktinfo))) |
778 err(1, "UDP setsockopt(IPV6_PKTINFO)"); 779 780 if (hoplimit != -1 && 781 setsockopt(dummy, IPPROTO_IPV6, IPV6_HOPLIMIT, | 901 err(1, "UDP setsockopt(IPV6_PKTINFO)"); 902 903 if (hoplimit != -1 && 904 setsockopt(dummy, IPPROTO_IPV6, IPV6_HOPLIMIT, |
782 (void *)&hoplimit, sizeof(hoplimit))) | 905 (void *)&hoplimit, sizeof(hoplimit))) |
783 err(1, "UDP setsockopt(IPV6_HOPLIMIT)"); 784 785 if (rthdr && 786 setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, | 906 err(1, "UDP setsockopt(IPV6_HOPLIMIT)"); 907 908 if (rthdr && 909 setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, |
787 (void *)rthdr, (rthdr->ip6r_len + 1) << 3)) | 910 (void *)rthdr, (rthdr->ip6r_len + 1) << 3)) |
788 err(1, "UDP setsockopt(IPV6_RTHDR)"); 789#else /* old advanced API */ 790 if (smsghdr.msg_control && 791 setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTOPTIONS, | 911 err(1, "UDP setsockopt(IPV6_RTHDR)"); 912#else /* old advanced API */ 913 if (smsghdr.msg_control && 914 setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTOPTIONS, |
792 (void *)smsghdr.msg_control, 793 smsghdr.msg_controllen)) { | 915 (void *)smsghdr.msg_control, smsghdr.msg_controllen)) |
794 err(1, "UDP setsockopt(IPV6_PKTOPTIONS)"); | 916 err(1, "UDP setsockopt(IPV6_PKTOPTIONS)"); |
795 } | |
796#endif | 917#endif |
797 | 918 |
798 if (connect(dummy, (struct sockaddr *)&src, len) < 0) 799 err(1, "UDP connect"); | 919 if (connect(dummy, (struct sockaddr *)&src, len) < 0) 920 err(1, "UDP connect"); |
800 | 921 |
801 if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) 802 err(1, "getsockname"); 803 804 close(dummy); 805 } 806 807#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 808 if (sockbufsize) { 809 if (datalen > sockbufsize) 810 warnx("you need -b to increase socket buffer size"); 811 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, | 922 if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) 923 err(1, "getsockname"); 924 925 close(dummy); 926 } 927 928#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 929 if (sockbufsize) { 930 if (datalen > sockbufsize) 931 warnx("you need -b to increase socket buffer size"); 932 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, |
812 sizeof(sockbufsize)) < 0) | 933 sizeof(sockbufsize)) < 0) |
813 err(1, "setsockopt(SO_SNDBUF)"); 814 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize, | 934 err(1, "setsockopt(SO_SNDBUF)"); 935 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize, |
815 sizeof(sockbufsize)) < 0) | 936 sizeof(sockbufsize)) < 0) |
816 err(1, "setsockopt(SO_RCVBUF)"); 817 } 818 else { 819 if (datalen > 8 * 1024) /*XXX*/ 820 warnx("you need -b to increase socket buffer size"); 821 /* 822 * When pinging the broadcast address, you can get a lot of 823 * answers. Doing something so evil is useful if you are trying 824 * to stress the ethernet, or just want to fill the arp cache 825 * to get some stuff for /etc/ethers. 826 */ 827 hold = 48 * 1024; | 937 err(1, "setsockopt(SO_RCVBUF)"); 938 } 939 else { 940 if (datalen > 8 * 1024) /*XXX*/ 941 warnx("you need -b to increase socket buffer size"); 942 /* 943 * When pinging the broadcast address, you can get a lot of 944 * answers. Doing something so evil is useful if you are trying 945 * to stress the ethernet, or just want to fill the arp cache 946 * to get some stuff for /etc/ethers. 947 */ 948 hold = 48 * 1024; |
828 setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold)); | 949 setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold, 950 sizeof(hold)); |
829 } 830#endif 831 832 optval = 1; 833#ifndef USE_SIN6_SCOPE_ID 834#ifdef IPV6_RECVPKTINFO 835 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, | 951 } 952#endif 953 954 optval = 1; 955#ifndef USE_SIN6_SCOPE_ID 956#ifdef IPV6_RECVPKTINFO 957 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, |
836 sizeof(optval)) < 0) | 958 sizeof(optval)) < 0) |
837 warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ 838#else /* old adv. API */ 839 if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval, | 959 warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ 960#else /* old adv. API */ 961 if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval, |
840 sizeof(optval)) < 0) | 962 sizeof(optval)) < 0) |
841 warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */ 842#endif 843#endif /* USE_SIN6_SCOPE_ID */ 844#ifdef IPV6_RECVHOPLIMIT 845 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, | 963 warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */ 964#endif 965#endif /* USE_SIN6_SCOPE_ID */ 966#ifdef IPV6_RECVHOPLIMIT 967 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, |
846 sizeof(optval)) < 0) | 968 sizeof(optval)) < 0) |
847 warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ 848#else /* old adv. API */ 849 if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, | 969 warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ 970#else /* old adv. API */ 971 if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, |
850 sizeof(optval)) < 0) | 972 sizeof(optval)) < 0) |
851 warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ 852#endif 853 | 973 warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ 974#endif 975 |
854 printf("PING6(%d=40+8+%d bytes) ", datalen + 48, datalen); 855 printf("%s --> ", pr_addr(&src)); 856 printf("%s\n", pr_addr(&dst)); | 976 printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), 977 (unsigned long)(pingerlen() - 8)); 978 printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); 979 printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); |
857 858 while (preload--) /* Fire off them quickies. */ 859 pinger(); 860 | 980 981 while (preload--) /* Fire off them quickies. */ 982 pinger(); 983 |
861 (void)signal(SIGINT, onint); 862 (void)signal(SIGINFO, oninfo); | 984 (void)signal(SIGINT, onsignal); 985#ifdef SIGINFO 986 (void)signal(SIGINFO, onsignal); 987#endif |
863 864 if ((options & F_FLOOD) == 0) { | 988 989 if ((options & F_FLOOD) == 0) { |
865 (void)signal(SIGALRM, onalrm); 866 itimer.it_interval.tv_sec = interval; 867 itimer.it_interval.tv_usec = 0; 868 itimer.it_value.tv_sec = 0; 869 itimer.it_value.tv_usec = 1; | 990 (void)signal(SIGALRM, onsignal); 991 itimer.it_interval = interval; 992 itimer.it_value = interval; |
870 (void)setitimer(ITIMER_REAL, &itimer, NULL); | 993 (void)setitimer(ITIMER_REAL, &itimer, NULL); |
994 retransmit(); |
|
871 } 872 | 995 } 996 |
873 fdmasks = howmany(s+1, NFDBITS); | 997 fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask); |
874 if ((fdmaskp = malloc(fdmasks)) == NULL) 875 err(1, "malloc"); 876 | 998 if ((fdmaskp = malloc(fdmasks)) == NULL) 999 err(1, "malloc"); 1000 |
1001 signo = seenalrm = seenint = 0; 1002#ifdef SIGINFO 1003 seeninfo = 0; 1004#endif 1005 |
|
877 for (;;) { 878 struct msghdr m; 879 struct cmsghdr *cm; 880 u_char buf[1024]; 881 struct iovec iov[2]; 882 | 1006 for (;;) { 1007 struct msghdr m; 1008 struct cmsghdr *cm; 1009 u_char buf[1024]; 1010 struct iovec iov[2]; 1011 |
1012 /* signal handling */ 1013 if (seenalrm) { 1014 retransmit(); 1015 seenalrm = 0; 1016 continue; 1017 } 1018 if (seenint) { 1019 onint(SIGINT); 1020 seenint = 0; 1021 continue; 1022 } 1023#ifdef SIGINFO 1024 if (seeninfo) { 1025 summary(); 1026 seeninfo = 0; 1027 continue; 1028 } 1029#endif 1030 |
|
883 if (options & F_FLOOD) { 884 pinger(); 885 timeout.tv_sec = 0; 886 timeout.tv_usec = 10000; | 1031 if (options & F_FLOOD) { 1032 pinger(); 1033 timeout.tv_sec = 0; 1034 timeout.tv_usec = 10000; |
887 memset(fdmaskp, 0, fdmasks); 888 FD_SET(s, fdmaskp); 889 if (select(s + 1, fdmaskp, NULL, NULL, &timeout) < 1) 890 continue; 891 } 892 fromlen = sizeof(from); | 1035 tv = &timeout; 1036 } else 1037 tv = NULL; 1038 memset(fdmaskp, 0, fdmasks); 1039 FD_SET(s, fdmaskp); 1040 cc = select(s + 1, fdmaskp, NULL, NULL, tv); 1041 if (cc < 0) { 1042 if (errno != EINTR) { 1043 warn("select"); 1044 sleep(1); 1045 } 1046 continue; 1047 } else if (cc == 0) 1048 continue; |
893 | 1049 |
1050 fromlen = sizeof(from); |
|
894 m.msg_name = (caddr_t)&from; 895 m.msg_namelen = sizeof(from); 896 memset(&iov, 0, sizeof(iov)); 897 iov[0].iov_base = (caddr_t)packet; 898 iov[0].iov_len = packlen; 899 m.msg_iov = iov; 900 m.msg_iovlen = 1; 901 cm = (struct cmsghdr *)buf; 902 m.msg_control = (caddr_t)buf; 903 m.msg_controllen = sizeof(buf); 904 | 1051 m.msg_name = (caddr_t)&from; 1052 m.msg_namelen = sizeof(from); 1053 memset(&iov, 0, sizeof(iov)); 1054 iov[0].iov_base = (caddr_t)packet; 1055 iov[0].iov_len = packlen; 1056 m.msg_iov = iov; 1057 m.msg_iovlen = 1; 1058 cm = (struct cmsghdr *)buf; 1059 m.msg_control = (caddr_t)buf; 1060 m.msg_controllen = sizeof(buf); 1061 |
905 if ((cc = recvmsg(s, &m, 0)) < 0) { 906 if (errno == EINTR) 907 continue; 908 warn("recvfrom"); | 1062 cc = recvmsg(s, &m, 0); 1063 if (cc < 0) { 1064 if (errno != EINTR) { 1065 warn("recvmsg"); 1066 sleep(1); 1067 } |
909 continue; | 1068 continue; |
910 } | 1069 } else if (cc == 0) { 1070 int mtu; |
911 | 1071 |
912 pr_pack(packet, cc, &m); | 1072 /* 1073 * receive control messages only. Process the 1074 * exceptions (currently the only possiblity is 1075 * a path MTU notification.) 1076 */ 1077 if ((mtu = get_pathmtu(&m)) > 0) { 1078 if ((options & F_VERBOSE) != 0) { 1079 printf("new path MTU (%d) is " 1080 "notified\n", mtu); 1081 } 1082 set_pathmtu(mtu); 1083 } 1084 continue; 1085 } else { 1086 /* 1087 * an ICMPv6 message (probably an echoreply) arrived. 1088 */ 1089 pr_pack(packet, cc, &m); 1090 } |
913 if (npackets && nreceived >= npackets) 914 break; 915 } 916 summary(); 917 exit(nreceived == 0); 918} 919 | 1091 if (npackets && nreceived >= npackets) 1092 break; 1093 } 1094 summary(); 1095 exit(nreceived == 0); 1096} 1097 |
1098void 1099onsignal(sig) 1100 int sig; 1101{ 1102 signo = sig; 1103 switch (sig) { 1104 case SIGALRM: 1105 seenalrm++; 1106 break; 1107 case SIGINT: 1108 seenint++; 1109 break; 1110#ifdef SIGINFO 1111 case SIGINFO: 1112 seeninfo++; 1113 break; 1114#endif 1115 } 1116} 1117 |
|
920/* | 1118/* |
921 * onalrm -- | 1119 * retransmit -- |
922 * This routine transmits another ping6. 923 */ | 1120 * This routine transmits another ping6. 1121 */ |
924/* ARGSUSED */ | |
925void | 1122void |
926onalrm(signo) 927 int signo; | 1123retransmit() |
928{ 929 struct itimerval itimer; 930 931 if (!npackets || ntransmitted < npackets) { 932 pinger(); 933 return; 934 } 935 --- 20 unchanged lines hidden (view full) --- 956/* 957 * pinger -- 958 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 959 * will be added on by the kernel. The ID field is our UNIX process ID, 960 * and the sequence number is an ascending integer. The first 8 bytes 961 * of the data portion are used to hold a UNIX "timeval" struct in VAX 962 * byte-order, to compute the round-trip time. 963 */ | 1124{ 1125 struct itimerval itimer; 1126 1127 if (!npackets || ntransmitted < npackets) { 1128 pinger(); 1129 return; 1130 } 1131 --- 20 unchanged lines hidden (view full) --- 1152/* 1153 * pinger -- 1154 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 1155 * will be added on by the kernel. The ID field is our UNIX process ID, 1156 * and the sequence number is an ascending integer. The first 8 bytes 1157 * of the data portion are used to hold a UNIX "timeval" struct in VAX 1158 * byte-order, to compute the round-trip time. 1159 */ |
1160size_t 1161pingerlen() 1162{ 1163 size_t l; 1164 1165 if (options & F_FQDN) 1166 l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1167 else if (options & F_FQDNOLD) 1168 l = ICMP6_NIQLEN; 1169 else if (options & F_NODEADDR) 1170 l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1171 else if (options & F_SUPTYPES) 1172 l = ICMP6_NIQLEN; 1173 else 1174 l = ICMP6ECHOLEN + datalen; 1175 1176 return l; 1177} 1178 |
|
964void 965pinger() 966{ 967 struct icmp6_hdr *icp; 968 struct iovec iov[2]; 969 int i, cc; | 1179void 1180pinger() 1181{ 1182 struct icmp6_hdr *icp; 1183 struct iovec iov[2]; 1184 int i, cc; |
1185 struct icmp6_nodeinfo *nip; 1186 int seq; |
|
970 971 icp = (struct icmp6_hdr *)outpack; | 1187 1188 icp = (struct icmp6_hdr *)outpack; |
1189 nip = (struct icmp6_nodeinfo *)outpack; |
|
972 memset(icp, 0, sizeof(*icp)); | 1190 memset(icp, 0, sizeof(*icp)); |
973 icp->icmp6_code = 0; | |
974 icp->icmp6_cksum = 0; | 1191 icp->icmp6_cksum = 0; |
975 icp->icmp6_seq = ntransmitted++; /* htons later */ 976 icp->icmp6_id = htons(ident); /* ID */ | 1192 seq = ntransmitted++; 1193 CLR(seq % mx_dup_ck); |
977 | 1194 |
978 CLR(icp->icmp6_seq % mx_dup_ck); 979 icp->icmp6_seq = htons(icp->icmp6_seq); 980 | |
981 if (options & F_FQDN) { 982 icp->icmp6_type = ICMP6_NI_QUERY; 983 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; | 1195 if (options & F_FQDN) { 1196 icp->icmp6_type = ICMP6_NI_QUERY; 1197 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; |
984 /* XXX: overwrite icmp6_id */ 985 ((struct icmp6_nodeinfo *)icp)->ni_qtype = htons(NI_QTYPE_FQDN); 986 ((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0); 987 if (timing) 988 (void)gettimeofday((struct timeval *) 989 &outpack[ICMP6ECHOLEN], NULL); | 1198 nip->ni_qtype = htons(NI_QTYPE_FQDN); 1199 nip->ni_flags = htons(0); 1200 1201 memcpy(nip->icmp6_ni_nonce, nonce, 1202 sizeof(nip->icmp6_ni_nonce)); 1203 *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 1204 |
990 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 991 sizeof(dst.sin6_addr)); 992 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 993 datalen = 0; 994 } else if (options & F_FQDNOLD) { 995 /* packet format in 03 draft - no Subject data on queries */ 996 icp->icmp6_type = ICMP6_NI_QUERY; | 1205 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 1206 sizeof(dst.sin6_addr)); 1207 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1208 datalen = 0; 1209 } else if (options & F_FQDNOLD) { 1210 /* packet format in 03 draft - no Subject data on queries */ 1211 icp->icmp6_type = ICMP6_NI_QUERY; |
997 /* code field is always 0 */ 998 /* XXX: overwrite icmp6_id */ 999 ((struct icmp6_nodeinfo *)icp)->ni_qtype = htons(NI_QTYPE_FQDN); 1000 ((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0); 1001 if (timing) 1002 (void)gettimeofday((struct timeval *) 1003 &outpack[ICMP6ECHOLEN], NULL); | 1212 icp->icmp6_code = 0; /* code field is always 0 */ 1213 nip->ni_qtype = htons(NI_QTYPE_FQDN); 1214 nip->ni_flags = htons(0); 1215 1216 memcpy(nip->icmp6_ni_nonce, nonce, 1217 sizeof(nip->icmp6_ni_nonce)); 1218 *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 1219 |
1004 cc = ICMP6_NIQLEN; 1005 datalen = 0; 1006 } else if (options & F_NODEADDR) { 1007 icp->icmp6_type = ICMP6_NI_QUERY; 1008 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; | 1220 cc = ICMP6_NIQLEN; 1221 datalen = 0; 1222 } else if (options & F_NODEADDR) { 1223 icp->icmp6_type = ICMP6_NI_QUERY; 1224 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; |
1009 /* XXX: overwrite icmp6_id */ 1010 ((struct icmp6_nodeinfo *)icp)->ni_qtype = 1011 htons(NI_QTYPE_NODEADDR); 1012 ((struct icmp6_nodeinfo *)icp)->ni_flags = htons(0); 1013 if (timing) 1014 (void)gettimeofday((struct timeval *) 1015 &outpack[ICMP6ECHOLEN], NULL); | 1225 nip->ni_qtype = htons(NI_QTYPE_NODEADDR); 1226 nip->ni_flags = naflags; 1227 1228 memcpy(nip->icmp6_ni_nonce, nonce, 1229 sizeof(nip->icmp6_ni_nonce)); 1230 *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 1231 |
1016 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 1017 sizeof(dst.sin6_addr)); 1018 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1019 datalen = 0; | 1232 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 1233 sizeof(dst.sin6_addr)); 1234 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1235 datalen = 0; |
1020 ((struct icmp6_nodeinfo *)icp)->ni_flags = naflags; 1021 } 1022 else { | 1236 } else if (options & F_SUPTYPES) { 1237 icp->icmp6_type = ICMP6_NI_QUERY; 1238 icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/ 1239 nip->ni_qtype = htons(NI_QTYPE_SUPTYPES); 1240 /* we support compressed bitmap */ 1241 nip->ni_flags = NI_SUPTYPE_FLAG_COMPRESS; 1242 1243 memcpy(nip->icmp6_ni_nonce, nonce, 1244 sizeof(nip->icmp6_ni_nonce)); 1245 *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 1246 cc = ICMP6_NIQLEN; 1247 datalen = 0; 1248 } else { |
1023 icp->icmp6_type = ICMP6_ECHO_REQUEST; | 1249 icp->icmp6_type = ICMP6_ECHO_REQUEST; |
1250 icp->icmp6_code = 0; 1251 icp->icmp6_id = htons(ident); 1252 icp->icmp6_seq = ntohs(seq); |
|
1024 if (timing) 1025 (void)gettimeofday((struct timeval *) 1026 &outpack[ICMP6ECHOLEN], NULL); 1027 cc = ICMP6ECHOLEN + datalen; 1028 } 1029 | 1253 if (timing) 1254 (void)gettimeofday((struct timeval *) 1255 &outpack[ICMP6ECHOLEN], NULL); 1256 cc = ICMP6ECHOLEN + datalen; 1257 } 1258 |
1259#ifdef DIAGNOSTIC 1260 if (pingerlen() != cc) 1261 errx(1, "internal error; length mismatch"); 1262#endif 1263 |
|
1030 smsghdr.msg_name = (caddr_t)&dst; 1031 smsghdr.msg_namelen = sizeof(dst); 1032 memset(&iov, 0, sizeof(iov)); 1033 iov[0].iov_base = (caddr_t)outpack; 1034 iov[0].iov_len = cc; 1035 smsghdr.msg_iov = iov; 1036 smsghdr.msg_iovlen = 1; 1037 --- 4 unchanged lines hidden (view full) --- 1042 warn("sendmsg"); 1043 (void)printf("ping6: wrote %s %d chars, ret=%d\n", 1044 hostname, cc, i); 1045 } 1046 if (!(options & F_QUIET) && options & F_FLOOD) 1047 (void)write(STDOUT_FILENO, &DOT, 1); 1048} 1049 | 1264 smsghdr.msg_name = (caddr_t)&dst; 1265 smsghdr.msg_namelen = sizeof(dst); 1266 memset(&iov, 0, sizeof(iov)); 1267 iov[0].iov_base = (caddr_t)outpack; 1268 iov[0].iov_len = cc; 1269 smsghdr.msg_iov = iov; 1270 smsghdr.msg_iovlen = 1; 1271 --- 4 unchanged lines hidden (view full) --- 1276 warn("sendmsg"); 1277 (void)printf("ping6: wrote %s %d chars, ret=%d\n", 1278 hostname, cc, i); 1279 } 1280 if (!(options & F_QUIET) && options & F_FLOOD) 1281 (void)write(STDOUT_FILENO, &DOT, 1); 1282} 1283 |
1284int 1285myechoreply(icp) 1286 const struct icmp6_hdr *icp; 1287{ 1288 if (ntohs(icp->icmp6_id) == ident) 1289 return 1; 1290 else 1291 return 0; 1292} 1293 1294int 1295mynireply(nip) 1296 const struct icmp6_nodeinfo *nip; 1297{ 1298 if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), 1299 nonce + sizeof(u_int16_t), 1300 sizeof(nonce) - sizeof(u_int16_t)) == 0) 1301 return 1; 1302 else 1303 return 0; 1304} 1305 1306char * 1307dnsdecode(sp, ep, base, buf, bufsiz) 1308 const u_char **sp; 1309 const u_char *ep; 1310 const u_char *base; /*base for compressed name*/ 1311 u_char *buf; 1312 size_t bufsiz; 1313{ 1314 int i; 1315 const u_char *cp; 1316 char cresult[MAXDNAME + 1]; 1317 const u_char *comp; 1318 int l; 1319 1320 cp = *sp; 1321 *buf = '\0'; 1322 1323 if (cp >= ep) 1324 return NULL; 1325 while (cp < ep) { 1326 i = *cp; 1327 if (i == 0 || cp != *sp) { 1328 if (strlcat(buf, ".", bufsiz) >= bufsiz) 1329 return NULL; /*result overrun*/ 1330 } 1331 if (i == 0) 1332 break; 1333 cp++; 1334 1335 if ((i & 0xc0) == 0xc0 && cp - base > (i & 0x3f)) { 1336 /* DNS compression */ 1337 if (!base) 1338 return NULL; 1339 1340 comp = base + (i & 0x3f); 1341 if (dnsdecode(&comp, cp, base, cresult, 1342 sizeof(cresult)) == NULL) 1343 return NULL; 1344 if (strlcat(buf, cresult, bufsiz) >= bufsiz) 1345 return NULL; /*result overrun*/ 1346 break; 1347 } else if ((i & 0x3f) == i) { 1348 if (i > ep - cp) 1349 return NULL; /*source overrun*/ 1350 while (i-- > 0 && cp < ep) { 1351 l = snprintf(cresult, sizeof(cresult), 1352 isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff); 1353 if (l >= sizeof(cresult)) 1354 return NULL; 1355 if (strlcat(buf, cresult, bufsiz) >= bufsiz) 1356 return NULL; /*result overrun*/ 1357 cp++; 1358 } 1359 } else 1360 return NULL; /*invalid label*/ 1361 } 1362 if (i != 0) 1363 return NULL; /*not terminated*/ 1364 cp++; 1365 *sp = cp; 1366 return buf; 1367} 1368 |
|
1050/* 1051 * pr_pack -- 1052 * Print out the packet, if it came from us. This logic is necessary 1053 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 1054 * which arrive ('tis only fair). This permits multiple copies of this 1055 * program to be run without having intermingled output (or statistics!). 1056 */ 1057void 1058pr_pack(buf, cc, mhdr) 1059 u_char *buf; 1060 int cc; 1061 struct msghdr *mhdr; 1062{ 1063#define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) 1064 struct icmp6_hdr *icp; | 1369/* 1370 * pr_pack -- 1371 * Print out the packet, if it came from us. This logic is necessary 1372 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 1373 * which arrive ('tis only fair). This permits multiple copies of this 1374 * program to be run without having intermingled output (or statistics!). 1375 */ 1376void 1377pr_pack(buf, cc, mhdr) 1378 u_char *buf; 1379 int cc; 1380 struct msghdr *mhdr; 1381{ 1382#define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) 1383 struct icmp6_hdr *icp; |
1384 struct icmp6_nodeinfo *ni; |
|
1065 int i; 1066 int hoplim; | 1385 int i; 1386 int hoplim; |
1067 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; | 1387 struct sockaddr *from; 1388 int fromlen; |
1068 u_char *cp = NULL, *dp, *end = buf + cc; 1069 struct in6_pktinfo *pktinfo = NULL; 1070 struct timeval tv, *tp; 1071 double triptime = 0; 1072 int dupflag; 1073 size_t off; 1074 int oldfqdn; | 1389 u_char *cp = NULL, *dp, *end = buf + cc; 1390 struct in6_pktinfo *pktinfo = NULL; 1391 struct timeval tv, *tp; 1392 double triptime = 0; 1393 int dupflag; 1394 size_t off; 1395 int oldfqdn; |
1396 u_int16_t seq; 1397 char dnsname[MAXDNAME + 1]; |
|
1075 1076 (void)gettimeofday(&tv, NULL); 1077 | 1398 1399 (void)gettimeofday(&tv, NULL); 1400 |
1401 if (!mhdr || !mhdr->msg_name || 1402 mhdr->msg_namelen != sizeof(struct sockaddr_in6) || 1403 ((struct sockaddr *)mhdr->msg_name)->sa_family != AF_INET6) { 1404 if (options & F_VERBOSE) 1405 warnx("invalid peername\n"); 1406 return; 1407 } 1408 from = (struct sockaddr *)mhdr->msg_name; 1409 fromlen = mhdr->msg_namelen; |
|
1078 if (cc < sizeof(struct icmp6_hdr)) { 1079 if (options & F_VERBOSE) 1080 warnx("packet too short (%d bytes) from %s\n", cc, | 1410 if (cc < sizeof(struct icmp6_hdr)) { 1411 if (options & F_VERBOSE) 1412 warnx("packet too short (%d bytes) from %s\n", cc, |
1081 pr_addr(from)); | 1413 pr_addr(from, fromlen)); |
1082 return; 1083 } 1084 icp = (struct icmp6_hdr *)buf; | 1414 return; 1415 } 1416 icp = (struct icmp6_hdr *)buf; |
1417 ni = (struct icmp6_nodeinfo *)buf; |
|
1085 off = 0; 1086 1087 if ((hoplim = get_hoplim(mhdr)) == -1) { 1088 warnx("failed to get receiving hop limit"); 1089 return; 1090 } 1091 if ((pktinfo = get_rcvpktinfo(mhdr)) == NULL) { 1092 warnx("failed to get receiving pakcet information"); 1093 return; 1094 } 1095 | 1418 off = 0; 1419 1420 if ((hoplim = get_hoplim(mhdr)) == -1) { 1421 warnx("failed to get receiving hop limit"); 1422 return; 1423 } 1424 if ((pktinfo = get_rcvpktinfo(mhdr)) == NULL) { 1425 warnx("failed to get receiving pakcet information"); 1426 return; 1427 } 1428 |
1096 if (icp->icmp6_type == ICMP6_ECHO_REPLY) { 1097 /* XXX the following line overwrites the original packet */ 1098 icp->icmp6_seq = ntohs(icp->icmp6_seq); 1099 if (ntohs(icp->icmp6_id) != ident) 1100 return; /* It was not our ECHO */ | 1429 if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) { 1430 seq = ntohs(icp->icmp6_seq); |
1101 ++nreceived; 1102 if (timing) { 1103 tp = (struct timeval *)(icp + 1); 1104 tvsub(&tv, tp); 1105 triptime = ((double)tv.tv_sec) * 1000.0 + 1106 ((double)tv.tv_usec) / 1000.0; 1107 tsum += triptime; | 1431 ++nreceived; 1432 if (timing) { 1433 tp = (struct timeval *)(icp + 1); 1434 tvsub(&tv, tp); 1435 triptime = ((double)tv.tv_sec) * 1000.0 + 1436 ((double)tv.tv_usec) / 1000.0; 1437 tsum += triptime; |
1438#if defined(__OpenBSD__) || defined(__NetBSD__) 1439 tsumsq += triptime * triptime; 1440#endif |
|
1108 if (triptime < tmin) 1109 tmin = triptime; 1110 if (triptime > tmax) 1111 tmax = triptime; 1112 } 1113 | 1441 if (triptime < tmin) 1442 tmin = triptime; 1443 if (triptime > tmax) 1444 tmax = triptime; 1445 } 1446 |
1114 if (TST(icp->icmp6_seq % mx_dup_ck)) { | 1447 if (TST(seq % mx_dup_ck)) { |
1115 ++nrepeats; 1116 --nreceived; 1117 dupflag = 1; 1118 } else { | 1448 ++nrepeats; 1449 --nreceived; 1450 dupflag = 1; 1451 } else { |
1119 SET(icp->icmp6_seq % mx_dup_ck); | 1452 SET(seq % mx_dup_ck); |
1120 dupflag = 0; 1121 } 1122 1123 if (options & F_QUIET) 1124 return; 1125 1126 if (options & F_FLOOD) 1127 (void)write(STDOUT_FILENO, &BSPACE, 1); 1128 else { 1129 (void)printf("%d bytes from %s, icmp_seq=%u", cc, | 1453 dupflag = 0; 1454 } 1455 1456 if (options & F_QUIET) 1457 return; 1458 1459 if (options & F_FLOOD) 1460 (void)write(STDOUT_FILENO, &BSPACE, 1); 1461 else { 1462 (void)printf("%d bytes from %s, icmp_seq=%u", cc, |
1130 pr_addr(from), 1131 icp->icmp6_seq); | 1463 pr_addr(from, fromlen), seq); |
1132 (void)printf(" hlim=%d", hoplim); 1133 if ((options & F_VERBOSE) != 0) { 1134 struct sockaddr_in6 dstsa; 1135 1136 memset(&dstsa, 0, sizeof(dstsa)); 1137 dstsa.sin6_family = AF_INET6; | 1464 (void)printf(" hlim=%d", hoplim); 1465 if ((options & F_VERBOSE) != 0) { 1466 struct sockaddr_in6 dstsa; 1467 1468 memset(&dstsa, 0, sizeof(dstsa)); 1469 dstsa.sin6_family = AF_INET6; |
1470#ifdef SIN6_LEN |
|
1138 dstsa.sin6_len = sizeof(dstsa); | 1471 dstsa.sin6_len = sizeof(dstsa); |
1472#endif |
|
1139 dstsa.sin6_scope_id = pktinfo->ipi6_ifindex; 1140 dstsa.sin6_addr = pktinfo->ipi6_addr; | 1473 dstsa.sin6_scope_id = pktinfo->ipi6_ifindex; 1474 dstsa.sin6_addr = pktinfo->ipi6_addr; |
1141 (void)printf(" dst=%s", pr_addr(&dstsa)); | 1475 (void)printf(" dst=%s", 1476 pr_addr((struct sockaddr *)&dstsa, 1477 sizeof(dstsa))); |
1142 } 1143 if (timing) 1144 (void)printf(" time=%g ms", triptime); 1145 if (dupflag) 1146 (void)printf("(DUP!)"); 1147 /* check the data */ 1148 cp = buf + off + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1149 dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1150 for (i = 8; cp < end; ++i, ++cp, ++dp) { 1151 if (*cp != *dp) { 1152 (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); 1153 break; 1154 } 1155 } 1156 } | 1478 } 1479 if (timing) 1480 (void)printf(" time=%g ms", triptime); 1481 if (dupflag) 1482 (void)printf("(DUP!)"); 1483 /* check the data */ 1484 cp = buf + off + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1485 dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1486 for (i = 8; cp < end; ++i, ++cp, ++dp) { 1487 if (*cp != *dp) { 1488 (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); 1489 break; 1490 } 1491 } 1492 } |
1157 } else if (icp->icmp6_type == ICMP6_NI_REPLY) { /* ICMP6_NI_REPLY */ 1158 struct icmp6_nodeinfo *ni = (struct icmp6_nodeinfo *)(buf + off); | 1493 } else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) { 1494 seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce); 1495 ++nreceived; 1496 if (TST(seq % mx_dup_ck)) { 1497 ++nrepeats; 1498 --nreceived; 1499 dupflag = 1; 1500 } else { 1501 SET(seq % mx_dup_ck); 1502 dupflag = 0; 1503 } |
1159 | 1504 |
1160 (void)printf("%d bytes from %s: ", cc, 1161 pr_addr(from)); | 1505 if (options & F_QUIET) 1506 return; |
1162 | 1507 |
1163 switch(ntohs(ni->ni_qtype)) { 1164 case NI_QTYPE_NOOP: 1165 printf("NodeInfo NOOP"); 1166 break; 1167 case NI_QTYPE_SUPTYPES: 1168 printf("NodeInfo Supported Qtypes"); 1169 break; 1170 case NI_QTYPE_NODEADDR: 1171 pr_nodeaddr(ni, end - (u_char *)ni); 1172 break; 1173 case NI_QTYPE_FQDN: 1174 default: /* XXX: for backward compatibility */ | 1508 (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); 1509 1510 switch (ntohs(ni->ni_code)) { 1511 case ICMP6_NI_SUCCESS: 1512 break; 1513 case ICMP6_NI_REFUSED: 1514 printf("refused, type 0x%x", ntohs(ni->ni_type)); 1515 goto fqdnend; 1516 case ICMP6_NI_UNKNOWN: 1517 printf("unknown, type 0x%x", ntohs(ni->ni_type)); 1518 goto fqdnend; 1519 default: 1520 printf("unknown code 0x%x, type 0x%x", 1521 ntohs(ni->ni_code), ntohs(ni->ni_type)); 1522 goto fqdnend; 1523 } 1524 1525 switch (ntohs(ni->ni_qtype)) { 1526 case NI_QTYPE_NOOP: 1527 printf("NodeInfo NOOP"); 1528 break; 1529 case NI_QTYPE_SUPTYPES: 1530 pr_suptypes(ni, end - (u_char *)ni); 1531 break; 1532 case NI_QTYPE_NODEADDR: 1533 pr_nodeaddr(ni, end - (u_char *)ni); 1534 break; 1535 case NI_QTYPE_FQDN: 1536 default: /* XXX: for backward compatibility */ |
1175 cp = (u_char *)ni + ICMP6_NIRLEN; 1176 if (buf[off + ICMP6_NIRLEN] == 1177 cc - off - ICMP6_NIRLEN - 1) 1178 oldfqdn = 1; 1179 else 1180 oldfqdn = 0; 1181 if (oldfqdn) { | 1537 cp = (u_char *)ni + ICMP6_NIRLEN; 1538 if (buf[off + ICMP6_NIRLEN] == 1539 cc - off - ICMP6_NIRLEN - 1) 1540 oldfqdn = 1; 1541 else 1542 oldfqdn = 0; 1543 if (oldfqdn) { |
1182 cp++; | 1544 cp++; /* skip length */ |
1183 while (cp < end) { 1184 safeputc(*cp & 0xff); 1185 cp++; 1186 } 1187 } else { | 1545 while (cp < end) { 1546 safeputc(*cp & 0xff); 1547 cp++; 1548 } 1549 } else { |
1550 i = 0; |
|
1188 while (cp < end) { | 1551 while (cp < end) { |
1189 i = *cp++; 1190 if (i) { 1191 if (i > end - cp) { 1192 printf("???"); 1193 break; 1194 } 1195 while (i-- && cp < end) { 1196 safeputc(*cp & 0xff); 1197 cp++; 1198 } 1199 if (cp + 1 < end && *cp) 1200 printf("."); 1201 } else { 1202 if (cp == end) { 1203 /* FQDN */ 1204 printf("."); 1205 } else if (cp + 1 == end && 1206 *cp == '\0') { 1207 /* truncated */ 1208 } else { 1209 /* invalid */ 1210 printf("???"); 1211 } | 1552 if (dnsdecode((const u_char **)&cp, end, 1553 (const u_char *)(ni + 1), dnsname, 1554 sizeof(dnsname)) == NULL) { 1555 printf("???"); |
1212 break; 1213 } | 1556 break; 1557 } |
1558 /* 1559 * name-lookup special handling for 1560 * truncated name 1561 */ 1562 if (cp + 1 <= end && !*cp && 1563 strlen(dnsname) > 0) { 1564 dnsname[strlen(dnsname) - 1] = '\0'; 1565 cp++; 1566 } 1567 printf("%s%s", i > 0 ? "," : "", 1568 dnsname); |
|
1214 } 1215 } 1216 if (options & F_VERBOSE) { 1217 int32_t ttl; 1218 int comma = 0; 1219 1220 (void)printf(" ("); /*)*/ 1221 | 1569 } 1570 } 1571 if (options & F_VERBOSE) { 1572 int32_t ttl; 1573 int comma = 0; 1574 1575 (void)printf(" ("); /*)*/ 1576 |
1222 switch(ni->ni_code) { | 1577 switch (ni->ni_code) { |
1223 case ICMP6_NI_REFUSED: 1224 (void)printf("refused"); 1225 comma++; 1226 break; 1227 case ICMP6_NI_UNKNOWN: 1228 (void)printf("unknwon qtype"); 1229 comma++; 1230 break; 1231 } 1232 1233 if ((end - (u_char *)ni) < ICMP6_NIRLEN) { | 1578 case ICMP6_NI_REFUSED: 1579 (void)printf("refused"); 1580 comma++; 1581 break; 1582 case ICMP6_NI_UNKNOWN: 1583 (void)printf("unknwon qtype"); 1584 comma++; 1585 break; 1586 } 1587 1588 if ((end - (u_char *)ni) < ICMP6_NIRLEN) { |
1234 /* case of refusion, unkown */ | 1589 /* case of refusion, unknown */ 1590 /*(*/ 1591 putchar(')'); |
1235 goto fqdnend; 1236 } 1237 ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); 1238 if (comma) 1239 printf(","); | 1592 goto fqdnend; 1593 } 1594 ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); 1595 if (comma) 1596 printf(","); |
1240 if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) | 1597 if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { |
1241 (void)printf("TTL=%d:meaningless", | 1598 (void)printf("TTL=%d:meaningless", |
1242 (int)ttl); 1243 else { | 1599 (int)ttl); 1600 } else { |
1244 if (ttl < 0) { 1245 (void)printf("TTL=%d:invalid", | 1601 if (ttl < 0) { 1602 (void)printf("TTL=%d:invalid", |
1246 ttl); | 1603 ttl); |
1247 } else 1248 (void)printf("TTL=%d", ttl); 1249 } 1250 comma++; 1251 1252 if (oldfqdn) { 1253 if (comma) 1254 printf(","); --- 9 unchanged lines hidden (view full) --- 1264 } 1265 } 1266 1267 if (buf[off + ICMP6_NIRLEN] != 1268 cc - off - ICMP6_NIRLEN - 1 && oldfqdn) { 1269 if (comma) 1270 printf(","); 1271 (void)printf("invalid namelen:%d/%lu", | 1604 } else 1605 (void)printf("TTL=%d", ttl); 1606 } 1607 comma++; 1608 1609 if (oldfqdn) { 1610 if (comma) 1611 printf(","); --- 9 unchanged lines hidden (view full) --- 1621 } 1622 } 1623 1624 if (buf[off + ICMP6_NIRLEN] != 1625 cc - off - ICMP6_NIRLEN - 1 && oldfqdn) { 1626 if (comma) 1627 printf(","); 1628 (void)printf("invalid namelen:%d/%lu", |
1272 buf[off + ICMP6_NIRLEN], 1273 (u_long)cc - off - ICMP6_NIRLEN - 1); | 1629 buf[off + ICMP6_NIRLEN], 1630 (u_long)cc - off - ICMP6_NIRLEN - 1); |
1274 comma++; 1275 } 1276 /*(*/ 1277 putchar(')'); 1278 } | 1631 comma++; 1632 } 1633 /*(*/ 1634 putchar(')'); 1635 } |
1279 fqdnend: | 1636 fqdnend: |
1280 ; 1281 } 1282 } else { 1283 /* We've got something other than an ECHOREPLY */ 1284 if (!(options & F_VERBOSE)) 1285 return; | 1637 ; 1638 } 1639 } else { 1640 /* We've got something other than an ECHOREPLY */ 1641 if (!(options & F_VERBOSE)) 1642 return; |
1286 (void)printf("%d bytes from %s: ", cc, 1287 pr_addr(from)); | 1643 (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); |
1288 pr_icmph(icp, end); 1289 } 1290 1291 if (!(options & F_FLOOD)) { 1292 (void)putchar('\n'); 1293 if (options & F_VERBOSE) 1294 pr_exthdrs(mhdr); 1295 (void)fflush(stdout); --- 7 unchanged lines hidden (view full) --- 1303{ 1304 struct cmsghdr *cm; 1305 1306 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1307 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1308 if (cm->cmsg_level != IPPROTO_IPV6) 1309 continue; 1310 | 1644 pr_icmph(icp, end); 1645 } 1646 1647 if (!(options & F_FLOOD)) { 1648 (void)putchar('\n'); 1649 if (options & F_VERBOSE) 1650 pr_exthdrs(mhdr); 1651 (void)fflush(stdout); --- 7 unchanged lines hidden (view full) --- 1659{ 1660 struct cmsghdr *cm; 1661 1662 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1663 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1664 if (cm->cmsg_level != IPPROTO_IPV6) 1665 continue; 1666 |
1311 switch(cm->cmsg_type) { | 1667 switch (cm->cmsg_type) { |
1312 case IPV6_HOPOPTS: 1313 printf(" HbH Options: "); 1314 pr_ip6opt(CMSG_DATA(cm)); 1315 break; 1316 case IPV6_DSTOPTS: 1317#ifdef IPV6_RTHDRDSTOPTS 1318 case IPV6_RTHDRDSTOPTS: 1319#endif --- 18 unchanged lines hidden (view full) --- 1338 size_t extlen, len; 1339 void *databuf; 1340 size_t offset; 1341 u_int16_t value2; 1342 u_int32_t value4; 1343 1344 ext = (struct ip6_hbh *)extbuf; 1345 extlen = (ext->ip6h_len + 1) * 8; | 1668 case IPV6_HOPOPTS: 1669 printf(" HbH Options: "); 1670 pr_ip6opt(CMSG_DATA(cm)); 1671 break; 1672 case IPV6_DSTOPTS: 1673#ifdef IPV6_RTHDRDSTOPTS 1674 case IPV6_RTHDRDSTOPTS: 1675#endif --- 18 unchanged lines hidden (view full) --- 1694 size_t extlen, len; 1695 void *databuf; 1696 size_t offset; 1697 u_int16_t value2; 1698 u_int32_t value4; 1699 1700 ext = (struct ip6_hbh *)extbuf; 1701 extlen = (ext->ip6h_len + 1) * 8; |
1346 printf("nxt %u, len %u (%d bytes)\n", ext->ip6h_nxt, 1347 ext->ip6h_len, extlen); | 1702 printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt, 1703 (unsigned int)ext->ip6h_len, (unsigned long)extlen); |
1348 1349 currentlen = 0; 1350 while (1) { 1351 currentlen = inet6_opt_next(extbuf, extlen, currentlen, | 1704 1705 currentlen = 0; 1706 while (1) { 1707 currentlen = inet6_opt_next(extbuf, extlen, currentlen, |
1352 &type, &len, &databuf); | 1708 &type, &len, &databuf); |
1353 if (currentlen == -1) 1354 break; 1355 switch (type) { 1356 /* 1357 * Note that inet6_opt_next automatically skips any padding 1358 * optins. 1359 */ 1360 case IP6OPT_JUMBO: 1361 offset = 0; 1362 offset = inet6_opt_get_val(databuf, offset, | 1709 if (currentlen == -1) 1710 break; 1711 switch (type) { 1712 /* 1713 * Note that inet6_opt_next automatically skips any padding 1714 * optins. 1715 */ 1716 case IP6OPT_JUMBO: 1717 offset = 0; 1718 offset = inet6_opt_get_val(databuf, offset, |
1363 &value4, sizeof(value4)); | 1719 &value4, sizeof(value4)); |
1364 printf(" Jumbo Payload Opt: Length %u\n", | 1720 printf(" Jumbo Payload Opt: Length %u\n", |
1365 (unsigned int)ntohl(value4)); | 1721 (u_int32_t)ntohl(value4)); |
1366 break; 1367 case IP6OPT_ROUTER_ALERT: 1368 offset = 0; 1369 offset = inet6_opt_get_val(databuf, offset, 1370 &value2, sizeof(value2)); 1371 printf(" Router Alert Opt: Type %u\n", | 1722 break; 1723 case IP6OPT_ROUTER_ALERT: 1724 offset = 0; 1725 offset = inet6_opt_get_val(databuf, offset, 1726 &value2, sizeof(value2)); 1727 printf(" Router Alert Opt: Type %u\n", |
1372 ntohs(value2)); | 1728 ntohs(value2)); |
1373 break; 1374 default: | 1729 break; 1730 default: |
1375 printf(" Received Opt %u len %u\n", type, len); | 1731 printf(" Received Opt %u len %lu\n", 1732 type, (unsigned long)len); |
1376 break; 1377 } 1378 } 1379 return; 1380} 1381#else /* !USE_RFC2292BIS */ 1382/* ARGSUSED */ 1383void --- 10 unchanged lines hidden (view full) --- 1394{ 1395 struct in6_addr *in6; 1396 char ntopbuf[INET6_ADDRSTRLEN]; 1397 struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; 1398 int i, segments; 1399 1400 /* print fixed part of the header */ 1401 printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, | 1733 break; 1734 } 1735 } 1736 return; 1737} 1738#else /* !USE_RFC2292BIS */ 1739/* ARGSUSED */ 1740void --- 10 unchanged lines hidden (view full) --- 1751{ 1752 struct in6_addr *in6; 1753 char ntopbuf[INET6_ADDRSTRLEN]; 1754 struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; 1755 int i, segments; 1756 1757 /* print fixed part of the header */ 1758 printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, |
1402 rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); | 1759 rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); |
1403 if ((segments = inet6_rth_segments(extbuf)) >= 0) 1404 printf("%d segments, ", segments); 1405 else 1406 printf("segments unknown, "); 1407 printf("%d left\n", rh->ip6r_segleft); 1408 1409 for (i = 0; i < segments; i++) { 1410 in6 = inet6_rth_getaddr(extbuf, i); 1411 if (in6 == NULL) 1412 printf(" [%d]<NULL>\n", i); | 1760 if ((segments = inet6_rth_segments(extbuf)) >= 0) 1761 printf("%d segments, ", segments); 1762 else 1763 printf("segments unknown, "); 1764 printf("%d left\n", rh->ip6r_segleft); 1765 1766 for (i = 0; i < segments; i++) { 1767 in6 = inet6_rth_getaddr(extbuf, i); 1768 if (in6 == NULL) 1769 printf(" [%d]<NULL>\n", i); |
1413 else 1414 printf(" [%d]%s\n", i, 1415 inet_ntop(AF_INET6, in6, 1416 ntopbuf, sizeof(ntopbuf))); | 1770 else { 1771 if (!inet_ntop(AF_INET6, in6, ntopbuf, 1772 sizeof(ntopbuf))) 1773 strncpy(ntopbuf, "?", sizeof(ntopbuf)); 1774 printf(" [%d]%s\n", i, ntopbuf); 1775 } |
1417 } 1418 1419 return; | 1776 } 1777 1778 return; |
1420 | 1779 |
1421} | 1780} |
1781 |
|
1422#else /* !USE_RFC2292BIS */ 1423/* ARGSUSED */ 1424void 1425pr_rthdr(void *extbuf) 1426{ 1427 putchar('\n'); 1428 return; 1429} 1430#endif /* USE_RFC2292BIS */ 1431 | 1782#else /* !USE_RFC2292BIS */ 1783/* ARGSUSED */ 1784void 1785pr_rthdr(void *extbuf) 1786{ 1787 putchar('\n'); 1788 return; 1789} 1790#endif /* USE_RFC2292BIS */ 1791 |
1792int 1793pr_bitrange(v, s, ii) 1794 u_int32_t v; 1795 int s; 1796 int ii; 1797{ 1798 int off; 1799 int i; |
|
1432 | 1800 |
1801 off = 0; 1802 while (off < 32) { 1803 /* shift till we have 0x01 */ 1804 if ((v & 0x01) == 0) { 1805 if (ii > 1) 1806 printf("-%u", s + off - 1); 1807 ii = 0; 1808 switch (v & 0x0f) { 1809 case 0x00: 1810 v >>= 4; 1811 off += 4; 1812 continue; 1813 case 0x08: 1814 v >>= 3; 1815 off += 3; 1816 continue; 1817 case 0x04: case 0x0c: 1818 v >>= 2; 1819 off += 2; 1820 continue; 1821 default: 1822 v >>= 1; 1823 off += 1; 1824 continue; 1825 } 1826 } 1827 1828 /* we have 0x01 with us */ 1829 for (i = 0; i < 32 - off; i++) { 1830 if ((v & (0x01 << i)) == 0) 1831 break; 1832 } 1833 if (!ii) 1834 printf(" %u", s + off); 1835 ii += i; 1836 v >>= i; off += i; 1837 } 1838 return ii; 1839} 1840 |
|
1433void | 1841void |
1842pr_suptypes(ni, nilen) 1843 struct icmp6_nodeinfo *ni; /* ni->qtype must be SUPTYPES */ 1844 size_t nilen; 1845{ 1846 size_t clen; 1847 u_int32_t v; 1848 const u_char *cp, *end; 1849 u_int16_t cur; 1850 struct cbit { 1851 u_int16_t words; /*32bit count*/ 1852 u_int16_t skip; 1853 } cbit; 1854#define MAXQTYPES (1 << 16) 1855 size_t off; 1856 int b; 1857 1858 cp = (u_char *)(ni + 1); 1859 end = ((u_char *)ni) + nilen; 1860 cur = 0; 1861 b = 0; 1862 1863 printf("NodeInfo Supported Qtypes"); 1864 if (options & F_VERBOSE) { 1865 if (ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) 1866 printf(", compressed bitmap"); 1867 else 1868 printf(", raw bitmap"); 1869 } 1870 1871 while (cp < end) { 1872 clen = (size_t)(end - cp); 1873 if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) == 0) { 1874 if (clen == 0 || clen > MAXQTYPES / 8 || 1875 clen % sizeof(v)) { 1876 printf("???"); 1877 return; 1878 } 1879 } else { 1880 if (clen < sizeof(cbit) || clen % sizeof(v)) 1881 return; 1882 memcpy(&cbit, cp, sizeof(cbit)); 1883 if (sizeof(cbit) + ntohs(cbit.words) * sizeof(v) > 1884 clen) 1885 return; 1886 cp += sizeof(cbit); 1887 clen = ntohs(cbit.words) * sizeof(v); 1888 if (cur + clen * 8 + (u_long)ntohs(cbit.skip) * 32 > 1889 MAXQTYPES) 1890 return; 1891 } 1892 1893 for (off = 0; off < clen; off += sizeof(v)) { 1894 memcpy(&v, cp + off, sizeof(v)); 1895 v = (u_int32_t)ntohl(v); 1896 b = pr_bitrange(v, (int)(cur + off * 8), b); 1897 } 1898 /* flush the remaining bits */ 1899 b = pr_bitrange(0, (int)(cur + off * 8), b); 1900 1901 cp += clen; 1902 cur += clen * 8; 1903 if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) != 0) 1904 cur += ntohs(cbit.skip) * 32; 1905 } 1906} 1907 1908void |
|
1434pr_nodeaddr(ni, nilen) 1435 struct icmp6_nodeinfo *ni; /* ni->qtype must be NODEADDR */ 1436 int nilen; 1437{ | 1909pr_nodeaddr(ni, nilen) 1910 struct icmp6_nodeinfo *ni; /* ni->qtype must be NODEADDR */ 1911 int nilen; 1912{ |
1438 struct in6_addr *ia6 = (struct in6_addr *)(ni + 1); | 1913 u_char *cp = (u_char *)(ni + 1); |
1439 char ntop_buf[INET6_ADDRSTRLEN]; | 1914 char ntop_buf[INET6_ADDRSTRLEN]; |
1915 int withttl = 0; |
|
1440 1441 nilen -= sizeof(struct icmp6_nodeinfo); 1442 1443 if (options & F_VERBOSE) { | 1916 1917 nilen -= sizeof(struct icmp6_nodeinfo); 1918 1919 if (options & F_VERBOSE) { |
1444 switch(ni->ni_code) { 1445 case ICMP6_NI_REFUSED: 1446 (void)printf("refused"); 1447 break; 1448 case ICMP6_NI_UNKNOWN: 1449 (void)printf("unknown qtype"); 1450 break; | 1920 switch (ni->ni_code) { 1921 case ICMP6_NI_REFUSED: 1922 (void)printf("refused"); 1923 break; 1924 case ICMP6_NI_UNKNOWN: 1925 (void)printf("unknown qtype"); 1926 break; |
1451 } | 1927 } |
1452 if (ni->ni_flags & NI_NODEADDR_FLAG_ALL) | 1928 if (ni->ni_flags & NI_NODEADDR_FLAG_TRUNCATE) |
1453 (void)printf(" truncated"); 1454 } 1455 putchar('\n'); 1456 if (nilen <= 0) 1457 printf(" no address\n"); | 1929 (void)printf(" truncated"); 1930 } 1931 putchar('\n'); 1932 if (nilen <= 0) 1933 printf(" no address\n"); |
1458 for (; nilen > 0; nilen -= sizeof(*ia6), ia6 += 1) { 1459 printf(" %s\n", 1460 inet_ntop(AF_INET6, ia6, ntop_buf, sizeof(ntop_buf))); | 1934 1935 /* 1936 * In icmp-name-lookups 05 and later, TTL of each returned address 1937 * is contained in the resposne. We try to detect the version 1938 * by the length of the data, but note that the detection algorithm 1939 * is incomplete. We assume the latest draft by default. 1940 */ 1941 if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0) 1942 withttl = 1; 1943 while (nilen > 0) { 1944 u_int32_t ttl; 1945 1946 if (withttl) { 1947 /* XXX: alignment? */ 1948 ttl = (u_int32_t)ntohl(*(u_int32_t *)cp); 1949 cp += sizeof(u_int32_t); 1950 nilen -= sizeof(u_int32_t); 1951 } 1952 1953 if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) == 1954 NULL) 1955 strncpy(ntop_buf, "?", sizeof(ntop_buf)); 1956 printf(" %s", ntop_buf); 1957 if (withttl) { 1958 if (ttl == 0xffffffff) { 1959 /* 1960 * XXX: can this convention be applied to all 1961 * type of TTL (i.e. non-ND TTL)? 1962 */ 1963 printf("(TTL=infty)"); 1964 } 1965 else 1966 printf("(TTL=%u)", ttl); 1967 } 1968 putchar('\n'); 1969 1970 nilen -= sizeof(struct in6_addr); 1971 cp += sizeof(struct in6_addr); |
1461 } 1462} 1463 1464int 1465get_hoplim(mhdr) 1466 struct msghdr *mhdr; 1467{ 1468 struct cmsghdr *cm; 1469 1470 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1471 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { | 1972 } 1973} 1974 1975int 1976get_hoplim(mhdr) 1977 struct msghdr *mhdr; 1978{ 1979 struct cmsghdr *cm; 1980 1981 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1982 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { |
1983 if (cm->cmsg_len == 0) 1984 return(-1); 1985 |
|
1472 if (cm->cmsg_level == IPPROTO_IPV6 && 1473 cm->cmsg_type == IPV6_HOPLIMIT && 1474 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1475 return(*(int *)CMSG_DATA(cm)); 1476 } 1477 1478 return(-1); 1479} 1480 1481struct in6_pktinfo * 1482get_rcvpktinfo(mhdr) 1483 struct msghdr *mhdr; 1484{ 1485 struct cmsghdr *cm; 1486 1487 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1488 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { | 1986 if (cm->cmsg_level == IPPROTO_IPV6 && 1987 cm->cmsg_type == IPV6_HOPLIMIT && 1988 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1989 return(*(int *)CMSG_DATA(cm)); 1990 } 1991 1992 return(-1); 1993} 1994 1995struct in6_pktinfo * 1996get_rcvpktinfo(mhdr) 1997 struct msghdr *mhdr; 1998{ 1999 struct cmsghdr *cm; 2000 2001 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 2002 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { |
2003 if (cm->cmsg_len == 0) 2004 return(NULL); 2005 |
|
1489 if (cm->cmsg_level == IPPROTO_IPV6 && 1490 cm->cmsg_type == IPV6_PKTINFO && 1491 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) 1492 return((struct in6_pktinfo *)CMSG_DATA(cm)); 1493 } 1494 1495 return(NULL); 1496} 1497 | 2006 if (cm->cmsg_level == IPPROTO_IPV6 && 2007 cm->cmsg_type == IPV6_PKTINFO && 2008 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) 2009 return((struct in6_pktinfo *)CMSG_DATA(cm)); 2010 } 2011 2012 return(NULL); 2013} 2014 |
2015int 2016get_pathmtu(mhdr) 2017 struct msghdr *mhdr; 2018{ 2019#ifdef IPV6_RECVPATHMTU 2020 struct cmsghdr *cm; 2021 struct ip6_mtuinfo *mtuctl = NULL; 2022 2023 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 2024 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 2025 if (cm->cmsg_len == 0) 2026 return(0); 2027 2028 if (cm->cmsg_level == IPPROTO_IPV6 && 2029 cm->cmsg_type == IPV6_PATHMTU && 2030 cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) { 2031 mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm); 2032 2033 /* 2034 * If the notified destination is different from 2035 * the one we are pinging, just ignore the info. 2036 * We check the scope ID only when both notified value 2037 * and our own value have non-0 values, because we may 2038 * have used the default scope zone ID for sending, 2039 * in which case the scope ID value is 0. 2040 */ 2041 if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr, 2042 &dst.sin6_addr) || 2043 (mtuctl->ip6m_addr.sin6_scope_id && 2044 dst.sin6_scope_id && 2045 mtuctl->ip6m_addr.sin6_scope_id != 2046 dst.sin6_scope_id)) { 2047 if ((options & F_VERBOSE) != 0) { 2048 printf("path MTU for %s is notified. " 2049 "(ignored)\n", 2050 pr_addr((struct sockaddr *)&mtuctl->ip6m_addr, 2051 sizeof(mtuctl->ip6m_addr))); 2052 } 2053 return(0); 2054 } 2055 2056 /* 2057 * Ignore an invalid MTU. XXX: can we just believe 2058 * the kernel check? 2059 */ 2060 if (mtuctl->ip6m_mtu < IPV6_MMTU) 2061 return(0); 2062 2063 /* notification for our destination. return the MTU. */ 2064 return((int)mtuctl->ip6m_mtu); 2065 } 2066 } 2067#endif 2068 return(0); 2069} 2070 2071void 2072set_pathmtu(mtu) 2073 int mtu; 2074{ 2075#ifdef IPV6_USE_MTU 2076 static int firsttime = 1; 2077 struct cmsghdr *cm; 2078 2079 if (firsttime) { 2080 int oldlen = smsghdr.msg_controllen; 2081 char *oldbuf = smsghdr.msg_control; 2082 2083 /* XXX: We need to enlarge control message buffer */ 2084 firsttime = 0; /* prevent further enlargement */ 2085 2086 smsghdr.msg_controllen = oldlen + CMSG_SPACE(sizeof(int)); 2087 if ((smsghdr.msg_control = 2088 (char *)malloc(smsghdr.msg_controllen)) == NULL) 2089 err(1, "set_pathmtu: malloc"); 2090 cm = (struct cmsghdr *)CMSG_FIRSTHDR(&smsghdr); 2091 cm->cmsg_len = CMSG_LEN(sizeof(int)); 2092 cm->cmsg_level = IPPROTO_IPV6; 2093 cm->cmsg_type = IPV6_USE_MTU; 2094 2095 cm = (struct cmsghdr *)CMSG_NXTHDR(&smsghdr, cm); 2096 if (oldlen) 2097 memcpy((void *)cm, (void *)oldbuf, oldlen); 2098 2099 free(oldbuf); 2100 } 2101 2102 /* 2103 * look for a cmsgptr that points MTU structure. 2104 * XXX: this procedure seems redundant at this moment, but we'd better 2105 * keep the code generic enough for future extensions. 2106 */ 2107 for (cm = CMSG_FIRSTHDR(&smsghdr); cm; 2108 cm = (struct cmsghdr *)CMSG_NXTHDR(&smsghdr, cm)) { 2109 if (cm->cmsg_len == 0) /* XXX: paranoid check */ 2110 errx(1, "set_pathmtu: internal error"); 2111 2112 if (cm->cmsg_level == IPPROTO_IPV6 && 2113 cm->cmsg_type == IPV6_USE_MTU && 2114 cm->cmsg_len == CMSG_LEN(sizeof(int))) 2115 break; 2116 } 2117 2118 if (cm == NULL) 2119 errx(1, "set_pathmtu: internal error: no space for path MTU"); 2120 2121 *(int *)CMSG_DATA(cm) = mtu; 2122#endif 2123} 2124 |
|
1498/* 1499 * tvsub -- 1500 * Subtract 2 timeval structs: out = out - in. Out is assumed to 1501 * be >= in. 1502 */ 1503void 1504tvsub(out, in) 1505 register struct timeval *out, *in; 1506{ 1507 if ((out->tv_usec -= in->tv_usec) < 0) { 1508 --out->tv_sec; 1509 out->tv_usec += 1000000; 1510 } 1511 out->tv_sec -= in->tv_sec; 1512} 1513 1514/* | 2125/* 2126 * tvsub -- 2127 * Subtract 2 timeval structs: out = out - in. Out is assumed to 2128 * be >= in. 2129 */ 2130void 2131tvsub(out, in) 2132 register struct timeval *out, *in; 2133{ 2134 if ((out->tv_usec -= in->tv_usec) < 0) { 2135 --out->tv_sec; 2136 out->tv_usec += 1000000; 2137 } 2138 out->tv_sec -= in->tv_sec; 2139} 2140 2141/* |
1515 * oninfo -- 1516 * SIGINFO handler. 1517 */ 1518/* ARGSUSED */ 1519void 1520oninfo(notused) 1521 int notused; 1522{ 1523 summary(); 1524} 1525 1526/* | |
1527 * onint -- 1528 * SIGINT handler. 1529 */ 1530/* ARGSUSED */ 1531void 1532onint(notused) 1533 int notused; 1534{ --- 8 unchanged lines hidden (view full) --- 1543 1544/* 1545 * summary -- 1546 * Print out statistics. 1547 */ 1548void 1549summary() 1550{ | 2142 * onint -- 2143 * SIGINT handler. 2144 */ 2145/* ARGSUSED */ 2146void 2147onint(notused) 2148 int notused; 2149{ --- 8 unchanged lines hidden (view full) --- 2158 2159/* 2160 * summary -- 2161 * Print out statistics. 2162 */ 2163void 2164summary() 2165{ |
1551 register int i; | |
1552 1553 (void)printf("\n--- %s ping6 statistics ---\n", hostname); 1554 (void)printf("%ld packets transmitted, ", ntransmitted); 1555 (void)printf("%ld packets received, ", nreceived); 1556 if (nrepeats) 1557 (void)printf("+%ld duplicates, ", nrepeats); 1558 if (ntransmitted) { 1559 if (nreceived > ntransmitted) 1560 (void)printf("-- somebody's printing up packets!"); 1561 else 1562 (void)printf("%d%% packet loss", 1563 (int) (((ntransmitted - nreceived) * 100) / 1564 ntransmitted)); 1565 } 1566 (void)putchar('\n'); 1567 if (nreceived && timing) { 1568 /* Only display average to microseconds */ | 2166 2167 (void)printf("\n--- %s ping6 statistics ---\n", hostname); 2168 (void)printf("%ld packets transmitted, ", ntransmitted); 2169 (void)printf("%ld packets received, ", nreceived); 2170 if (nrepeats) 2171 (void)printf("+%ld duplicates, ", nrepeats); 2172 if (ntransmitted) { 2173 if (nreceived > ntransmitted) 2174 (void)printf("-- somebody's printing up packets!"); 2175 else 2176 (void)printf("%d%% packet loss", 2177 (int) (((ntransmitted - nreceived) * 100) / 2178 ntransmitted)); 2179 } 2180 (void)putchar('\n'); 2181 if (nreceived && timing) { 2182 /* Only display average to microseconds */ |
1569 i = 1000.0 * tsum / (nreceived + nrepeats); 1570 (void)printf("round-trip min/avg/max = %g/%g/%g ms\n", 1571 tmin, ((double)i) / 1000.0, tmax); | 2183 double num = nreceived + nrepeats; 2184 double avg = tsum / num; 2185#if defined(__OpenBSD__) || defined(__NetBSD__) 2186 double dev = sqrt(tsumsq / num - avg * avg); 2187 (void)printf( 2188 "round-trip min/avg/max/std-dev = %.3f/%.3f/%.3f/%.3f ms\n", 2189 tmin, avg, tmax, dev); 2190#else 2191 (void)printf( 2192 "round-trip min/avg/max = %.3f/%.3f/%.3f ms\n", 2193 tmin, avg, tmax); 2194#endif |
1572 (void)fflush(stdout); 1573 } | 2195 (void)fflush(stdout); 2196 } |
2197 (void)fflush(stdout); |
|
1574} 1575 | 2198} 2199 |
1576#ifdef notdef 1577static char *ttab[] = { 1578 "Echo Reply", /* ip + seq + udata */ 1579 "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */ 1580 "Source Quench", /* IP */ 1581 "Redirect", /* redirect type, gateway, + IP */ 1582 "Echo", 1583 "Time Exceeded", /* transit, frag reassem + IP */ 1584 "Parameter Problem", /* pointer + IP */ 1585 "Timestamp", /* id + seq + three timestamps */ 1586 "Timestamp Reply", /* " */ 1587 "Info Request", /* id + sq */ 1588 "Info Reply" /* " */ | 2200/*subject type*/ 2201static char *niqcode[] = { 2202 "IPv6 address", 2203 "DNS label", /*or empty*/ 2204 "IPv4 address", |
1589}; | 2205}; |
1590#endif | |
1591 | 2206 |
2207/*result code*/ 2208static char *nircode[] = { 2209 "Success", "Refused", "Unknown", 2210}; 2211 2212 |
|
1592/* 1593 * pr_icmph -- 1594 * Print a descriptive string about an ICMP header. 1595 */ 1596void 1597pr_icmph(icp, end) 1598 struct icmp6_hdr *icp; 1599 u_char *end; 1600{ 1601 char ntop_buf[INET6_ADDRSTRLEN]; | 2213/* 2214 * pr_icmph -- 2215 * Print a descriptive string about an ICMP header. 2216 */ 2217void 2218pr_icmph(icp, end) 2219 struct icmp6_hdr *icp; 2220 u_char *end; 2221{ 2222 char ntop_buf[INET6_ADDRSTRLEN]; |
2223 struct nd_redirect *red; 2224 struct icmp6_nodeinfo *ni; 2225 char dnsname[MAXDNAME + 1]; 2226 const u_char *cp; 2227 size_t l; |
|
1602 | 2228 |
1603 switch(icp->icmp6_type) { | 2229 switch (icp->icmp6_type) { |
1604 case ICMP6_DST_UNREACH: | 2230 case ICMP6_DST_UNREACH: |
1605 switch(icp->icmp6_code) { | 2231 switch (icp->icmp6_code) { |
1606 case ICMP6_DST_UNREACH_NOROUTE: 1607 (void)printf("No Route to Destination\n"); 1608 break; 1609 case ICMP6_DST_UNREACH_ADMIN: 1610 (void)printf("Destination Administratively " | 2232 case ICMP6_DST_UNREACH_NOROUTE: 2233 (void)printf("No Route to Destination\n"); 2234 break; 2235 case ICMP6_DST_UNREACH_ADMIN: 2236 (void)printf("Destination Administratively " |
1611 "Unreachable\n"); | 2237 "Unreachable\n"); |
1612 break; 1613 case ICMP6_DST_UNREACH_BEYONDSCOPE: 1614 (void)printf("Destination Unreachable Beyond Scope\n"); 1615 break; 1616 case ICMP6_DST_UNREACH_ADDR: 1617 (void)printf("Destination Host Unreachable\n"); 1618 break; 1619 case ICMP6_DST_UNREACH_NOPORT: --- 4 unchanged lines hidden (view full) --- 1624 icp->icmp6_code); 1625 break; 1626 } 1627 /* Print returned IP header information */ 1628 pr_retip((struct ip6_hdr *)(icp + 1), end); 1629 break; 1630 case ICMP6_PACKET_TOO_BIG: 1631 (void)printf("Packet too big mtu = %d\n", | 2238 break; 2239 case ICMP6_DST_UNREACH_BEYONDSCOPE: 2240 (void)printf("Destination Unreachable Beyond Scope\n"); 2241 break; 2242 case ICMP6_DST_UNREACH_ADDR: 2243 (void)printf("Destination Host Unreachable\n"); 2244 break; 2245 case ICMP6_DST_UNREACH_NOPORT: --- 4 unchanged lines hidden (view full) --- 2250 icp->icmp6_code); 2251 break; 2252 } 2253 /* Print returned IP header information */ 2254 pr_retip((struct ip6_hdr *)(icp + 1), end); 2255 break; 2256 case ICMP6_PACKET_TOO_BIG: 2257 (void)printf("Packet too big mtu = %d\n", |
1632 (int)ntohl(icp->icmp6_mtu)); | 2258 (int)ntohl(icp->icmp6_mtu)); |
1633 pr_retip((struct ip6_hdr *)(icp + 1), end); 1634 break; 1635 case ICMP6_TIME_EXCEEDED: | 2259 pr_retip((struct ip6_hdr *)(icp + 1), end); 2260 break; 2261 case ICMP6_TIME_EXCEEDED: |
1636 switch(icp->icmp6_code) { | 2262 switch (icp->icmp6_code) { |
1637 case ICMP6_TIME_EXCEED_TRANSIT: 1638 (void)printf("Time to live exceeded\n"); 1639 break; 1640 case ICMP6_TIME_EXCEED_REASSEMBLY: 1641 (void)printf("Frag reassembly time exceeded\n"); 1642 break; 1643 default: 1644 (void)printf("Time exceeded, Bad Code: %d\n", 1645 icp->icmp6_code); 1646 break; 1647 } 1648 pr_retip((struct ip6_hdr *)(icp + 1), end); 1649 break; 1650 case ICMP6_PARAM_PROB: 1651 (void)printf("Parameter problem: "); | 2263 case ICMP6_TIME_EXCEED_TRANSIT: 2264 (void)printf("Time to live exceeded\n"); 2265 break; 2266 case ICMP6_TIME_EXCEED_REASSEMBLY: 2267 (void)printf("Frag reassembly time exceeded\n"); 2268 break; 2269 default: 2270 (void)printf("Time exceeded, Bad Code: %d\n", 2271 icp->icmp6_code); 2272 break; 2273 } 2274 pr_retip((struct ip6_hdr *)(icp + 1), end); 2275 break; 2276 case ICMP6_PARAM_PROB: 2277 (void)printf("Parameter problem: "); |
1652 switch(icp->icmp6_code) { 1653 case ICMP6_PARAMPROB_HEADER: 1654 (void)printf("Erroneous Header "); 1655 break; 1656 case ICMP6_PARAMPROB_NEXTHEADER: 1657 (void)printf("Unknown Nextheader "); 1658 break; 1659 case ICMP6_PARAMPROB_OPTION: 1660 (void)printf("Unrecognized Option "); 1661 break; 1662 default: 1663 (void)printf("Bad code(%d) ", icp->icmp6_code); 1664 break; | 2278 switch (icp->icmp6_code) { 2279 case ICMP6_PARAMPROB_HEADER: 2280 (void)printf("Erroneous Header "); 2281 break; 2282 case ICMP6_PARAMPROB_NEXTHEADER: 2283 (void)printf("Unknown Nextheader "); 2284 break; 2285 case ICMP6_PARAMPROB_OPTION: 2286 (void)printf("Unrecognized Option "); 2287 break; 2288 default: 2289 (void)printf("Bad code(%d) ", icp->icmp6_code); 2290 break; |
1665 } 1666 (void)printf("pointer = 0x%02x\n", | 2291 } 2292 (void)printf("pointer = 0x%02x\n", |
1667 (int)ntohl(icp->icmp6_pptr)); | 2293 (u_int32_t)ntohl(icp->icmp6_pptr)); |
1668 pr_retip((struct ip6_hdr *)(icp + 1), end); 1669 break; 1670 case ICMP6_ECHO_REQUEST: 1671 (void)printf("Echo Request"); 1672 /* XXX ID + Seq + Data */ 1673 break; 1674 case ICMP6_ECHO_REPLY: 1675 (void)printf("Echo Reply"); --- 16 unchanged lines hidden (view full) --- 1692 break; 1693 case ND_NEIGHBOR_SOLICIT: 1694 (void)printf("Neighbor Solicitation"); 1695 break; 1696 case ND_NEIGHBOR_ADVERT: 1697 (void)printf("Neighbor Advertisement"); 1698 break; 1699 case ND_REDIRECT: | 2294 pr_retip((struct ip6_hdr *)(icp + 1), end); 2295 break; 2296 case ICMP6_ECHO_REQUEST: 2297 (void)printf("Echo Request"); 2298 /* XXX ID + Seq + Data */ 2299 break; 2300 case ICMP6_ECHO_REPLY: 2301 (void)printf("Echo Reply"); --- 16 unchanged lines hidden (view full) --- 2318 break; 2319 case ND_NEIGHBOR_SOLICIT: 2320 (void)printf("Neighbor Solicitation"); 2321 break; 2322 case ND_NEIGHBOR_ADVERT: 2323 (void)printf("Neighbor Advertisement"); 2324 break; 2325 case ND_REDIRECT: |
1700 { 1701 struct nd_redirect *red = (struct nd_redirect *)icp; 1702 | 2326 red = (struct nd_redirect *)icp; |
1703 (void)printf("Redirect\n"); | 2327 (void)printf("Redirect\n"); |
1704 (void)printf("Destination: %s", 1705 inet_ntop(AF_INET6, &red->nd_rd_dst, 1706 ntop_buf, sizeof(ntop_buf))); 1707 (void)printf("New Target: %s", 1708 inet_ntop(AF_INET6, &red->nd_rd_target, 1709 ntop_buf, sizeof(ntop_buf))); | 2328 if (!inet_ntop(AF_INET6, &red->nd_rd_dst, ntop_buf, 2329 sizeof(ntop_buf))) 2330 strncpy(ntop_buf, "?", sizeof(ntop_buf)); 2331 (void)printf("Destination: %s", ntop_buf); 2332 if (!inet_ntop(AF_INET6, &red->nd_rd_target, ntop_buf, 2333 sizeof(ntop_buf))) 2334 strncpy(ntop_buf, "?", sizeof(ntop_buf)); 2335 (void)printf(" New Target: %s", ntop_buf); |
1710 break; | 2336 break; |
1711 } | |
1712 case ICMP6_NI_QUERY: 1713 (void)printf("Node Information Query"); 1714 /* XXX ID + Seq + Data */ | 2337 case ICMP6_NI_QUERY: 2338 (void)printf("Node Information Query"); 2339 /* XXX ID + Seq + Data */ |
2340 ni = (struct icmp6_nodeinfo *)icp; 2341 l = end - (u_char *)(ni + 1); 2342 printf(", "); 2343 switch (ntohs(ni->ni_qtype)) { 2344 case NI_QTYPE_NOOP: 2345 (void)printf("NOOP"); 2346 break; 2347 case NI_QTYPE_SUPTYPES: 2348 (void)printf("Supported qtypes"); 2349 break; 2350 case NI_QTYPE_FQDN: 2351 (void)printf("DNS name"); 2352 break; 2353 case NI_QTYPE_NODEADDR: 2354 (void)printf("nodeaddr"); 2355 break; 2356 case NI_QTYPE_IPV4ADDR: 2357 (void)printf("IPv4 nodeaddr"); 2358 break; 2359 default: 2360 (void)printf("unknown qtype"); 2361 break; 2362 } 2363 if (options & F_VERBOSE) { 2364 switch (ni->ni_code) { 2365 case ICMP6_NI_SUBJ_IPV6: 2366 if (l == sizeof(struct in6_addr) && 2367 inet_ntop(AF_INET6, ni + 1, ntop_buf, 2368 sizeof(ntop_buf)) != NULL) { 2369 (void)printf(", subject=%s(%s)", 2370 niqcode[ni->ni_code], ntop_buf); 2371 } else { 2372#if 1 2373 /* backward compat to -W */ 2374 (void)printf(", oldfqdn"); 2375#else 2376 (void)printf(", invalid"); 2377#endif 2378 } 2379 break; 2380 case ICMP6_NI_SUBJ_FQDN: 2381 if (end == (u_char *)(ni + 1)) { 2382 (void)printf(", no subject"); 2383 break; 2384 } 2385 printf(", subject=%s", niqcode[ni->ni_code]); 2386 cp = (const u_char *)(ni + 1); 2387 if (dnsdecode(&cp, end, NULL, dnsname, 2388 sizeof(dnsname)) != NULL) 2389 printf("(%s)", dnsname); 2390 else 2391 printf("(invalid)"); 2392 break; 2393 case ICMP6_NI_SUBJ_IPV4: 2394 if (l == sizeof(struct in_addr) && 2395 inet_ntop(AF_INET, ni + 1, ntop_buf, 2396 sizeof(ntop_buf)) != NULL) { 2397 (void)printf(", subject=%s(%s)", 2398 niqcode[ni->ni_code], ntop_buf); 2399 } else 2400 (void)printf(", invalid"); 2401 break; 2402 default: 2403 (void)printf(", invalid"); 2404 break; 2405 } 2406 } |
|
1715 break; 1716 case ICMP6_NI_REPLY: 1717 (void)printf("Node Information Reply"); 1718 /* XXX ID + Seq + Data */ | 2407 break; 2408 case ICMP6_NI_REPLY: 2409 (void)printf("Node Information Reply"); 2410 /* XXX ID + Seq + Data */ |
2411 ni = (struct icmp6_nodeinfo *)icp; 2412 printf(", "); 2413 switch (ntohs(ni->ni_qtype)) { 2414 case NI_QTYPE_NOOP: 2415 (void)printf("NOOP"); 2416 break; 2417 case NI_QTYPE_SUPTYPES: 2418 (void)printf("Supported qtypes"); 2419 break; 2420 case NI_QTYPE_FQDN: 2421 (void)printf("DNS name"); 2422 break; 2423 case NI_QTYPE_NODEADDR: 2424 (void)printf("nodeaddr"); 2425 break; 2426 case NI_QTYPE_IPV4ADDR: 2427 (void)printf("IPv4 nodeaddr"); 2428 break; 2429 default: 2430 (void)printf("unknown qtype"); 2431 break; 2432 } 2433 if (options & F_VERBOSE) { 2434 if (ni->ni_code > sizeof(nircode) / sizeof(nircode[0])) 2435 printf(", invalid"); 2436 else 2437 printf(", %s", nircode[ni->ni_code]); 2438 } |
|
1719 break; 1720 default: 1721 (void)printf("Bad ICMP type: %d", icp->icmp6_type); 1722 } 1723} 1724 1725/* 1726 * pr_iph -- --- 8 unchanged lines hidden (view full) --- 1735 char ntop_buf[INET6_ADDRSTRLEN]; 1736 1737 tc = *(&ip6->ip6_vfc + 1); /* XXX */ 1738 tc = (tc >> 4) & 0x0f; 1739 tc |= (ip6->ip6_vfc << 4); 1740 1741 printf("Vr TC Flow Plen Nxt Hlim\n"); 1742 printf(" %1x %02x %05x %04x %02x %02x\n", | 2439 break; 2440 default: 2441 (void)printf("Bad ICMP type: %d", icp->icmp6_type); 2442 } 2443} 2444 2445/* 2446 * pr_iph -- --- 8 unchanged lines hidden (view full) --- 2455 char ntop_buf[INET6_ADDRSTRLEN]; 2456 2457 tc = *(&ip6->ip6_vfc + 1); /* XXX */ 2458 tc = (tc >> 4) & 0x0f; 2459 tc |= (ip6->ip6_vfc << 4); 2460 2461 printf("Vr TC Flow Plen Nxt Hlim\n"); 2462 printf(" %1x %02x %05x %04x %02x %02x\n", |
1743 (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (int)ntohl(flow), 1744 ntohs(ip6->ip6_plen), 1745 ip6->ip6_nxt, ip6->ip6_hlim); 1746 printf("%s->", inet_ntop(AF_INET6, &ip6->ip6_src, 1747 ntop_buf, sizeof(ntop_buf))); 1748 printf("%s\n", inet_ntop(AF_INET6, &ip6->ip6_dst, 1749 ntop_buf, sizeof(ntop_buf))); | 2463 (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow), 2464 ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim); 2465 if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf))) 2466 strncpy(ntop_buf, "?", sizeof(ntop_buf)); 2467 printf("%s->", ntop_buf); 2468 if (!inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf))) 2469 strncpy(ntop_buf, "?", sizeof(ntop_buf)); 2470 printf("%s\n", ntop_buf); |
1750} 1751 1752/* 1753 * pr_addr -- 1754 * Return an ascii host address as a dotted quad and optionally with 1755 * a hostname. 1756 */ 1757const char * | 2471} 2472 2473/* 2474 * pr_addr -- 2475 * Return an ascii host address as a dotted quad and optionally with 2476 * a hostname. 2477 */ 2478const char * |
1758pr_addr(addr) 1759 struct sockaddr_in6 *addr; | 2479pr_addr(addr, addrlen) 2480 struct sockaddr *addr; 2481 int addrlen; |
1760{ | 2482{ |
1761 static char buf[MAXHOSTNAMELEN]; 1762 int flag = 0; | 2483 static char buf[NI_MAXHOST]; 2484 int flag; |
1763 | 2485 |
2486#ifdef NI_WITHSCOPEID 2487 flag = NI_WITHSCOPEID; 2488#else 2489 flag = 0; 2490#endif |
|
1764 if ((options & F_HOSTNAME) == 0) 1765 flag |= NI_NUMERICHOST; | 2491 if ((options & F_HOSTNAME) == 0) 2492 flag |= NI_NUMERICHOST; |
1766#ifdef KAME_SCOPEID 1767 flag |= NI_WITHSCOPEID; 1768#endif | |
1769 | 2493 |
1770 getnameinfo((struct sockaddr *)addr, addr->sin6_len, buf, sizeof(buf), 1771 NULL, 0, flag); 1772 1773 return (buf); | 2494 if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0) 2495 return (buf); 2496 else 2497 return "?"; |
1774} 1775 1776/* 1777 * pr_retip -- 1778 * Dump some info on a returned (via ICMPv6) IPv6 packet. 1779 */ 1780void 1781pr_retip(ip6, end) --- 9 unchanged lines hidden (view full) --- 1791 } 1792 pr_iph(ip6); 1793 hlen = sizeof(*ip6); 1794 1795 nh = ip6->ip6_nxt; 1796 cp += hlen; 1797 while (end - cp >= 8) { 1798 switch (nh) { | 2498} 2499 2500/* 2501 * pr_retip -- 2502 * Dump some info on a returned (via ICMPv6) IPv6 packet. 2503 */ 2504void 2505pr_retip(ip6, end) --- 9 unchanged lines hidden (view full) --- 2515 } 2516 pr_iph(ip6); 2517 hlen = sizeof(*ip6); 2518 2519 nh = ip6->ip6_nxt; 2520 cp += hlen; 2521 while (end - cp >= 8) { 2522 switch (nh) { |
1799 case IPPROTO_HOPOPTS: 1800 printf("HBH "); 1801 hlen = (((struct ip6_hbh *)cp)->ip6h_len+1) << 3; 1802 nh = ((struct ip6_hbh *)cp)->ip6h_nxt; 1803 break; 1804 case IPPROTO_DSTOPTS: 1805 printf("DSTOPT "); 1806 hlen = (((struct ip6_dest *)cp)->ip6d_len+1) << 3; 1807 nh = ((struct ip6_dest *)cp)->ip6d_nxt; 1808 break; 1809 case IPPROTO_FRAGMENT: 1810 printf("FRAG "); 1811 hlen = sizeof(struct ip6_frag); 1812 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 1813 break; 1814 case IPPROTO_ROUTING: 1815 printf("RTHDR "); 1816 hlen = (((struct ip6_rthdr *)cp)->ip6r_len+1) << 3; 1817 nh = ((struct ip6_rthdr *)cp)->ip6r_nxt; 1818 break; | 2523 case IPPROTO_HOPOPTS: 2524 printf("HBH "); 2525 hlen = (((struct ip6_hbh *)cp)->ip6h_len+1) << 3; 2526 nh = ((struct ip6_hbh *)cp)->ip6h_nxt; 2527 break; 2528 case IPPROTO_DSTOPTS: 2529 printf("DSTOPT "); 2530 hlen = (((struct ip6_dest *)cp)->ip6d_len+1) << 3; 2531 nh = ((struct ip6_dest *)cp)->ip6d_nxt; 2532 break; 2533 case IPPROTO_FRAGMENT: 2534 printf("FRAG "); 2535 hlen = sizeof(struct ip6_frag); 2536 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 2537 break; 2538 case IPPROTO_ROUTING: 2539 printf("RTHDR "); 2540 hlen = (((struct ip6_rthdr *)cp)->ip6r_len+1) << 3; 2541 nh = ((struct ip6_rthdr *)cp)->ip6r_nxt; 2542 break; |
1819#ifdef IPSEC | 2543#ifdef IPSEC |
1820 case IPPROTO_AH: 1821 printf("AH "); 1822 hlen = (((struct ah *)cp)->ah_len+2) << 2; 1823 nh = ((struct ah *)cp)->ah_nxt; 1824 break; | 2544 case IPPROTO_AH: 2545 printf("AH "); 2546 hlen = (((struct ah *)cp)->ah_len+2) << 2; 2547 nh = ((struct ah *)cp)->ah_nxt; 2548 break; |
1825#endif | 2549#endif |
1826 case IPPROTO_ICMPV6: 1827 printf("ICMP6: type = %d, code = %d\n", 1828 *cp, *(cp + 1)); 1829 return; 1830 case IPPROTO_ESP: 1831 printf("ESP\n"); 1832 return; 1833 case IPPROTO_TCP: 1834 printf("TCP: from port %u, to port %u (decimal)\n", 1835 (*cp * 256 + *(cp + 1)), 1836 (*(cp + 2) * 256 + *(cp + 3))); 1837 return; 1838 case IPPROTO_UDP: 1839 printf("UDP: from port %u, to port %u (decimal)\n", 1840 (*cp * 256 + *(cp + 1)), 1841 (*(cp + 2) * 256 + *(cp + 3))); 1842 return; 1843 default: 1844 printf("Unknown Header(%d)\n", nh); 1845 return; | 2550 case IPPROTO_ICMPV6: 2551 printf("ICMP6: type = %d, code = %d\n", 2552 *cp, *(cp + 1)); 2553 return; 2554 case IPPROTO_ESP: 2555 printf("ESP\n"); 2556 return; 2557 case IPPROTO_TCP: 2558 printf("TCP: from port %u, to port %u (decimal)\n", 2559 (*cp * 256 + *(cp + 1)), 2560 (*(cp + 2) * 256 + *(cp + 3))); 2561 return; 2562 case IPPROTO_UDP: 2563 printf("UDP: from port %u, to port %u (decimal)\n", 2564 (*cp * 256 + *(cp + 1)), 2565 (*(cp + 2) * 256 + *(cp + 3))); 2566 return; 2567 default: 2568 printf("Unknown Header(%d)\n", nh); 2569 return; |
1846 } 1847 1848 if ((cp += hlen) >= end) 1849 goto trunc; 1850 } 1851 if (end - cp < 8) 1852 goto trunc; 1853 --- 17 unchanged lines hidden (view full) --- 1871 if (!isxdigit(*cp)) 1872 errx(1, "patterns must be specified as hex digits"); 1873 ii = sscanf(patp, 1874 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1875 &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], 1876 &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], 1877 &pat[13], &pat[14], &pat[15]); 1878 | 2570 } 2571 2572 if ((cp += hlen) >= end) 2573 goto trunc; 2574 } 2575 if (end - cp < 8) 2576 goto trunc; 2577 --- 17 unchanged lines hidden (view full) --- 2595 if (!isxdigit(*cp)) 2596 errx(1, "patterns must be specified as hex digits"); 2597 ii = sscanf(patp, 2598 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 2599 &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], 2600 &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], 2601 &pat[13], &pat[14], &pat[15]); 2602 |
1879/* xxx */ | 2603/* xxx */ |
1880 if (ii > 0) 1881 for (kk = 0; 1882 kk <= MAXDATALEN - (8 + sizeof(struct timeval) + ii); 1883 kk += ii) 1884 for (jj = 0; jj < ii; ++jj) 1885 bp[jj + kk] = pat[jj]; 1886 if (!(options & F_QUIET)) { 1887 (void)printf("PATTERN: 0x"); --- 13 unchanged lines hidden (view full) --- 1901 char *buf; 1902 1903 if (policy == NULL) 1904 return 0; /* ignore */ 1905 1906 buf = ipsec_set_policy(policy, strlen(policy)); 1907 if (buf == NULL) 1908 errx(1, "%s", ipsec_strerror()); | 2604 if (ii > 0) 2605 for (kk = 0; 2606 kk <= MAXDATALEN - (8 + sizeof(struct timeval) + ii); 2607 kk += ii) 2608 for (jj = 0; jj < ii; ++jj) 2609 bp[jj + kk] = pat[jj]; 2610 if (!(options & F_QUIET)) { 2611 (void)printf("PATTERN: 0x"); --- 13 unchanged lines hidden (view full) --- 2625 char *buf; 2626 2627 if (policy == NULL) 2628 return 0; /* ignore */ 2629 2630 buf = ipsec_set_policy(policy, strlen(policy)); 2631 if (buf == NULL) 2632 errx(1, "%s", ipsec_strerror()); |
1909 if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, 1910 buf, ipsec_get_policylen(buf)) < 0) | 2633 if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, 2634 ipsec_get_policylen(buf)) < 0) |
1911 warnx("Unable to set IPSec policy"); 1912 free(buf); 1913 1914 return 0; 1915} 1916#endif 1917#endif 1918 1919char * 1920nigroup(name) 1921 char *name; 1922{ 1923 char *p; | 2635 warnx("Unable to set IPSec policy"); 2636 free(buf); 2637 2638 return 0; 2639} 2640#endif 2641#endif 2642 2643char * 2644nigroup(name) 2645 char *name; 2646{ 2647 char *p; |
2648 unsigned char *q; |
|
1924 MD5_CTX ctxt; 1925 u_int8_t digest[16]; | 2649 MD5_CTX ctxt; 2650 u_int8_t digest[16]; |
1926 char l; | 2651 u_int8_t c; 2652 size_t l; |
1927 char hbuf[NI_MAXHOST]; 1928 struct in6_addr in6; 1929 | 2653 char hbuf[NI_MAXHOST]; 2654 struct in6_addr in6; 2655 |
1930 p = name; 1931 while (p && *p && *p != '.') 1932 p++; 1933 if (p - name > 63) 1934 return NULL; /*label too long*/ | 2656 p = strchr(name, '.'); 2657 if (!p) 2658 p = name + strlen(name); |
1935 l = p - name; | 2659 l = p - name; |
2660 if (l > 63 || l > sizeof(hbuf) - 1) 2661 return NULL; /*label too long*/ 2662 strncpy(hbuf, name, l); 2663 hbuf[(int)l] = '\0'; |
|
1936 | 2664 |
2665 for (q = name; *q; q++) { 2666 if (isupper(*q)) 2667 *q = tolower(*q); 2668 } 2669 |
|
1937 /* generate 8 bytes of pseudo-random value. */ 1938 bzero(&ctxt, sizeof(ctxt)); 1939 MD5Init(&ctxt); | 2670 /* generate 8 bytes of pseudo-random value. */ 2671 bzero(&ctxt, sizeof(ctxt)); 2672 MD5Init(&ctxt); |
1940 MD5Update(&ctxt, &l, sizeof(l)); 1941 MD5Update(&ctxt, name, p - name); | 2673 c = l & 0xff; 2674 MD5Update(&ctxt, &c, sizeof(c)); 2675 MD5Update(&ctxt, name, l); |
1942 MD5Final(digest, &ctxt); 1943 | 2676 MD5Final(digest, &ctxt); 2677 |
1944 bzero(&in6, sizeof(in6)); 1945 in6.s6_addr[0] = 0xff; 1946 in6.s6_addr[1] = 0x02; 1947 in6.s6_addr[11] = 0x02; | 2678 if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1) 2679 return NULL; /*XXX*/ |
1948 bcopy(digest, &in6.s6_addr[12], 4); 1949 1950 if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) 1951 return NULL; 1952 1953 return strdup(hbuf); 1954} 1955 1956void 1957usage() 1958{ 1959 (void)fprintf(stderr, | 2680 bcopy(digest, &in6.s6_addr[12], 4); 2681 2682 if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) 2683 return NULL; 2684 2685 return strdup(hbuf); 2686} 2687 2688void 2689usage() 2690{ 2691 (void)fprintf(stderr, |
1960"usage: ping6 [-dfHnNqvwW" | 2692 "usage: ping6 [-dfHmnNqvwW" |
1961#ifdef IPV6_REACHCONF | 2693#ifdef IPV6_REACHCONF |
1962 "R" | 2694 "R" |
1963#endif 1964#ifdef IPSEC 1965#ifdef IPSEC_POLICY_IPSEC | 2695#endif 2696#ifdef IPSEC 2697#ifdef IPSEC_POLICY_IPSEC |
1966 "] [-P policy" | 2698 "] [-P policy" |
1967#else | 2699#else |
1968 "AE" | 2700 "AE" |
1969#endif | 2701#endif |
1970#endif 1971 "] [-a [aAclsg]] [-b sockbufsiz] [-c count] \n\ 1972 [-I interface] [-i wait] [-l preload] [-p pattern] [-S sourceaddr]\n\ 1973 [-s packetsize] [-h hoplimit] [hops...] host\n"); | 2702#endif 2703 "] [-a [aAclsg]] [-b sockbufsiz] [-c count] \n" 2704 "\t[-I interface] [-i wait] [-l preload] [-p pattern] " 2705 "[-S sourceaddr]\n" 2706 "\t[-s packetsize] [-h hoplimit] [hops...] host\n"); |
1974 exit(1); 1975} | 2707 exit(1); 2708} |