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