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