inet.c revision 1.93 1 /* $NetBSD: inet.c,v 1.93 2010/12/13 21:15:30 pooka Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. 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:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
36 #else
37 __RCSID("$NetBSD: inet.c,v 1.93 2010/12/13 21:15:30 pooka Exp $");
38 #endif
39 #endif /* not lint */
40
41 #define _CALLOUT_PRIVATE /* for defs in sys/callout.h */
42
43 #include <sys/param.h>
44 #include <sys/queue.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/mbuf.h>
48 #include <sys/protosw.h>
49 #include <sys/sysctl.h>
50
51 #include <net/if_arp.h>
52 #include <net/route.h>
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/ip.h>
56 #include <netinet/in_pcb.h>
57 #include <netinet/ip_icmp.h>
58
59 #ifdef INET6
60 #include <netinet/ip6.h>
61 #endif
62
63 #include <netinet/icmp_var.h>
64 #include <netinet/igmp_var.h>
65 #include <netinet/ip_var.h>
66 #include <netinet/pim_var.h>
67 #include <netinet/tcp.h>
68 #include <netinet/tcpip.h>
69 #include <netinet/tcp_seq.h>
70 #define TCPSTATES
71 #include <netinet/tcp_fsm.h>
72 #define TCPTIMERS
73 #include <netinet/tcp_timer.h>
74 #include <netinet/tcp_var.h>
75 #include <netinet/tcp_debug.h>
76 #include <netinet/udp.h>
77 #include <netinet/ip_carp.h>
78 #include <netinet/udp_var.h>
79 #include <net/pfvar.h>
80 #include <net/if_pfsync.h>
81
82 #include <arpa/inet.h>
83 #include <kvm.h>
84 #include <netdb.h>
85 #include <stdio.h>
86 #include <string.h>
87 #include <unistd.h>
88 #include <stdlib.h>
89 #include <err.h>
90 #include "netstat.h"
91 #include "prog_ops.h"
92
93 char *inetname(struct in_addr *);
94 void inetprint(struct in_addr *, u_int16_t, const char *, int);
95
96 /*
97 * Print a summary of connections related to an Internet
98 * protocol. For TCP, also give state of connection.
99 * Listening processes (aflag) are suppressed unless the
100 * -a (all) flag is specified.
101 */
102 static int width;
103 static int compact;
104
105 static void
106 protoprhdr(void)
107 {
108 printf("Active Internet connections");
109 if (aflag)
110 printf(" (including servers)");
111 putchar('\n');
112 if (Aflag)
113 printf("%-8.8s ", "PCB");
114 printf("%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
115 "Proto", "Recv-Q", "Send-Q", compact ? "" : " ",
116 width, width, "Local Address",
117 width, width, "Foreign Address",
118 "State");
119 }
120
121 static void
122 protopr0(intptr_t ppcb, u_long rcv_sb_cc, u_long snd_sb_cc,
123 struct in_addr *laddr, u_int16_t lport,
124 struct in_addr *faddr, u_int16_t fport,
125 short t_state, const char *name, int inp_flags)
126 {
127 static const char *shorttcpstates[] = {
128 "CLOSED", "LISTEN", "SYNSEN", "SYSRCV",
129 "ESTABL", "CLWAIT", "FWAIT1", "CLOSNG",
130 "LASTAK", "FWAIT2", "TMWAIT",
131 };
132 int istcp;
133
134 istcp = strcmp(name, "tcp") == 0;
135
136 if (Aflag) {
137 printf("%8" PRIxPTR " ", ppcb);
138 }
139 printf("%-5.5s %6ld %6ld%s", name, rcv_sb_cc, snd_sb_cc,
140 compact ? "" : " ");
141 if (numeric_port) {
142 inetprint(laddr, lport, name, 1);
143 inetprint(faddr, fport, name, 1);
144 } else if (inp_flags & INP_ANONPORT) {
145 inetprint(laddr, lport, name, 1);
146 inetprint(faddr, fport, name, 0);
147 } else {
148 inetprint(laddr, lport, name, 0);
149 inetprint(faddr, fport, name, 0);
150 }
151 if (istcp) {
152 if (t_state < 0 || t_state >= TCP_NSTATES)
153 printf(" %d", t_state);
154 else
155 printf(" %s", compact ? shorttcpstates[t_state] :
156 tcpstates[t_state]);
157 }
158 putchar('\n');
159 }
160
161 void
162 protopr(u_long off, const char *name)
163 {
164 struct inpcbtable table;
165 struct inpcb *head, *next, *prev;
166 struct inpcb inpcb;
167 struct tcpcb tcpcb;
168 struct socket sockb;
169 int istcp;
170 static int first = 1;
171
172 compact = 0;
173 if (Aflag) {
174 if (!numeric_addr)
175 width = 18;
176 else {
177 width = 21;
178 compact = 1;
179 }
180 } else
181 width = 22;
182
183 if (use_sysctl) {
184 struct kinfo_pcb *pcblist;
185 int mib[8];
186 size_t namelen = 0, size = 0, i;
187 char *mibname = NULL;
188
189 memset(mib, 0, sizeof(mib));
190
191 if (asprintf(&mibname, "net.inet.%s.pcblist", name) == -1)
192 err(1, "asprintf");
193
194 /* get dynamic pcblist node */
195 if (sysctlnametomib(mibname, mib, &namelen) == -1)
196 err(1, "sysctlnametomib: %s", mibname);
197
198 if (prog_sysctl(mib, sizeof(mib) / sizeof(*mib),
199 NULL, &size, NULL, 0) == -1)
200 err(1, "sysctl (query)");
201
202 if ((pcblist = malloc(size)) == NULL)
203 err(1, "malloc");
204 memset(pcblist, 0, size);
205
206 mib[6] = sizeof(*pcblist);
207 mib[7] = size / sizeof(*pcblist);
208
209 if (prog_sysctl(mib, sizeof(mib) / sizeof(*mib),
210 pcblist, &size, NULL, 0) == -1)
211 err(1, "sysctl (copy)");
212
213 for (i = 0; i < size / sizeof(*pcblist); i++) {
214 struct sockaddr_in src, dst;
215
216 memcpy(&src, &pcblist[i].ki_s, sizeof(src));
217 memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
218
219 if (!aflag &&
220 inet_lnaof(dst.sin_addr) == INADDR_ANY)
221 continue;
222
223 if (first) {
224 protoprhdr();
225 first = 0;
226 }
227
228 protopr0((intptr_t) pcblist[i].ki_ppcbaddr,
229 pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
230 &src.sin_addr, src.sin_port,
231 &dst.sin_addr, dst.sin_port,
232 pcblist[i].ki_tstate, name,
233 pcblist[i].ki_pflags);
234 }
235
236 free(pcblist);
237 return;
238 }
239
240 if (off == 0)
241 return;
242 istcp = strcmp(name, "tcp") == 0;
243 kread(off, (char *)&table, sizeof table);
244 prev = head =
245 (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first;
246 next = (struct inpcb *)table.inpt_queue.cqh_first;
247
248 while (next != head) {
249 kread((u_long)next, (char *)&inpcb, sizeof inpcb);
250 if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
251 printf("???\n");
252 break;
253 }
254 prev = next;
255 next = (struct inpcb *)inpcb.inp_queue.cqe_next;
256
257 if (inpcb.inp_af != AF_INET)
258 continue;
259
260 if (!aflag &&
261 inet_lnaof(inpcb.inp_faddr) == INADDR_ANY)
262 continue;
263 kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
264 if (istcp) {
265 kread((u_long)inpcb.inp_ppcb,
266 (char *)&tcpcb, sizeof (tcpcb));
267 }
268
269 if (first) {
270 protoprhdr();
271 first = 0;
272 }
273
274 protopr0(istcp ? (intptr_t) inpcb.inp_ppcb : (intptr_t) prev,
275 sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc,
276 &inpcb.inp_laddr, inpcb.inp_lport,
277 &inpcb.inp_faddr, inpcb.inp_fport,
278 tcpcb.t_state, name, inpcb.inp_flags);
279 }
280 }
281
282 /*
283 * Dump TCP statistics structure.
284 */
285 void
286 tcp_stats(u_long off, const char *name)
287 {
288 uint64_t tcpstat[TCP_NSTATS];
289
290 if (use_sysctl) {
291 size_t size = sizeof(tcpstat);
292
293 if (sysctlbyname("net.inet.tcp.stats", tcpstat, &size,
294 NULL, 0) == -1)
295 return;
296 } else {
297 warnx("%s stats not available via KVM.", name);
298 return;
299 }
300
301 printf ("%s:\n", name);
302
303 #define ps(f, m) if (tcpstat[f] || sflag <= 1) \
304 printf(m, (unsigned long long)tcpstat[f])
305 #define p(f, m) if (tcpstat[f] || sflag <= 1) \
306 printf(m, (unsigned long long)tcpstat[f], plural(tcpstat[f]))
307 #define p2(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
308 printf(m, (unsigned long long)tcpstat[f1], plural(tcpstat[f1]), \
309 (unsigned long long)tcpstat[f2], plural(tcpstat[f2]))
310 #define p2s(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
311 printf(m, (unsigned long long)tcpstat[f1], plural(tcpstat[f1]), \
312 (unsigned long long)tcpstat[f2])
313 #define p3(f, m) if (tcpstat[f] || sflag <= 1) \
314 printf(m, (unsigned long long)tcpstat[f], plurales(tcpstat[f]))
315
316 p(TCP_STAT_SNDTOTAL, "\t%llu packet%s sent\n");
317 p2(TCP_STAT_SNDPACK,TCP_STAT_SNDBYTE,
318 "\t\t%llu data packet%s (%llu byte%s)\n");
319 p2(TCP_STAT_SNDREXMITPACK, TCP_STAT_SNDREXMITBYTE,
320 "\t\t%llu data packet%s (%llu byte%s) retransmitted\n");
321 p2s(TCP_STAT_SNDACKS, TCP_STAT_DELACK,
322 "\t\t%llu ack-only packet%s (%llu delayed)\n");
323 p(TCP_STAT_SNDURG, "\t\t%llu URG only packet%s\n");
324 p(TCP_STAT_SNDPROBE, "\t\t%llu window probe packet%s\n");
325 p(TCP_STAT_SNDWINUP, "\t\t%llu window update packet%s\n");
326 p(TCP_STAT_SNDCTRL, "\t\t%llu control packet%s\n");
327 p(TCP_STAT_SELFQUENCH,
328 "\t\t%llu send attempt%s resulted in self-quench\n");
329 p(TCP_STAT_RCVTOTAL, "\t%llu packet%s received\n");
330 p2(TCP_STAT_RCVACKPACK, TCP_STAT_RCVACKBYTE,
331 "\t\t%llu ack%s (for %llu byte%s)\n");
332 p(TCP_STAT_RCVDUPACK, "\t\t%llu duplicate ack%s\n");
333 p(TCP_STAT_RCVACKTOOMUCH, "\t\t%llu ack%s for unsent data\n");
334 p2(TCP_STAT_RCVPACK, TCP_STAT_RCVBYTE,
335 "\t\t%llu packet%s (%llu byte%s) received in-sequence\n");
336 p2(TCP_STAT_RCVDUPPACK, TCP_STAT_RCVDUPBYTE,
337 "\t\t%llu completely duplicate packet%s (%llu byte%s)\n");
338 p(TCP_STAT_PAWSDROP, "\t\t%llu old duplicate packet%s\n");
339 p2(TCP_STAT_RCVPARTDUPPACK, TCP_STAT_RCVPARTDUPBYTE,
340 "\t\t%llu packet%s with some dup. data (%llu byte%s duped)\n");
341 p2(TCP_STAT_RCVOOPACK, TCP_STAT_RCVOOBYTE,
342 "\t\t%llu out-of-order packet%s (%llu byte%s)\n");
343 p2(TCP_STAT_RCVPACKAFTERWIN, TCP_STAT_RCVBYTEAFTERWIN,
344 "\t\t%llu packet%s (%llu byte%s) of data after window\n");
345 p(TCP_STAT_RCVWINPROBE, "\t\t%llu window probe%s\n");
346 p(TCP_STAT_RCVWINUPD, "\t\t%llu window update packet%s\n");
347 p(TCP_STAT_RCVAFTERCLOSE, "\t\t%llu packet%s received after close\n");
348 p(TCP_STAT_RCVBADSUM, "\t\t%llu discarded for bad checksum%s\n");
349 p(TCP_STAT_RCVBADOFF, "\t\t%llu discarded for bad header offset field%s\n");
350 ps(TCP_STAT_RCVSHORT, "\t\t%llu discarded because packet too short\n");
351 p(TCP_STAT_CONNATTEMPT, "\t%llu connection request%s\n");
352 p(TCP_STAT_ACCEPTS, "\t%llu connection accept%s\n");
353 p(TCP_STAT_CONNECTS,
354 "\t%llu connection%s established (including accepts)\n");
355 p2(TCP_STAT_CLOSED, TCP_STAT_DROPS,
356 "\t%llu connection%s closed (including %llu drop%s)\n");
357 p(TCP_STAT_CONNDROPS, "\t%llu embryonic connection%s dropped\n");
358 p(TCP_STAT_DELAYED_FREE, "\t%llu delayed free%s of tcpcb\n");
359 p2(TCP_STAT_RTTUPDATED, TCP_STAT_SEGSTIMED,
360 "\t%llu segment%s updated rtt (of %llu attempt%s)\n");
361 p(TCP_STAT_REXMTTIMEO, "\t%llu retransmit timeout%s\n");
362 p(TCP_STAT_TIMEOUTDROP,
363 "\t\t%llu connection%s dropped by rexmit timeout\n");
364 p2(TCP_STAT_PERSISTTIMEO, TCP_STAT_PERSISTDROPS,
365 "\t%llu persist timeout%s (resulting in %llu dropped "
366 "connection%s)\n");
367 p(TCP_STAT_KEEPTIMEO, "\t%llu keepalive timeout%s\n");
368 p(TCP_STAT_KEEPPROBE, "\t\t%llu keepalive probe%s sent\n");
369 p(TCP_STAT_KEEPDROPS, "\t\t%llu connection%s dropped by keepalive\n");
370 p(TCP_STAT_PREDACK, "\t%llu correct ACK header prediction%s\n");
371 p(TCP_STAT_PREDDAT, "\t%llu correct data packet header prediction%s\n");
372 p3(TCP_STAT_PCBHASHMISS, "\t%llu PCB hash miss%s\n");
373 ps(TCP_STAT_NOPORT, "\t%llu dropped due to no socket\n");
374 p(TCP_STAT_CONNSDRAINED, "\t%llu connection%s drained due to memory "
375 "shortage\n");
376 p(TCP_STAT_PMTUBLACKHOLE, "\t%llu PMTUD blackhole%s detected\n");
377
378 p(TCP_STAT_BADSYN, "\t%llu bad connection attempt%s\n");
379 ps(TCP_STAT_SC_ADDED, "\t%llu SYN cache entries added\n");
380 p(TCP_STAT_SC_COLLISIONS, "\t\t%llu hash collision%s\n");
381 ps(TCP_STAT_SC_COMPLETED, "\t\t%llu completed\n");
382 ps(TCP_STAT_SC_ABORTED, "\t\t%llu aborted (no space to build PCB)\n");
383 ps(TCP_STAT_SC_TIMED_OUT, "\t\t%llu timed out\n");
384 ps(TCP_STAT_SC_OVERFLOWED, "\t\t%llu dropped due to overflow\n");
385 ps(TCP_STAT_SC_BUCKETOVERFLOW, "\t\t%llu dropped due to bucket overflow\n");
386 ps(TCP_STAT_SC_RESET, "\t\t%llu dropped due to RST\n");
387 ps(TCP_STAT_SC_UNREACH, "\t\t%llu dropped due to ICMP unreachable\n");
388 ps(TCP_STAT_SC_DELAYED_FREE, "\t\t%llu delayed free of SYN cache "
389 "entries\n");
390 p(TCP_STAT_SC_RETRANSMITTED, "\t%llu SYN,ACK%s retransmitted\n");
391 p(TCP_STAT_SC_DUPESYN, "\t%llu duplicate SYN%s received for entries "
392 "already in the cache\n");
393 p(TCP_STAT_SC_DROPPED, "\t%llu SYN%s dropped (no route or no space)\n");
394 p(TCP_STAT_BADSIG, "\t%llu packet%s with bad signature\n");
395 p(TCP_STAT_GOODSIG, "\t%llu packet%s with good signature\n");
396
397 p(TCP_STAT_ECN_SHS, "\t%llu sucessful ECN handshake%s\n");
398 p(TCP_STAT_ECN_CE, "\t%llu packet%s with ECN CE bit\n");
399 p(TCP_STAT_ECN_ECT, "\t%llu packet%s ECN ECT(0) bit\n");
400 #undef p
401 #undef ps
402 #undef p2
403 #undef p2s
404 #undef p3
405 }
406
407 /*
408 * Dump UDP statistics structure.
409 */
410 void
411 udp_stats(u_long off, const char *name)
412 {
413 uint64_t udpstat[UDP_NSTATS];
414 u_quad_t delivered;
415
416 if (use_sysctl) {
417 size_t size = sizeof(udpstat);
418
419 if (sysctlbyname("net.inet.udp.stats", udpstat, &size,
420 NULL, 0) == -1)
421 return;
422 } else {
423 warnx("%s stats not available via KVM.", name);
424 return;
425 }
426
427 printf ("%s:\n", name);
428
429 #define ps(f, m) if (udpstat[f] || sflag <= 1) \
430 printf(m, (unsigned long long)udpstat[f])
431 #define p(f, m) if (udpstat[f] || sflag <= 1) \
432 printf(m, (unsigned long long)udpstat[f], plural(udpstat[f]))
433 #define p3(f, m) if (udpstat[f] || sflag <= 1) \
434 printf(m, (unsigned long long)udpstat[f], plurales(udpstat[f]))
435
436 p(UDP_STAT_IPACKETS, "\t%llu datagram%s received\n");
437 ps(UDP_STAT_HDROPS, "\t%llu with incomplete header\n");
438 ps(UDP_STAT_BADLEN, "\t%llu with bad data length field\n");
439 ps(UDP_STAT_BADSUM, "\t%llu with bad checksum\n");
440 ps(UDP_STAT_NOPORT, "\t%llu dropped due to no socket\n");
441 p(UDP_STAT_NOPORTBCAST,
442 "\t%llu broadcast/multicast datagram%s dropped due to no socket\n");
443 ps(UDP_STAT_FULLSOCK, "\t%llu dropped due to full socket buffers\n");
444 delivered = udpstat[UDP_STAT_IPACKETS] -
445 udpstat[UDP_STAT_HDROPS] -
446 udpstat[UDP_STAT_BADLEN] -
447 udpstat[UDP_STAT_BADSUM] -
448 udpstat[UDP_STAT_NOPORT] -
449 udpstat[UDP_STAT_NOPORTBCAST] -
450 udpstat[UDP_STAT_FULLSOCK];
451 if (delivered || sflag <= 1)
452 printf("\t%llu delivered\n", (unsigned long long)delivered);
453 p3(UDP_STAT_PCBHASHMISS, "\t%llu PCB hash miss%s\n");
454 p(UDP_STAT_OPACKETS, "\t%llu datagram%s output\n");
455
456 #undef ps
457 #undef p
458 #undef p3
459 }
460
461 /*
462 * Dump IP statistics structure.
463 */
464 void
465 ip_stats(u_long off, const char *name)
466 {
467 uint64_t ipstat[IP_NSTATS];
468
469 if (use_sysctl) {
470 size_t size = sizeof(ipstat);
471
472 if (sysctlbyname("net.inet.ip.stats", ipstat, &size,
473 NULL, 0) == -1)
474 return;
475 } else {
476 warnx("%s stats not available via KVM.", name);
477 return;
478 }
479
480 printf("%s:\n", name);
481
482 #define ps(f, m) if (ipstat[f] || sflag <= 1) \
483 printf(m, (unsigned long long)ipstat[f])
484 #define p(f, m) if (ipstat[f] || sflag <= 1) \
485 printf(m, (unsigned long long)ipstat[f], plural(ipstat[f]))
486
487 p(IP_STAT_TOTAL, "\t%llu total packet%s received\n");
488 p(IP_STAT_BADSUM, "\t%llu bad header checksum%s\n");
489 ps(IP_STAT_TOOSMALL, "\t%llu with size smaller than minimum\n");
490 ps(IP_STAT_TOOSHORT, "\t%llu with data size < data length\n");
491 ps(IP_STAT_TOOLONG, "\t%llu with length > max ip packet size\n");
492 ps(IP_STAT_BADHLEN, "\t%llu with header length < data size\n");
493 ps(IP_STAT_BADLEN, "\t%llu with data length < header length\n");
494 ps(IP_STAT_BADOPTIONS, "\t%llu with bad options\n");
495 ps(IP_STAT_BADVERS, "\t%llu with incorrect version number\n");
496 p(IP_STAT_FRAGMENTS, "\t%llu fragment%s received\n");
497 p(IP_STAT_FRAGDROPPED, "\t%llu fragment%s dropped (dup or out of space)\n");
498 p(IP_STAT_RCVMEMDROP, "\t%llu fragment%s dropped (out of ipqent)\n");
499 p(IP_STAT_BADFRAGS, "\t%llu malformed fragment%s dropped\n");
500 p(IP_STAT_FRAGTIMEOUT, "\t%llu fragment%s dropped after timeout\n");
501 p(IP_STAT_REASSEMBLED, "\t%llu packet%s reassembled ok\n");
502 p(IP_STAT_DELIVERED, "\t%llu packet%s for this host\n");
503 p(IP_STAT_NOPROTO, "\t%llu packet%s for unknown/unsupported protocol\n");
504 p(IP_STAT_FORWARD, "\t%llu packet%s forwarded");
505 p(IP_STAT_FASTFORWARD, " (%llu packet%s fast forwarded)");
506 if (ipstat[IP_STAT_FORWARD] || sflag <= 1)
507 putchar('\n');
508 p(IP_STAT_CANTFORWARD, "\t%llu packet%s not forwardable\n");
509 p(IP_STAT_REDIRECTSENT, "\t%llu redirect%s sent\n");
510 p(IP_STAT_NOGIF, "\t%llu packet%s no matching gif found\n");
511 p(IP_STAT_LOCALOUT, "\t%llu packet%s sent from this host\n");
512 p(IP_STAT_RAWOUT, "\t%llu packet%s sent with fabricated ip header\n");
513 p(IP_STAT_ODROPPED, "\t%llu output packet%s dropped due to no bufs, etc.\n");
514 p(IP_STAT_NOROUTE, "\t%llu output packet%s discarded due to no route\n");
515 p(IP_STAT_FRAGMENTED, "\t%llu output datagram%s fragmented\n");
516 p(IP_STAT_OFRAGMENTS, "\t%llu fragment%s created\n");
517 p(IP_STAT_CANTFRAG, "\t%llu datagram%s that can't be fragmented\n");
518 p(IP_STAT_BADADDR, "\t%llu datagram%s with bad address in header\n");
519 #undef ps
520 #undef p
521 }
522
523 static const char *icmpnames[] = {
524 "echo reply",
525 "#1",
526 "#2",
527 "destination unreachable",
528 "source quench",
529 "routing redirect",
530 "alternate host address",
531 "#7",
532 "echo",
533 "router advertisement",
534 "router solicitation",
535 "time exceeded",
536 "parameter problem",
537 "time stamp",
538 "time stamp reply",
539 "information request",
540 "information request reply",
541 "address mask request",
542 "address mask reply",
543 };
544
545 /*
546 * Dump ICMP statistics.
547 */
548 void
549 icmp_stats(u_long off, const char *name)
550 {
551 uint64_t icmpstat[ICMP_NSTATS];
552 int i, first;
553
554 if (use_sysctl) {
555 size_t size = sizeof(icmpstat);
556
557 if (sysctlbyname("net.inet.icmp.stats", icmpstat, &size,
558 NULL, 0) == -1)
559 return;
560 } else {
561 warnx("%s stats not available via KVM.", name);
562 return;
563 }
564
565 printf("%s:\n", name);
566
567 #define p(f, m) if (icmpstat[f] || sflag <= 1) \
568 printf(m, (unsigned long long)icmpstat[f], plural(icmpstat[f]))
569
570 p(ICMP_STAT_ERROR, "\t%llu call%s to icmp_error\n");
571 p(ICMP_STAT_OLDICMP,
572 "\t%llu error%s not generated because old message was icmp\n");
573 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
574 if (icmpstat[ICMP_STAT_OUTHIST + i] != 0) {
575 if (first) {
576 printf("\tOutput histogram:\n");
577 first = 0;
578 }
579 printf("\t\t%s: %llu\n", icmpnames[i],
580 (unsigned long long)icmpstat[ICMP_STAT_OUTHIST + i]);
581 }
582 p(ICMP_STAT_BADCODE, "\t%llu message%s with bad code fields\n");
583 p(ICMP_STAT_TOOSHORT, "\t%llu message%s < minimum length\n");
584 p(ICMP_STAT_CHECKSUM, "\t%llu bad checksum%s\n");
585 p(ICMP_STAT_BADLEN, "\t%llu message%s with bad length\n");
586 p(ICMP_STAT_BMCASTECHO, "\t%llu multicast echo request%s ignored\n");
587 p(ICMP_STAT_BMCASTTSTAMP, "\t%llu multicast timestamp request%s ignored\n");
588 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
589 if (icmpstat[ICMP_STAT_INHIST + i] != 0) {
590 if (first) {
591 printf("\tInput histogram:\n");
592 first = 0;
593 }
594 printf("\t\t%s: %llu\n", icmpnames[i],
595 (unsigned long long)icmpstat[ICMP_STAT_INHIST + i]);
596 }
597 p(ICMP_STAT_REFLECT, "\t%llu message response%s generated\n");
598 p(ICMP_STAT_PMTUCHG, "\t%llu path MTU change%s\n");
599 #undef p
600 }
601
602 /*
603 * Dump IGMP statistics structure.
604 */
605 void
606 igmp_stats(u_long off, const char *name)
607 {
608 uint64_t igmpstat[IGMP_NSTATS];
609
610 if (use_sysctl) {
611 size_t size = sizeof(igmpstat);
612
613 if (sysctlbyname("net.inet.igmp.stats", igmpstat, &size,
614 NULL, 0) == -1)
615 return;
616 } else {
617 warnx("%s stats not available via KVM.", name);
618 return;
619 }
620
621 printf("%s:\n", name);
622
623 #define p(f, m) if (igmpstat[f] || sflag <= 1) \
624 printf(m, (unsigned long long)igmpstat[f], plural(igmpstat[f]))
625 #define py(f, m) if (igmpstat[f] || sflag <= 1) \
626 printf(m, (unsigned long long)igmpstat[f], igmpstat[f] != 1 ? "ies" : "y")
627 p(IGMP_STAT_RCV_TOTAL, "\t%llu message%s received\n");
628 p(IGMP_STAT_RCV_TOOSHORT, "\t%llu message%s received with too few bytes\n");
629 p(IGMP_STAT_RCV_BADSUM, "\t%llu message%s received with bad checksum\n");
630 py(IGMP_STAT_RCV_QUERIES, "\t%llu membership quer%s received\n");
631 py(IGMP_STAT_RCV_BADQUERIES, "\t%llu membership quer%s received with invalid field(s)\n");
632 p(IGMP_STAT_RCV_REPORTS, "\t%llu membership report%s received\n");
633 p(IGMP_STAT_RCV_BADREPORTS, "\t%llu membership report%s received with invalid field(s)\n");
634 p(IGMP_STAT_RCV_OURREPORTS, "\t%llu membership report%s received for groups to which we belong\n");
635 p(IGMP_STAT_SND_REPORTS, "\t%llu membership report%s sent\n");
636 #undef p
637 #undef py
638 }
639
640 /*
641 * Dump CARP statistics structure.
642 */
643 void
644 carp_stats(u_long off, const char *name)
645 {
646 uint64_t carpstat[CARP_NSTATS];
647
648 if (use_sysctl) {
649 size_t size = sizeof(carpstat);
650
651 if (sysctlbyname("net.inet.carp.stats", carpstat, &size,
652 NULL, 0) == -1)
653 return;
654 } else {
655 warnx("%s stats not available via KVM.", name);
656 return;
657 }
658
659 printf("%s:\n", name);
660
661 #define p(f, m) if (carpstat[f] || sflag <= 1) \
662 printf(m, carpstat[f], plural(carpstat[f]))
663 #define p2(f, m) if (carpstat[f] || sflag <= 1) \
664 printf(m, carpstat[f])
665
666 p(CARP_STAT_IPACKETS, "\t%" PRIu64 " packet%s received (IPv4)\n");
667 p(CARP_STAT_IPACKETS6, "\t%" PRIu64 " packet%s received (IPv6)\n");
668 p(CARP_STAT_BADIF,
669 "\t\t%" PRIu64 " packet%s discarded for bad interface\n");
670 p(CARP_STAT_BADTTL,
671 "\t\t%" PRIu64 " packet%s discarded for wrong TTL\n");
672 p(CARP_STAT_HDROPS, "\t\t%" PRIu64 " packet%s shorter than header\n");
673 p(CARP_STAT_BADSUM, "\t\t%" PRIu64
674 " packet%s discarded for bad checksum\n");
675 p(CARP_STAT_BADVER,
676 "\t\t%" PRIu64 " packet%s discarded with a bad version\n");
677 p2(CARP_STAT_BADLEN,
678 "\t\t%" PRIu64 " discarded because packet was too short\n");
679 p(CARP_STAT_BADAUTH,
680 "\t\t%" PRIu64 " packet%s discarded for bad authentication\n");
681 p(CARP_STAT_BADVHID, "\t\t%" PRIu64 " packet%s discarded for bad vhid\n");
682 p(CARP_STAT_BADADDRS, "\t\t%" PRIu64
683 " packet%s discarded because of a bad address list\n");
684 p(CARP_STAT_OPACKETS, "\t%" PRIu64 " packet%s sent (IPv4)\n");
685 p(CARP_STAT_OPACKETS6, "\t%" PRIu64 " packet%s sent (IPv6)\n");
686 p2(CARP_STAT_ONOMEM,
687 "\t\t%" PRIu64 " send failed due to mbuf memory error\n");
688 #undef p
689 #undef p2
690 }
691
692 /*
693 * Dump PFSYNC statistics structure.
694 */
695 void
696 pfsync_stats(u_long off, const char *name)
697 {
698 uint64_t pfsyncstat[PFSYNC_NSTATS];
699
700 if (use_sysctl) {
701 size_t size = sizeof(pfsyncstat);
702
703 if (sysctlbyname("net.inet.pfsync.stats", pfsyncstat, &size,
704 NULL, 0) == -1)
705 return;
706 } else {
707 warnx("%s stats not available via KVM.", name);
708 return;
709 }
710
711 printf("%s:\n", name);
712
713 #define p(f, m) if (pfsyncstat[f] || sflag <= 1) \
714 printf(m, pfsyncstat[f], plural(pfsyncstat[f]))
715 #define p2(f, m) if (pfsyncstat[f] || sflag <= 1) \
716 printf(m, pfsyncstat[f])
717
718 p(PFSYNC_STAT_IPACKETS, "\t%" PRIu64 " packet%s received (IPv4)\n");
719 p(PFSYNC_STAT_IPACKETS6,"\t%" PRIu64 " packet%s received (IPv6)\n");
720 p(PFSYNC_STAT_BADIF, "\t\t%" PRIu64 " packet%s discarded for bad interface\n");
721 p(PFSYNC_STAT_BADTTL, "\t\t%" PRIu64 " packet%s discarded for bad ttl\n");
722 p(PFSYNC_STAT_HDROPS, "\t\t%" PRIu64 " packet%s shorter than header\n");
723 p(PFSYNC_STAT_BADVER, "\t\t%" PRIu64 " packet%s discarded for bad version\n");
724 p(PFSYNC_STAT_BADAUTH, "\t\t%" PRIu64 " packet%s discarded for bad HMAC\n");
725 p(PFSYNC_STAT_BADACT,"\t\t%" PRIu64 " packet%s discarded for bad action\n");
726 p(PFSYNC_STAT_BADLEN, "\t\t%" PRIu64 " packet%s discarded for short packet\n");
727 p(PFSYNC_STAT_BADVAL, "\t\t%" PRIu64 " state%s discarded for bad values\n");
728 p(PFSYNC_STAT_STALE, "\t\t%" PRIu64 " stale state%s\n");
729 p(PFSYNC_STAT_BADSTATE, "\t\t%" PRIu64 " failed state lookup/insert%s\n");
730 p(PFSYNC_STAT_OPACKETS, "\t%" PRIu64 " packet%s sent (IPv4)\n");
731 p(PFSYNC_STAT_OPACKETS6, "\t%" PRIu64 " packet%s sent (IPv6)\n");
732 p2(PFSYNC_STAT_ONOMEM, "\t\t%" PRIu64 " send failed due to mbuf memory error\n");
733 p2(PFSYNC_STAT_OERRORS, "\t\t%" PRIu64 " send error\n");
734 #undef p
735 #undef p2
736 }
737
738 /*
739 * Dump PIM statistics structure.
740 */
741 void
742 pim_stats(u_long off, const char *name)
743 {
744 struct pimstat pimstat;
745
746 if (off == 0)
747 return;
748 if (kread(off, (char *)&pimstat, sizeof (pimstat)) != 0) {
749 /* XXX: PIM is probably not enabled in the kernel */
750 return;
751 }
752
753 printf("%s:\n", name);
754
755 #define p(f, m) if (pimstat.f || sflag <= 1) \
756 printf(m, (unsigned long long)pimstat.f, plural(pimstat.f))
757
758 p(pims_rcv_total_msgs, "\t%llu message%s received\n");
759 p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
760 p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
761 p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
762 p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
763 p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
764 p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
765 p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
766 p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
767 p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
768 p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
769 #undef p
770 }
771
772 /*
773 * Dump the ARP statistics structure.
774 */
775 void
776 arp_stats(u_long off, const char *name)
777 {
778 uint64_t arpstat[ARP_NSTATS];
779
780 if (use_sysctl) {
781 size_t size = sizeof(arpstat);
782
783 if (sysctlbyname("net.inet.arp.stats", arpstat, &size,
784 NULL, 0) == -1)
785 return;
786 } else {
787 warnx("%s stats not available via KVM.", name);
788 return;
789 }
790
791 printf("%s:\n", name);
792
793 #define ps(f, m) if (arpstat[f] || sflag <= 1) \
794 printf(m, (unsigned long long)arpstat[f])
795 #define p(f, m) if (arpstat[f] || sflag <= 1) \
796 printf(m, (unsigned long long)arpstat[f], plural(arpstat[f]))
797
798 p(ARP_STAT_SNDTOTAL, "\t%llu packet%s sent\n");
799 p(ARP_STAT_SNDREPLY, "\t\t%llu reply packet%s\n");
800 p(ARP_STAT_SENDREQUEST, "\t\t%llu request packet%s\n");
801
802 p(ARP_STAT_RCVTOTAL, "\t%llu packet%s received\n");
803 p(ARP_STAT_RCVREPLY, "\t\t%llu reply packet%s\n");
804 p(ARP_STAT_RCVREQUEST, "\t\t%llu valid request packet%s\n");
805 p(ARP_STAT_RCVMCAST, "\t\t%llu broadcast/multicast packet%s\n");
806 p(ARP_STAT_RCVBADPROTO, "\t\t%llu packet%s with unknown protocol type\n");
807 p(ARP_STAT_RCVBADLEN, "\t\t%llu packet%s with bad (short) length\n");
808 p(ARP_STAT_RCVZEROTPA, "\t\t%llu packet%s with null target IP address\n");
809 p(ARP_STAT_RCVZEROSPA, "\t\t%llu packet%s with null source IP address\n");
810 ps(ARP_STAT_RCVNOINT, "\t\t%llu could not be mapped to an interface\n");
811 p(ARP_STAT_RCVLOCALSHA, "\t\t%llu packet%s sourced from a local hardware "
812 "address\n");
813 p(ARP_STAT_RCVBCASTSHA, "\t\t%llu packet%s with a broadcast "
814 "source hardware address\n");
815 p(ARP_STAT_RCVLOCALSPA, "\t\t%llu duplicate%s for a local IP address\n");
816 p(ARP_STAT_RCVOVERPERM, "\t\t%llu attempt%s to overwrite a static entry\n");
817 p(ARP_STAT_RCVOVERINT, "\t\t%llu packet%s received on wrong interface\n");
818 p(ARP_STAT_RCVOVER, "\t\t%llu entry%s overwritten\n");
819 p(ARP_STAT_RCVLENCHG, "\t\t%llu change%s in hardware address length\n");
820
821 p(ARP_STAT_DFRTOTAL, "\t%llu packet%s deferred pending ARP resolution\n");
822 ps(ARP_STAT_DFRSENT, "\t\t%llu sent\n");
823 ps(ARP_STAT_DFRDROPPED, "\t\t%llu dropped\n");
824
825 p(ARP_STAT_ALLOCFAIL, "\t%llu failure%s to allocate llinfo\n");
826
827 #undef ps
828 #undef p
829 }
830
831 /*
832 * Pretty print an Internet address (net address + port).
833 * Take numeric_addr and numeric_port into consideration.
834 */
835 void
836 inetprint(struct in_addr *in, uint16_t port, const char *proto,
837 int port_numeric)
838 {
839 struct servent *sp = 0;
840 char line[80], *cp;
841 size_t space;
842
843 (void)snprintf(line, sizeof line, "%.*s.",
844 (Aflag && !numeric_addr) ? 12 : 16, inetname(in));
845 cp = strchr(line, '\0');
846 if (!port_numeric && port)
847 sp = getservbyport((int)port, proto);
848 space = sizeof line - (cp-line);
849 if (sp || port == 0)
850 (void)snprintf(cp, space, "%s", sp ? sp->s_name : "*");
851 else
852 (void)snprintf(cp, space, "%u", ntohs(port));
853 (void)printf(" %-*.*s", width, width, line);
854 }
855
856 /*
857 * Construct an Internet address representation.
858 * If numeric_addr has been supplied, give
859 * numeric value, otherwise try for symbolic name.
860 */
861 char *
862 inetname(struct in_addr *inp)
863 {
864 char *cp;
865 static char line[50];
866 struct hostent *hp;
867 struct netent *np;
868 static char domain[MAXHOSTNAMELEN + 1];
869 static int first = 1;
870
871 if (first && !numeric_addr) {
872 first = 0;
873 if (gethostname(domain, sizeof domain) == 0) {
874 domain[sizeof(domain) - 1] = '\0';
875 if ((cp = strchr(domain, '.')))
876 (void) strlcpy(domain, cp + 1, sizeof(domain));
877 else
878 domain[0] = 0;
879 } else
880 domain[0] = 0;
881 }
882 cp = 0;
883 if (!numeric_addr && inp->s_addr != INADDR_ANY) {
884 int net = inet_netof(*inp);
885 int lna = inet_lnaof(*inp);
886
887 if (lna == INADDR_ANY) {
888 np = getnetbyaddr(net, AF_INET);
889 if (np)
890 cp = np->n_name;
891 }
892 if (cp == 0) {
893 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
894 if (hp) {
895 if ((cp = strchr(hp->h_name, '.')) &&
896 !strcmp(cp + 1, domain))
897 *cp = 0;
898 cp = hp->h_name;
899 }
900 }
901 }
902 if (inp->s_addr == INADDR_ANY)
903 strlcpy(line, "*", sizeof line);
904 else if (cp)
905 strlcpy(line, cp, sizeof line);
906 else {
907 inp->s_addr = ntohl(inp->s_addr);
908 #define C(x) ((x) & 0xff)
909 (void)snprintf(line, sizeof line, "%u.%u.%u.%u",
910 C(inp->s_addr >> 24), C(inp->s_addr >> 16),
911 C(inp->s_addr >> 8), C(inp->s_addr));
912 #undef C
913 }
914 return (line);
915 }
916
917 /*
918 * Dump the contents of a TCP PCB.
919 */
920 void
921 tcp_dump(u_long pcbaddr)
922 {
923 callout_impl_t *ci;
924 struct tcpcb tcpcb;
925 int i, hardticks;
926
927 kread(pcbaddr, (char *)&tcpcb, sizeof(tcpcb));
928 hardticks = get_hardticks();
929
930 printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
931
932 printf("Timers:\n");
933 for (i = 0; i < TCPT_NTIMERS; i++) {
934 ci = (callout_impl_t *)&tcpcb.t_timer[i];
935 printf("\t%s: %d", tcptimers[i],
936 (ci->c_flags & CALLOUT_PENDING) ?
937 ci->c_time - hardticks : 0);
938 }
939 printf("\n\n");
940
941 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
942 printf("State: %d", tcpcb.t_state);
943 else
944 printf("State: %s", tcpstates[tcpcb.t_state]);
945 printf(", flags 0x%x, inpcb 0x%lx, in6pcb 0x%lx\n\n", tcpcb.t_flags,
946 (u_long)tcpcb.t_inpcb, (u_long)tcpcb.t_in6pcb);
947
948 printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcpcb.t_rxtshift,
949 tcpcb.t_rxtcur, tcpcb.t_dupacks);
950 printf("peermss %u, ourmss %u, segsz %u\n\n", tcpcb.t_peermss,
951 tcpcb.t_ourmss, tcpcb.t_segsz);
952
953 printf("snd_una %u, snd_nxt %u, snd_up %u\n",
954 tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
955 printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %lu\n\n",
956 tcpcb.snd_wl1, tcpcb.snd_wl2, tcpcb.iss, tcpcb.snd_wnd);
957
958 printf("rcv_wnd %lu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
959 tcpcb.rcv_wnd, tcpcb.rcv_nxt, tcpcb.rcv_up, tcpcb.irs);
960
961 printf("rcv_adv %u, snd_max %u, snd_cwnd %lu, snd_ssthresh %lu\n",
962 tcpcb.rcv_adv, tcpcb.snd_max, tcpcb.snd_cwnd, tcpcb.snd_ssthresh);
963
964 printf("rcvtime %u, rtttime %u, rtseq %u, srtt %d, rttvar %d, "
965 "rttmin %d, max_sndwnd %lu\n\n", tcpcb.t_rcvtime, tcpcb.t_rtttime,
966 tcpcb.t_rtseq, tcpcb.t_srtt, tcpcb.t_rttvar, tcpcb.t_rttmin,
967 tcpcb.max_sndwnd);
968
969 printf("oobflags %d, iobc %d, softerror %d\n\n", tcpcb.t_oobflags,
970 tcpcb.t_iobc, tcpcb.t_softerror);
971
972 printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
973 tcpcb.snd_scale, tcpcb.rcv_scale, tcpcb.request_r_scale,
974 tcpcb.requested_s_scale);
975 printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
976 tcpcb.ts_recent, tcpcb.ts_recent_age, tcpcb.last_ack_sent);
977 }
978