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