Deleted Added
full compact
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}