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