inet6.c revision 1.28 1 /* $NetBSD: inet6.c,v 1.28 2003/08/07 11:15:19 agc Exp $ */
2 /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1983, 1988, 1993
35 * The Regents of the University of California. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 */
61
62 #include <sys/cdefs.h>
63 #ifndef lint
64 #if 0
65 static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94";
66 #else
67 __RCSID("$NetBSD: inet6.c,v 1.28 2003/08/07 11:15:19 agc Exp $");
68 #endif
69 #endif /* not lint */
70
71 #include <sys/param.h>
72 #include <sys/socket.h>
73 #include <sys/socketvar.h>
74 #include <sys/ioctl.h>
75 #include <sys/mbuf.h>
76 #include <sys/protosw.h>
77
78 #include <net/route.h>
79 #include <net/if.h>
80 #include <netinet/in.h>
81 #include <netinet/ip6.h>
82 #include <netinet/icmp6.h>
83 #include <netinet/in_systm.h>
84 #ifndef TCP6
85 #include <netinet/ip.h>
86 #include <netinet/ip_var.h>
87 #endif
88 #include <netinet6/ip6_var.h>
89 #include <netinet6/in6_pcb.h>
90 #include <netinet6/in6_var.h>
91 #include <netinet6/ip6_var.h>
92 #ifdef TCP6
93 #include <netinet6/tcp6.h>
94 #include <netinet6/tcp6_seq.h>
95 #define TCP6STATES
96 #include <netinet6/tcp6_fsm.h>
97 #define TCP6TIMERS
98 #include <netinet6/tcp6_timer.h>
99 #include <netinet6/tcp6_var.h>
100 #include <netinet6/tcp6_debug.h>
101 #else
102 #include <netinet/tcp.h>
103 #include <netinet/tcpip.h>
104 #include <netinet/tcp_seq.h>
105 /*#define TCPSTATES*/
106 #include <netinet/tcp_fsm.h>
107 extern char *tcpstates[];
108 /*#define TCPTIMERS*/
109 #include <netinet/tcp_timer.h>
110 #include <netinet/tcp_var.h>
111 #include <netinet/tcp_debug.h>
112 #endif /*TCP6*/
113 #include <netinet6/udp6.h>
114 #include <netinet6/udp6_var.h>
115 #include <netinet6/pim6_var.h>
116 #include <netinet6/raw_ip6.h>
117
118 #include <arpa/inet.h>
119 #if 0
120 #include "gethostbyname2.h"
121 #endif
122 #include <netdb.h>
123
124 #include <stdio.h>
125 #include <string.h>
126 #include <unistd.h>
127 #include "netstat.h"
128
129 #ifdef INET6
130
131 struct in6pcb in6pcb;
132 #ifdef TCP6
133 struct tcp6cb tcp6cb;
134 #else
135 struct tcpcb tcpcb;
136 #endif
137 struct socket sockb;
138
139 char *inet6name __P((struct in6_addr *));
140 void inet6print __P((struct in6_addr *, int, char *));
141
142 /*
143 * Print a summary of connections related to an Internet
144 * protocol. For TCP, also give state of connection.
145 * Listening processes (aflag) are suppressed unless the
146 * -a (all) flag is specified.
147 */
148 void
149 ip6protopr(off, name)
150 u_long off;
151 char *name;
152 {
153 struct in6pcb cb;
154 register struct in6pcb *prev, *next;
155 int istcp;
156 static int first = 1;
157 int width = 22;
158 if (off == 0)
159 return;
160 istcp = strcmp(name, "tcp6") == 0;
161 kread(off, (char *)&cb, sizeof (struct in6pcb));
162 in6pcb = cb;
163 prev = (struct in6pcb *)off;
164 if (in6pcb.in6p_next == (struct in6pcb *)off)
165 return;
166 while (in6pcb.in6p_next != (struct in6pcb *)off) {
167 next = in6pcb.in6p_next;
168 kread((u_long)next, (char *)&in6pcb, sizeof (in6pcb));
169 if (in6pcb.in6p_prev != prev) {
170 printf("???\n");
171 break;
172 }
173 if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&in6pcb.in6p_laddr)) {
174 prev = next;
175 continue;
176 }
177 kread((u_long)in6pcb.in6p_socket, (char *)&sockb, sizeof (sockb));
178 if (istcp) {
179 #ifdef TCP6
180 kread((u_long)in6pcb.in6p_ppcb,
181 (char *)&tcp6cb, sizeof (tcp6cb));
182 #else
183 kread((u_long)in6pcb.in6p_ppcb,
184 (char *)&tcpcb, sizeof (tcpcb));
185 #endif
186 }
187 if (first) {
188 printf("Active Internet6 connections");
189 if (aflag)
190 printf(" (including servers)");
191 putchar('\n');
192 if (Aflag) {
193 printf("%-8.8s ", "PCB");
194 width = 18;
195 }
196 printf( "%-5.5s %-6.6s %-6.6s %*.*s %*.*s %s\n",
197 "Proto", "Recv-Q", "Send-Q",
198 -width, width, "Local Address",
199 -width, width, "Foreign Address",
200 "(state)");
201 first = 0;
202 }
203 if (Aflag) {
204 if (istcp)
205 printf("%8lx ", (u_long) in6pcb.in6p_ppcb);
206 else
207 printf("%8lx ", (u_long) next);
208 }
209 printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
210 sockb.so_snd.sb_cc);
211 /* xxx */
212 inet6print(&in6pcb.in6p_laddr, (int)in6pcb.in6p_lport, name);
213 inet6print(&in6pcb.in6p_faddr, (int)in6pcb.in6p_fport, name);
214 if (istcp) {
215 #ifdef TCP6
216 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
217 printf(" %d", tcp6cb.t_state);
218 else
219 printf(" %s", tcp6states[tcp6cb.t_state]);
220 #else
221 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
222 printf(" %d", tcpcb.t_state);
223 else
224 printf(" %s", tcpstates[tcpcb.t_state]);
225 #endif
226 }
227 putchar('\n');
228 prev = next;
229 }
230 }
231
232 #ifdef TCP6
233 /*
234 * Dump TCP6 statistics structure.
235 */
236 void
237 tcp6_stats(off, name)
238 u_long off;
239 char *name;
240 {
241 struct tcp6stat tcp6stat;
242
243 if (off == 0)
244 return;
245 printf ("%s:\n", name);
246 kread(off, (char *)&tcp6stat, sizeof (tcp6stat));
247
248 #define p(f, m) if (tcp6stat.f || sflag <= 1) \
249 printf(m, tcp6stat.f, plural(tcp6stat.f))
250 #define p2(f1, f2, m) if (tcp6stat.f1 || tcp6stat.f2 || sflag <= 1) \
251 printf(m, tcp6stat.f1, plural(tcp6stat.f1), tcp6stat.f2, plural(tcp6stat.f2))
252 #define p3(f, m) if (tcp6stat.f || sflag <= 1) \
253 printf(m, tcp6stat.f, plurales(tcp6stat.f))
254
255 p(tcp6s_sndtotal, "\t%ld packet%s sent\n");
256 p2(tcp6s_sndpack,tcp6s_sndbyte,
257 "\t\t%ld data packet%s (%ld byte%s)\n");
258 p2(tcp6s_sndrexmitpack, tcp6s_sndrexmitbyte,
259 "\t\t%ld data packet%s (%ld byte%s) retransmitted\n");
260 p2(tcp6s_sndacks, tcp6s_delack,
261 "\t\t%ld ack-only packet%s (%ld packet%s delayed)\n");
262 p(tcp6s_sndurg, "\t\t%ld URG only packet%s\n");
263 p(tcp6s_sndprobe, "\t\t%ld window probe packet%s\n");
264 p(tcp6s_sndwinup, "\t\t%ld window update packet%s\n");
265 p(tcp6s_sndctrl, "\t\t%ld control packet%s\n");
266 p(tcp6s_rcvtotal, "\t%ld packet%s received\n");
267 p2(tcp6s_rcvackpack, tcp6s_rcvackbyte, "\t\t%ld ack%s (for %ld byte%s)\n");
268 p(tcp6s_rcvdupack, "\t\t%ld duplicate ack%s\n");
269 p(tcp6s_rcvacktoomuch, "\t\t%ld ack%s for unsent data\n");
270 p2(tcp6s_rcvpack, tcp6s_rcvbyte,
271 "\t\t%ld packet%s (%ld byte%s) received in-sequence\n");
272 p2(tcp6s_rcvduppack, tcp6s_rcvdupbyte,
273 "\t\t%ld completely duplicate packet%s (%ld byte%s)\n");
274 p(tcp6s_pawsdrop, "\t\t%ld old duplicate packet%s\n");
275 p2(tcp6s_rcvpartduppack, tcp6s_rcvpartdupbyte,
276 "\t\t%ld packet%s with some dup. data (%ld byte%s duped)\n");
277 p2(tcp6s_rcvoopack, tcp6s_rcvoobyte,
278 "\t\t%ld out-of-order packet%s (%ld byte%s)\n");
279 p2(tcp6s_rcvpackafterwin, tcp6s_rcvbyteafterwin,
280 "\t\t%ld packet%s (%ld byte%s) of data after window\n");
281 p(tcp6s_rcvwinprobe, "\t\t%ld window probe%s\n");
282 p(tcp6s_rcvwinupd, "\t\t%ld window update packet%s\n");
283 p(tcp6s_rcvafterclose, "\t\t%ld packet%s received after close\n");
284 p(tcp6s_rcvbadsum, "\t\t%ld discarded for bad checksum%s\n");
285 p(tcp6s_rcvbadoff, "\t\t%ld discarded for bad header offset field%s\n");
286 p(tcp6s_rcvshort, "\t\t%ld discarded because packet%s too short\n");
287 p(tcp6s_connattempt, "\t%ld connection request%s\n");
288 p(tcp6s_accepts, "\t%ld connection accept%s\n");
289 p(tcp6s_badsyn, "\t%ld bad connection attempt%s\n");
290 p(tcp6s_connects, "\t%ld connection%s established (including accepts)\n");
291 p2(tcp6s_closed, tcp6s_drops,
292 "\t%ld connection%s closed (including %ld drop%s)\n");
293 p(tcp6s_conndrops, "\t%ld embryonic connection%s dropped\n");
294 p2(tcp6s_rttupdated, tcp6s_segstimed,
295 "\t%ld segment%s updated rtt (of %ld attempt%s)\n");
296 p(tcp6s_rexmttimeo, "\t%ld retransmit timeout%s\n");
297 p(tcp6s_timeoutdrop, "\t\t%ld connection%s dropped by rexmit timeout\n");
298 p(tcp6s_persisttimeo, "\t%ld persist timeout%s\n");
299 p(tcp6s_persistdrop, "\t%ld connection%s timed out in persist\n");
300 p(tcp6s_keeptimeo, "\t%ld keepalive timeout%s\n");
301 p(tcp6s_keepprobe, "\t\t%ld keepalive probe%s sent\n");
302 p(tcp6s_keepdrops, "\t\t%ld connection%s dropped by keepalive\n");
303 p(tcp6s_predack, "\t%ld correct ACK header prediction%s\n");
304 p(tcp6s_preddat, "\t%ld correct data packet header prediction%s\n");
305 p3(tcp6s_pcbcachemiss, "\t%ld PCB cache miss%s\n");
306 #undef p
307 #undef p2
308 #undef p3
309 }
310 #endif
311
312 /*
313 * Dump UDP6 statistics structure.
314 */
315 void
316 udp6_stats(off, name)
317 u_long off;
318 char *name;
319 {
320 struct udp6stat udp6stat;
321 u_quad_t delivered;
322
323 if (off == 0)
324 return;
325 kread(off, (char *)&udp6stat, sizeof (udp6stat));
326 printf("%s:\n", name);
327 #define p(f, m) if (udp6stat.f || sflag <= 1) \
328 printf(m, (unsigned long long)udp6stat.f, plural(udp6stat.f))
329 #define p1(f, m) if (udp6stat.f || sflag <= 1) \
330 printf(m, (unsigned long long)udp6stat.f)
331 p(udp6s_ipackets, "\t%llu datagram%s received\n");
332 p1(udp6s_hdrops, "\t%llu with incomplete header\n");
333 p1(udp6s_badlen, "\t%llu with bad data length field\n");
334 p1(udp6s_badsum, "\t%llu with bad checksum\n");
335 p1(udp6s_nosum, "\t%llu with no checksum\n");
336 p1(udp6s_noport, "\t%llu dropped due to no socket\n");
337 p(udp6s_noportmcast,
338 "\t%llu multicast datagram%s dropped due to no socket\n");
339 p1(udp6s_fullsock, "\t%llu dropped due to full socket buffers\n");
340 delivered = udp6stat.udp6s_ipackets -
341 udp6stat.udp6s_hdrops -
342 udp6stat.udp6s_badlen -
343 udp6stat.udp6s_badsum -
344 udp6stat.udp6s_noport -
345 udp6stat.udp6s_noportmcast -
346 udp6stat.udp6s_fullsock;
347 if (delivered || sflag <= 1)
348 printf("\t%llu delivered\n", (unsigned long long)delivered);
349 p(udp6s_opackets, "\t%llu datagram%s output\n");
350 #undef p
351 #undef p1
352 }
353
354 static char *ip6nh[] = {
355 /*0*/ "hop by hop",
356 "ICMP",
357 "IGMP",
358 NULL,
359 "IP",
360 /*5*/ NULL,
361 "TCP",
362 NULL,
363 NULL,
364 NULL,
365 /*10*/ NULL, NULL, NULL, NULL, NULL,
366 /*15*/ NULL,
367 NULL,
368 "UDP",
369 NULL,
370 NULL,
371 /*20*/ NULL,
372 NULL,
373 "IDP",
374 NULL,
375 NULL,
376 /*25*/ NULL,
377 NULL,
378 NULL,
379 NULL,
380 "TP",
381 /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
382 /*40*/ NULL,
383 "IP6",
384 NULL,
385 "routing",
386 "fragment",
387 /*45*/ NULL, NULL, NULL, NULL, NULL,
388 /*50*/ "ESP",
389 "AH",
390 NULL,
391 NULL,
392 NULL,
393 /*55*/ NULL,
394 NULL,
395 NULL,
396 "ICMP6",
397 "no next header",
398 /*60*/ "destination option",
399 NULL,
400 NULL,
401 NULL,
402 NULL,
403 /*65*/ NULL, NULL, NULL, NULL, NULL,
404 /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
405 /*80*/ "ISOIP",
406 NULL,
407 NULL,
408 NULL,
409 NULL,
410 NULL,
411 NULL,
412 NULL,
413 NULL,
414 "OSPF",
415 /*90*/ NULL, NULL, NULL, NULL, NULL,
416 /*95*/ NULL,
417 NULL,
418 "Ethernet",
419 NULL,
420 NULL,
421 /*100*/ NULL,
422 NULL,
423 NULL,
424 "PIM",
425 NULL,
426 /*105*/ NULL, NULL, NULL, NULL, NULL,
427 /*110*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
428 /*120*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
429 /*130*/ NULL,
430 NULL,
431 "SCTP",
432 NULL,
433 NULL,
434 /*135*/ NULL, NULL, NULL, NULL, NULL,
435 /*140*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
436 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
437 /*160*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
438 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
439 /*180*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
440 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
441 /*200*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
442 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
443 /*220*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
444 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
445 /*240*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
446 NULL, NULL, NULL, NULL, NULL, NULL,
447 };
448
449 /*
450 * Dump IP6 statistics structure.
451 */
452 void
453 ip6_stats(off, name)
454 u_long off;
455 char *name;
456 {
457 struct ip6stat ip6stat;
458 int first, i;
459 struct protoent *ep;
460 const char *n;
461
462 if (off == 0)
463 return;
464
465 kread(off, (char *)&ip6stat, sizeof (ip6stat));
466 printf("%s:\n", name);
467
468 #define p(f, m) if (ip6stat.f || sflag <= 1) \
469 printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f))
470 #define p1(f, m) if (ip6stat.f || sflag <= 1) \
471 printf(m, (unsigned long long)ip6stat.f)
472
473 p(ip6s_total, "\t%llu total packet%s received\n");
474 p1(ip6s_toosmall, "\t%llu with size smaller than minimum\n");
475 p1(ip6s_tooshort, "\t%llu with data size < data length\n");
476 p1(ip6s_badoptions, "\t%llu with bad options\n");
477 p1(ip6s_badvers, "\t%llu with incorrect version number\n");
478 p(ip6s_fragments, "\t%llu fragment%s received\n");
479 p(ip6s_fragdropped,
480 "\t%llu fragment%s dropped (dup or out of space)\n");
481 p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
482 p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n");
483 p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n");
484 p(ip6s_delivered, "\t%llu packet%s for this host\n");
485 p(ip6s_forward, "\t%llu packet%s forwarded\n");
486 p(ip6s_cantforward, "\t%llu packet%s not forwardable\n");
487 p(ip6s_redirectsent, "\t%llu redirect%s sent\n");
488 p(ip6s_localout, "\t%llu packet%s sent from this host\n");
489 p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n");
490 p(ip6s_odropped,
491 "\t%llu output packet%s dropped due to no bufs, etc.\n");
492 p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n");
493 p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n");
494 p(ip6s_ofragments, "\t%llu fragment%s created\n");
495 p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
496 p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n");
497 p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n");
498 for (first = 1, i = 0; i < 256; i++)
499 if (ip6stat.ip6s_nxthist[i] != 0) {
500 if (first) {
501 printf("\tInput packet histogram:\n");
502 first = 0;
503 }
504 n = NULL;
505 if (ip6nh[i])
506 n = ip6nh[i];
507 else if ((ep = getprotobynumber(i)) != NULL)
508 n = ep->p_name;
509 if (n)
510 printf("\t\t%s: %llu\n", n,
511 (unsigned long long)ip6stat.ip6s_nxthist[i]);
512 else
513 printf("\t\t#%d: %llu\n", i,
514 (unsigned long long)ip6stat.ip6s_nxthist[i]);
515 }
516 printf("\tMbuf statistics:\n");
517 p(ip6s_m1, "\t\t%llu one mbuf%s\n");
518 for (first = 1, i = 0; i < 32; i++) {
519 char ifbuf[IFNAMSIZ];
520 if (ip6stat.ip6s_m2m[i] != 0) {
521 if (first) {
522 printf("\t\ttwo or more mbuf:\n");
523 first = 0;
524 }
525 printf("\t\t\t%s = %llu\n",
526 if_indextoname(i, ifbuf),
527 (unsigned long long)ip6stat.ip6s_m2m[i]);
528 }
529 }
530 p(ip6s_mext1, "\t\t%llu one ext mbuf%s\n");
531 p(ip6s_mext2m, "\t\t%llu two or more ext mbuf%s\n");
532 p(ip6s_exthdrtoolong,
533 "\t%llu packet%s whose headers are not continuous\n");
534 p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
535 p(ip6s_toomanyhdr,
536 "\t%llu packet%s discarded due to too many headers\n");
537
538 /* for debugging source address selection */
539 #define PRINT_SCOPESTAT(s,i) do {\
540 switch(i) { /* XXX hardcoding in each case */\
541 case 1:\
542 p(s, "\t\t%llu node-local%s\n");\
543 break;\
544 case 2:\
545 p(s, "\t\t%llu link-local%s\n");\
546 break;\
547 case 5:\
548 p(s, "\t\t%llu site-local%s\n");\
549 break;\
550 case 14:\
551 p(s, "\t\t%llu global%s\n");\
552 break;\
553 default:\
554 printf("\t\t%llu addresses scope=%x\n",\
555 (unsigned long long)ip6stat.s, i);\
556 }\
557 } while(0);
558
559 p(ip6s_sources_none,
560 "\t%llu failure%s of source address selection\n");
561 for (first = 1, i = 0; i < 16; i++) {
562 if (ip6stat.ip6s_sources_sameif[i]) {
563 if (first) {
564 printf("\tsource addresses on an outgoing I/F\n");
565 first = 0;
566 }
567 PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
568 }
569 }
570 for (first = 1, i = 0; i < 16; i++) {
571 if (ip6stat.ip6s_sources_otherif[i]) {
572 if (first) {
573 printf("\tsource addresses on a non-outgoing I/F\n");
574 first = 0;
575 }
576 PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
577 }
578 }
579 for (first = 1, i = 0; i < 16; i++) {
580 if (ip6stat.ip6s_sources_samescope[i]) {
581 if (first) {
582 printf("\tsource addresses of same scope\n");
583 first = 0;
584 }
585 PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
586 }
587 }
588 for (first = 1, i = 0; i < 16; i++) {
589 if (ip6stat.ip6s_sources_otherscope[i]) {
590 if (first) {
591 printf("\tsource addresses of a different scope\n");
592 first = 0;
593 }
594 PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
595 }
596 }
597 for (first = 1, i = 0; i < 16; i++) {
598 if (ip6stat.ip6s_sources_deprecated[i]) {
599 if (first) {
600 printf("\tdeprecated source addresses\n");
601 first = 0;
602 }
603 PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
604 }
605 }
606
607 p1(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
608 p1(ip6s_forward_cachemiss, "\t%llu forward cache miss\n");
609 #undef p
610 #undef p1
611 }
612
613 /*
614 * Dump IPv6 per-interface statistics based on RFC 2465.
615 */
616 void
617 ip6_ifstats(ifname)
618 char *ifname;
619 {
620 struct in6_ifreq ifr;
621 int s;
622 #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
623 printf(m, (unsigned long long)ifr.ifr_ifru.ifru_stat.f, \
624 plural(ifr.ifr_ifru.ifru_stat.f))
625 #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
626 printf(m, (unsigned long long)ip6stat.f)
627
628 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
629 perror("Warning: socket(AF_INET6)");
630 return;
631 }
632
633 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
634 printf("ip6 on %s:\n", ifname);
635
636 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
637 perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
638 goto end;
639 }
640
641 p(ifs6_in_receive, "\t%llu total input datagram%s\n");
642 p(ifs6_in_hdrerr, "\t%llu datagram%s with invalid header received\n");
643 p(ifs6_in_toobig, "\t%llu datagram%s exceeded MTU received\n");
644 p(ifs6_in_noroute, "\t%llu datagram%s with no route received\n");
645 p(ifs6_in_addrerr, "\t%llu datagram%s with invalid dst received\n");
646 p(ifs6_in_truncated, "\t%llu truncated datagram%s received\n");
647 p(ifs6_in_protounknown, "\t%llu datagram%s with unknown proto received\n");
648 p(ifs6_in_discard, "\t%llu input datagram%s discarded\n");
649 p(ifs6_in_deliver,
650 "\t%llu datagram%s delivered to an upper layer protocol\n");
651 p(ifs6_out_forward, "\t%llu datagram%s forwarded to this interface\n");
652 p(ifs6_out_request,
653 "\t%llu datagram%s sent from an upper layer protocol\n");
654 p(ifs6_out_discard, "\t%llu total discarded output datagram%s\n");
655 p(ifs6_out_fragok, "\t%llu output datagram%s fragmented\n");
656 p(ifs6_out_fragfail, "\t%llu output datagram%s failed on fragment\n");
657 p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
658 p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
659 p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
660 p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
661 p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
662 p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
663
664 end:
665 close(s);
666
667 #undef p
668 #undef p_5
669 }
670
671 static char *icmp6names[] = {
672 "#0",
673 "unreach",
674 "packet too big",
675 "time exceed",
676 "parameter problem",
677 "#5",
678 "#6",
679 "#7",
680 "#8",
681 "#9",
682 "#10",
683 "#11",
684 "#12",
685 "#13",
686 "#14",
687 "#15",
688 "#16",
689 "#17",
690 "#18",
691 "#19",
692 "#20",
693 "#21",
694 "#22",
695 "#23",
696 "#24",
697 "#25",
698 "#26",
699 "#27",
700 "#28",
701 "#29",
702 "#30",
703 "#31",
704 "#32",
705 "#33",
706 "#34",
707 "#35",
708 "#36",
709 "#37",
710 "#38",
711 "#39",
712 "#40",
713 "#41",
714 "#42",
715 "#43",
716 "#44",
717 "#45",
718 "#46",
719 "#47",
720 "#48",
721 "#49",
722 "#50",
723 "#51",
724 "#52",
725 "#53",
726 "#54",
727 "#55",
728 "#56",
729 "#57",
730 "#58",
731 "#59",
732 "#60",
733 "#61",
734 "#62",
735 "#63",
736 "#64",
737 "#65",
738 "#66",
739 "#67",
740 "#68",
741 "#69",
742 "#70",
743 "#71",
744 "#72",
745 "#73",
746 "#74",
747 "#75",
748 "#76",
749 "#77",
750 "#78",
751 "#79",
752 "#80",
753 "#81",
754 "#82",
755 "#83",
756 "#84",
757 "#85",
758 "#86",
759 "#87",
760 "#88",
761 "#89",
762 "#80",
763 "#91",
764 "#92",
765 "#93",
766 "#94",
767 "#95",
768 "#96",
769 "#97",
770 "#98",
771 "#99",
772 "#100",
773 "#101",
774 "#102",
775 "#103",
776 "#104",
777 "#105",
778 "#106",
779 "#107",
780 "#108",
781 "#109",
782 "#110",
783 "#111",
784 "#112",
785 "#113",
786 "#114",
787 "#115",
788 "#116",
789 "#117",
790 "#118",
791 "#119",
792 "#120",
793 "#121",
794 "#122",
795 "#123",
796 "#124",
797 "#125",
798 "#126",
799 "#127",
800 "echo",
801 "echo reply",
802 "multicast listener query",
803 "multicast listener report",
804 "multicast listener done",
805 "router solicitation",
806 "router advertisement",
807 "neighbor solicitation",
808 "neighbor advertisement",
809 "redirect",
810 "router renumbering",
811 "node information request",
812 "node information reply",
813 "#141",
814 "#142",
815 "#143",
816 "#144",
817 "#145",
818 "#146",
819 "#147",
820 "#148",
821 "#149",
822 "#150",
823 "#151",
824 "#152",
825 "#153",
826 "#154",
827 "#155",
828 "#156",
829 "#157",
830 "#158",
831 "#159",
832 "#160",
833 "#161",
834 "#162",
835 "#163",
836 "#164",
837 "#165",
838 "#166",
839 "#167",
840 "#168",
841 "#169",
842 "#170",
843 "#171",
844 "#172",
845 "#173",
846 "#174",
847 "#175",
848 "#176",
849 "#177",
850 "#178",
851 "#179",
852 "#180",
853 "#181",
854 "#182",
855 "#183",
856 "#184",
857 "#185",
858 "#186",
859 "#187",
860 "#188",
861 "#189",
862 "#180",
863 "#191",
864 "#192",
865 "#193",
866 "#194",
867 "#195",
868 "#196",
869 "#197",
870 "#198",
871 "#199",
872 "#200",
873 "#201",
874 "#202",
875 "#203",
876 "#204",
877 "#205",
878 "#206",
879 "#207",
880 "#208",
881 "#209",
882 "#210",
883 "#211",
884 "#212",
885 "#213",
886 "#214",
887 "#215",
888 "#216",
889 "#217",
890 "#218",
891 "#219",
892 "#220",
893 "#221",
894 "#222",
895 "#223",
896 "#224",
897 "#225",
898 "#226",
899 "#227",
900 "#228",
901 "#229",
902 "#230",
903 "#231",
904 "#232",
905 "#233",
906 "#234",
907 "#235",
908 "#236",
909 "#237",
910 "#238",
911 "#239",
912 "#240",
913 "#241",
914 "#242",
915 "#243",
916 "#244",
917 "#245",
918 "#246",
919 "#247",
920 "#248",
921 "#249",
922 "#250",
923 "#251",
924 "#252",
925 "#253",
926 "#254",
927 "#255",
928 };
929
930 /*
931 * Dump ICMPv6 statistics.
932 */
933 void
934 icmp6_stats(off, name)
935 u_long off;
936 char *name;
937 {
938 struct icmp6stat icmp6stat;
939 register int i, first;
940
941 if (off == 0)
942 return;
943 kread(off, (char *)&icmp6stat, sizeof (icmp6stat));
944 printf("%s:\n", name);
945
946 #define p(f, m) if (icmp6stat.f || sflag <= 1) \
947 printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
948 #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
949 printf(m, (unsigned long long)icmp6stat.f)
950
951 p(icp6s_error, "\t%llu call%s to icmp6_error\n");
952 p(icp6s_canterror,
953 "\t%llu error%s not generated because old message was icmp6 or so\n");
954 p(icp6s_toofreq,
955 "\t%llu error%s not generated because of rate limitation\n");
956 for (first = 1, i = 0; i < 256; i++)
957 if (icmp6stat.icp6s_outhist[i] != 0) {
958 if (first) {
959 printf("\tOutput packet histogram:\n");
960 first = 0;
961 }
962 printf("\t\t%s: %llu\n", icmp6names[i],
963 (unsigned long long)icmp6stat.icp6s_outhist[i]);
964 }
965 p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
966 p(icp6s_tooshort, "\t%llu message%s < minimum length\n");
967 p(icp6s_checksum, "\t%llu bad checksum%s\n");
968 p(icp6s_badlen, "\t%llu message%s with bad length\n");
969 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++)
970 if (icmp6stat.icp6s_inhist[i] != 0) {
971 if (first) {
972 printf("\tInput packet histogram:\n");
973 first = 0;
974 }
975 printf("\t\t%s: %llu\n", icmp6names[i],
976 (unsigned long long)icmp6stat.icp6s_inhist[i]);
977 }
978 printf("\tHistogram of error messages to be generated:\n");
979 p_5(icp6s_odst_unreach_noroute, "\t\t%llu no route\n");
980 p_5(icp6s_odst_unreach_admin, "\t\t%llu administratively prohibited\n");
981 p_5(icp6s_odst_unreach_beyondscope, "\t\t%llu beyond scope\n");
982 p_5(icp6s_odst_unreach_addr, "\t\t%llu address unreachable\n");
983 p_5(icp6s_odst_unreach_noport, "\t\t%llu port unreachable\n");
984 p_5(icp6s_opacket_too_big, "\t\t%llu packet too big\n");
985 p_5(icp6s_otime_exceed_transit, "\t\t%llu time exceed transit\n");
986 p_5(icp6s_otime_exceed_reassembly, "\t\t%llu time exceed reassembly\n");
987 p_5(icp6s_oparamprob_header, "\t\t%llu erroneous header field\n");
988 p_5(icp6s_oparamprob_nextheader, "\t\t%llu unrecognized next header\n");
989 p_5(icp6s_oparamprob_option, "\t\t%llu unrecognized option\n");
990 p_5(icp6s_oredirect, "\t\t%llu redirect\n");
991 p_5(icp6s_ounknown, "\t\t%llu unknown\n");
992
993 p(icp6s_reflect, "\t%llu message response%s generated\n");
994 p(icp6s_nd_toomanyopt, "\t%llu message%s with too many ND options\n");
995 p(icp6s_nd_badopt, "\t%llu message%s with bad ND options\n");
996 p(icp6s_badns, "\t%llu bad neighbor solicitation message%s\n");
997 p(icp6s_badna, "\t%llu bad neighbor advertisement message%s\n");
998 p(icp6s_badrs, "\t%llu bad router solicitation message%s\n");
999 p(icp6s_badra, "\t%llu bad router advertisement message%s\n");
1000 p(icp6s_badredirect, "\t%llu bad redirect message%s\n");
1001 p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
1002 #undef p
1003 #undef p_5
1004 }
1005
1006 /*
1007 * Dump ICMPv6 per-interface statistics based on RFC 2466.
1008 */
1009 void
1010 icmp6_ifstats(ifname)
1011 char *ifname;
1012 {
1013 struct in6_ifreq ifr;
1014 int s;
1015 #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
1016 printf(m, (unsigned long long)ifr.ifr_ifru.ifru_icmp6stat.f, \
1017 plural(ifr.ifr_ifru.ifru_icmp6stat.f))
1018
1019 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1020 perror("Warning: socket(AF_INET6)");
1021 return;
1022 }
1023
1024 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1025 printf("icmp6 on %s:\n", ifname);
1026
1027 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1028 perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
1029 goto end;
1030 }
1031
1032 p(ifs6_in_msg, "\t%llu total input message%s\n");
1033 p(ifs6_in_error, "\t%llu total input error message%s\n");
1034 p(ifs6_in_dstunreach, "\t%llu input destination unreachable error%s\n");
1035 p(ifs6_in_adminprohib, "\t%llu input administratively prohibited error%s\n");
1036 p(ifs6_in_timeexceed, "\t%llu input time exceeded error%s\n");
1037 p(ifs6_in_paramprob, "\t%llu input parameter problem error%s\n");
1038 p(ifs6_in_pkttoobig, "\t%llu input packet too big error%s\n");
1039 p(ifs6_in_echo, "\t%llu input echo request%s\n");
1040 p(ifs6_in_echoreply, "\t%llu input echo reply%s\n");
1041 p(ifs6_in_routersolicit, "\t%llu input router solicitation%s\n");
1042 p(ifs6_in_routeradvert, "\t%llu input router advertisement%s\n");
1043 p(ifs6_in_neighborsolicit, "\t%llu input neighbor solicitation%s\n");
1044 p(ifs6_in_neighboradvert, "\t%llu input neighbor advertisement%s\n");
1045 p(ifs6_in_redirect, "\t%llu input redirect%s\n");
1046 p(ifs6_in_mldquery, "\t%llu input MLD query%s\n");
1047 p(ifs6_in_mldreport, "\t%llu input MLD report%s\n");
1048 p(ifs6_in_mlddone, "\t%llu input MLD done%s\n");
1049
1050 p(ifs6_out_msg, "\t%llu total output message%s\n");
1051 p(ifs6_out_error, "\t%llu total output error message%s\n");
1052 p(ifs6_out_dstunreach, "\t%llu output destination unreachable error%s\n");
1053 p(ifs6_out_adminprohib, "\t%llu output administratively prohibited error%s\n");
1054 p(ifs6_out_timeexceed, "\t%llu output time exceeded error%s\n");
1055 p(ifs6_out_paramprob, "\t%llu output parameter problem error%s\n");
1056 p(ifs6_out_pkttoobig, "\t%llu output packet too big error%s\n");
1057 p(ifs6_out_echo, "\t%llu output echo request%s\n");
1058 p(ifs6_out_echoreply, "\t%llu output echo reply%s\n");
1059 p(ifs6_out_routersolicit, "\t%llu output router solicitation%s\n");
1060 p(ifs6_out_routeradvert, "\t%llu output router advertisement%s\n");
1061 p(ifs6_out_neighborsolicit, "\t%llu output neighbor solicitation%s\n");
1062 p(ifs6_out_neighboradvert, "\t%llu output neighbor advertisement%s\n");
1063 p(ifs6_out_redirect, "\t%llu output redirect%s\n");
1064 p(ifs6_out_mldquery, "\t%llu output MLD query%s\n");
1065 p(ifs6_out_mldreport, "\t%llu output MLD report%s\n");
1066 p(ifs6_out_mlddone, "\t%llu output MLD done%s\n");
1067
1068 end:
1069 close(s);
1070 #undef p
1071 }
1072
1073 /*
1074 * Dump PIM statistics structure.
1075 */
1076 void
1077 pim6_stats(off, name)
1078 u_long off;
1079 char *name;
1080 {
1081 struct pim6stat pim6stat;
1082
1083 if (off == 0)
1084 return;
1085 kread(off, (char *)&pim6stat, sizeof(pim6stat));
1086 printf("%s:\n", name);
1087
1088 #define p(f, m) if (pim6stat.f || sflag <= 1) \
1089 printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f))
1090 p(pim6s_rcv_total, "\t%llu message%s received\n");
1091 p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
1092 p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
1093 p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
1094 p(pim6s_rcv_registers, "\t%llu register%s received\n");
1095 p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
1096 p(pim6s_snd_registers, "\t%llu register%s sent\n");
1097 #undef p
1098 }
1099
1100 /*
1101 * Dump raw ip6 statistics structure.
1102 */
1103 void
1104 rip6_stats(off, name)
1105 u_long off;
1106 char *name;
1107 {
1108 struct rip6stat rip6stat;
1109 u_quad_t delivered;
1110
1111 if (off == 0)
1112 return;
1113 kread(off, (char *)&rip6stat, sizeof(rip6stat));
1114 printf("%s:\n", name);
1115
1116 #define p(f, m) if (rip6stat.f || sflag <= 1) \
1117 printf(m, (unsigned long long)rip6stat.f, plural(rip6stat.f))
1118 p(rip6s_ipackets, "\t%llu message%s received\n");
1119 p(rip6s_isum, "\t%llu checksum calculation%s on inbound\n");
1120 p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
1121 p(rip6s_nosock, "\t%llu message%s dropped due to no socket\n");
1122 p(rip6s_nosockmcast,
1123 "\t%llu multicast message%s dropped due to no socket\n");
1124 p(rip6s_fullsock,
1125 "\t%llu message%s dropped due to full socket buffers\n");
1126 delivered = rip6stat.rip6s_ipackets -
1127 rip6stat.rip6s_badsum -
1128 rip6stat.rip6s_nosock -
1129 rip6stat.rip6s_nosockmcast -
1130 rip6stat.rip6s_fullsock;
1131 if (delivered || sflag <= 1)
1132 printf("\t%llu delivered\n", (unsigned long long)delivered);
1133 p(rip6s_opackets, "\t%llu datagram%s output\n");
1134 #undef p
1135 }
1136
1137 /*
1138 * Pretty print an Internet address (net address + port).
1139 * Take numeric_addr and numeric_port into consideration.
1140 */
1141 void
1142 inet6print(in6, port, proto)
1143 register struct in6_addr *in6;
1144 int port;
1145 char *proto;
1146 {
1147 #define GETSERVBYPORT6(port, proto, ret)\
1148 do {\
1149 if (strcmp((proto), "tcp6") == 0)\
1150 (ret) = getservbyport((int)(port), "tcp");\
1151 else if (strcmp((proto), "udp6") == 0)\
1152 (ret) = getservbyport((int)(port), "udp");\
1153 else\
1154 (ret) = getservbyport((int)(port), (proto));\
1155 } while (0)
1156 struct servent *sp = 0;
1157 char line[80], *cp;
1158 int width;
1159
1160 width = Aflag ? 12 : 16;
1161 if (vflag && width < strlen(inet6name(in6)))
1162 width = strlen(inet6name(in6));
1163 snprintf(line, sizeof(line), "%.*s.", width, inet6name(in6));
1164 cp = strchr(line, '\0');
1165 if (!numeric_port && port)
1166 GETSERVBYPORT6(port, proto, sp);
1167 if (sp || port == 0)
1168 snprintf(cp, sizeof(line) - (cp - line),
1169 "%s", sp ? sp->s_name : "*");
1170 else
1171 snprintf(cp, sizeof(line) - (cp - line),
1172 "%d", ntohs((u_short)port));
1173 width = Aflag ? 18 : 22;
1174 if (vflag && width < strlen(line))
1175 width = strlen(line);
1176 printf(" %-*.*s", width, width, line);
1177 }
1178
1179 /*
1180 * Construct an Internet address representation.
1181 * If the numeric_addr has been supplied, give
1182 * numeric value, otherwise try for symbolic name.
1183 */
1184
1185 char *
1186 inet6name(in6p)
1187 struct in6_addr *in6p;
1188 {
1189 register char *cp;
1190 static char line[NI_MAXHOST];
1191 struct hostent *hp;
1192 static char domain[MAXHOSTNAMELEN + 1];
1193 static int first = 1;
1194 char hbuf[NI_MAXHOST];
1195 struct sockaddr_in6 sin6;
1196 #ifdef NI_WITHSCOPEID
1197 const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
1198 #else
1199 const int niflag = NI_NUMERICHOST;
1200 #endif
1201
1202 if (first && !numeric_addr) {
1203 first = 0;
1204 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1205 (cp = strchr(domain, '.')))
1206 (void) strlcpy(domain, cp + 1, sizeof(domain));
1207 else
1208 domain[0] = 0;
1209 }
1210 cp = 0;
1211 if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1212 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
1213 if (hp) {
1214 if ((cp = strchr(hp->h_name, '.')) &&
1215 !strcmp(cp + 1, domain))
1216 *cp = 0;
1217 cp = hp->h_name;
1218 }
1219 }
1220 if (IN6_IS_ADDR_UNSPECIFIED(in6p))
1221 strlcpy(line, "*", sizeof(line));
1222 else if (cp)
1223 strlcpy(line, cp, sizeof(line));
1224 else {
1225 memset(&sin6, 0, sizeof(sin6));
1226 sin6.sin6_len = sizeof(sin6);
1227 sin6.sin6_family = AF_INET6;
1228 sin6.sin6_addr = *in6p;
1229 #ifdef __KAME__
1230 if (IN6_IS_ADDR_LINKLOCAL(in6p)) {
1231 sin6.sin6_scope_id =
1232 ntohs(*(u_int16_t *)&in6p->s6_addr[2]);
1233 sin6.sin6_addr.s6_addr[2] = 0;
1234 sin6.sin6_addr.s6_addr[3] = 0;
1235 }
1236 #endif
1237 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
1238 hbuf, sizeof(hbuf), NULL, 0, niflag) != 0)
1239 strlcpy(hbuf, "?", sizeof(hbuf));
1240 strlcpy(line, hbuf, sizeof(line));
1241 }
1242 return (line);
1243 }
1244
1245 #ifdef TCP6
1246 /*
1247 * Dump the contents of a TCP6 PCB.
1248 */
1249 void
1250 tcp6_dump(pcbaddr)
1251 u_long pcbaddr;
1252 {
1253 struct tcp6cb tcp6cb;
1254 int i;
1255
1256 kread(pcbaddr, (char *)&tcp6cb, sizeof(tcp6cb));
1257
1258 printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
1259
1260 printf("Timers:\n");
1261 for (i = 0; i < TCP6T_NTIMERS; i++)
1262 printf("\t%s: %u", tcp6timers[i], tcp6cb.t_timer[i]);
1263 printf("\n\n");
1264
1265 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
1266 printf("State: %d", tcp6cb.t_state);
1267 else
1268 printf("State: %s", tcp6states[tcp6cb.t_state]);
1269 printf(", flags 0x%x, in6pcb 0x%lx\n\n", tcp6cb.t_flags,
1270 (u_long)tcp6cb.t_in6pcb);
1271
1272 printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcp6cb.t_rxtshift,
1273 tcp6cb.t_rxtcur, tcp6cb.t_dupacks);
1274 printf("peermaxseg %u, maxseg %u, force %d\n\n", tcp6cb.t_peermaxseg,
1275 tcp6cb.t_maxseg, tcp6cb.t_force);
1276
1277 printf("snd_una %u, snd_nxt %u, snd_up %u\n",
1278 tcp6cb.snd_una, tcp6cb.snd_nxt, tcp6cb.snd_up);
1279 printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %llu\n\n",
1280 tcp6cb.snd_wl1, tcp6cb.snd_wl2, tcp6cb.iss,
1281 (unsigned long long)tcp6cb.snd_wnd);
1282
1283 printf("rcv_wnd %llu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
1284 (unsigned long long)cp6cb.rcv_wnd, tcp6cb.rcv_nxt,
1285 tcp6cb.rcv_up, tcp6cb.irs);
1286
1287 printf("rcv_adv %u, snd_max %u, snd_cwnd %llu, snd_ssthresh %llu\n",
1288 tcp6cb.rcv_adv, tcp6cb.snd_max, (unsigned long long)tcp6cb.snd_cwnd,
1289 (unsigned long long)tcp6cb.snd_ssthresh);
1290
1291 printf("idle %d, rtt %d, rtseq %u, srtt %d, rttvar %d, rttmin %d, "
1292 "max_sndwnd %llu\n\n", tcp6cb.t_idle, tcp6cb.t_rtt, tcp6cb.t_rtseq,
1293 tcp6cb.t_srtt, tcp6cb.t_rttvar, tcp6cb.t_rttmin,
1294 (unsigned long long)tcp6cb.max_sndwnd);
1295
1296 printf("oobflags %d, iobc %d, softerror %d\n\n", tcp6cb.t_oobflags,
1297 tcp6cb.t_iobc, tcp6cb.t_softerror);
1298
1299 printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
1300 tcp6cb.snd_scale, tcp6cb.rcv_scale, tcp6cb.request_r_scale,
1301 tcp6cb.requested_s_scale);
1302 printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
1303 tcp6cb.ts_recent, tcp6cb.ts_recent_age, tcp6cb.last_ack_sent);
1304 }
1305 #endif
1306
1307 #endif /*INET6*/
1308