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