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