inet.c revision 1.10 1 1.1 cgd /*
2 1.9 mycroft * Copyright (c) 1983, 1988, 1993
3 1.9 mycroft * The Regents of the University of California. All rights reserved.
4 1.1 cgd *
5 1.1 cgd * Redistribution and use in source and binary forms, with or without
6 1.1 cgd * modification, are permitted provided that the following conditions
7 1.1 cgd * are met:
8 1.1 cgd * 1. Redistributions of source code must retain the above copyright
9 1.1 cgd * notice, this list of conditions and the following disclaimer.
10 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer in the
12 1.1 cgd * documentation and/or other materials provided with the distribution.
13 1.1 cgd * 3. All advertising materials mentioning features or use of this software
14 1.1 cgd * must display the following acknowledgement:
15 1.1 cgd * This product includes software developed by the University of
16 1.1 cgd * California, Berkeley and its contributors.
17 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
18 1.1 cgd * may be used to endorse or promote products derived from this software
19 1.1 cgd * without specific prior written permission.
20 1.1 cgd *
21 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 cgd * SUCH DAMAGE.
32 1.1 cgd */
33 1.1 cgd
34 1.1 cgd #ifndef lint
35 1.9 mycroft /*static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";*/
36 1.10 cgd static char *rcsid = "$Id: inet.c,v 1.10 1994/12/24 17:21:51 cgd Exp $";
37 1.1 cgd #endif /* not lint */
38 1.1 cgd
39 1.1 cgd #include <sys/param.h>
40 1.10 cgd #include <sys/queue.h>
41 1.1 cgd #include <sys/socket.h>
42 1.1 cgd #include <sys/socketvar.h>
43 1.1 cgd #include <sys/mbuf.h>
44 1.1 cgd #include <sys/protosw.h>
45 1.1 cgd
46 1.1 cgd #include <net/route.h>
47 1.1 cgd #include <netinet/in.h>
48 1.1 cgd #include <netinet/in_systm.h>
49 1.1 cgd #include <netinet/ip.h>
50 1.1 cgd #include <netinet/in_pcb.h>
51 1.1 cgd #include <netinet/ip_icmp.h>
52 1.1 cgd #include <netinet/icmp_var.h>
53 1.6 brezak #include <netinet/igmp_var.h>
54 1.1 cgd #include <netinet/ip_var.h>
55 1.1 cgd #include <netinet/tcp.h>
56 1.1 cgd #include <netinet/tcpip.h>
57 1.1 cgd #include <netinet/tcp_seq.h>
58 1.1 cgd #define TCPSTATES
59 1.1 cgd #include <netinet/tcp_fsm.h>
60 1.1 cgd #include <netinet/tcp_timer.h>
61 1.1 cgd #include <netinet/tcp_var.h>
62 1.1 cgd #include <netinet/tcp_debug.h>
63 1.1 cgd #include <netinet/udp.h>
64 1.1 cgd #include <netinet/udp_var.h>
65 1.1 cgd
66 1.9 mycroft #include <arpa/inet.h>
67 1.1 cgd #include <netdb.h>
68 1.1 cgd #include <stdio.h>
69 1.1 cgd #include <string.h>
70 1.9 mycroft #include <unistd.h>
71 1.9 mycroft #include "netstat.h"
72 1.1 cgd
73 1.1 cgd struct inpcb inpcb;
74 1.1 cgd struct tcpcb tcpcb;
75 1.1 cgd struct socket sockb;
76 1.1 cgd
77 1.9 mycroft char *inetname __P((struct in_addr *));
78 1.9 mycroft void inetprint __P((struct in_addr *, int, char *));
79 1.1 cgd
80 1.1 cgd /*
81 1.1 cgd * Print a summary of connections related to an Internet
82 1.1 cgd * protocol. For TCP, also give state of connection.
83 1.1 cgd * Listening processes (aflag) are suppressed unless the
84 1.1 cgd * -a (all) flag is specified.
85 1.1 cgd */
86 1.9 mycroft void
87 1.1 cgd protopr(off, name)
88 1.8 cgd u_long off;
89 1.1 cgd char *name;
90 1.1 cgd {
91 1.1 cgd struct inpcb cb;
92 1.1 cgd register struct inpcb *prev, *next;
93 1.1 cgd int istcp;
94 1.1 cgd static int first = 1;
95 1.1 cgd
96 1.1 cgd if (off == 0)
97 1.1 cgd return;
98 1.1 cgd istcp = strcmp(name, "tcp") == 0;
99 1.9 mycroft kread(off, (char *)&cb, sizeof (struct inpcb));
100 1.1 cgd inpcb = cb;
101 1.9 mycroft prev = (struct inpcb *)off;
102 1.9 mycroft if (inpcb.inp_next == (struct inpcb *)off)
103 1.1 cgd return;
104 1.9 mycroft while (inpcb.inp_next != (struct inpcb *)off) {
105 1.1 cgd next = inpcb.inp_next;
106 1.9 mycroft kread((u_long)next, (char *)&inpcb, sizeof (inpcb));
107 1.1 cgd if (inpcb.inp_prev != prev) {
108 1.1 cgd printf("???\n");
109 1.1 cgd break;
110 1.1 cgd }
111 1.1 cgd if (!aflag &&
112 1.1 cgd inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {
113 1.1 cgd prev = next;
114 1.1 cgd continue;
115 1.1 cgd }
116 1.9 mycroft kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
117 1.1 cgd if (istcp) {
118 1.9 mycroft kread((u_long)inpcb.inp_ppcb,
119 1.9 mycroft (char *)&tcpcb, sizeof (tcpcb));
120 1.1 cgd }
121 1.1 cgd if (first) {
122 1.1 cgd printf("Active Internet connections");
123 1.1 cgd if (aflag)
124 1.1 cgd printf(" (including servers)");
125 1.1 cgd putchar('\n');
126 1.1 cgd if (Aflag)
127 1.1 cgd printf("%-8.8s ", "PCB");
128 1.1 cgd printf(Aflag ?
129 1.1 cgd "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
130 1.1 cgd "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
131 1.1 cgd "Proto", "Recv-Q", "Send-Q",
132 1.1 cgd "Local Address", "Foreign Address", "(state)");
133 1.1 cgd first = 0;
134 1.1 cgd }
135 1.1 cgd if (Aflag)
136 1.1 cgd if (istcp)
137 1.1 cgd printf("%8x ", inpcb.inp_ppcb);
138 1.1 cgd else
139 1.1 cgd printf("%8x ", next);
140 1.1 cgd printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
141 1.1 cgd sockb.so_snd.sb_cc);
142 1.9 mycroft inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, name);
143 1.9 mycroft inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, name);
144 1.1 cgd if (istcp) {
145 1.1 cgd if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
146 1.1 cgd printf(" %d", tcpcb.t_state);
147 1.1 cgd else
148 1.1 cgd printf(" %s", tcpstates[tcpcb.t_state]);
149 1.1 cgd }
150 1.1 cgd putchar('\n');
151 1.1 cgd prev = next;
152 1.1 cgd }
153 1.1 cgd }
154 1.1 cgd
155 1.1 cgd /*
156 1.1 cgd * Dump TCP statistics structure.
157 1.1 cgd */
158 1.9 mycroft void
159 1.1 cgd tcp_stats(off, name)
160 1.8 cgd u_long off;
161 1.1 cgd char *name;
162 1.1 cgd {
163 1.1 cgd struct tcpstat tcpstat;
164 1.1 cgd
165 1.1 cgd if (off == 0)
166 1.1 cgd return;
167 1.1 cgd printf ("%s:\n", name);
168 1.9 mycroft kread(off, (char *)&tcpstat, sizeof (tcpstat));
169 1.9 mycroft
170 1.9 mycroft #define p(f, m) if (tcpstat.f || sflag <= 1) \
171 1.9 mycroft printf(m, tcpstat.f, plural(tcpstat.f))
172 1.9 mycroft #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
173 1.9 mycroft printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
174 1.9 mycroft #define p3(f, m) if (tcpstat.f || sflag <= 1) \
175 1.9 mycroft printf(m, tcpstat.f, plurales(tcpstat.f))
176 1.1 cgd
177 1.1 cgd p(tcps_sndtotal, "\t%d packet%s sent\n");
178 1.1 cgd p2(tcps_sndpack,tcps_sndbyte,
179 1.1 cgd "\t\t%d data packet%s (%d byte%s)\n");
180 1.1 cgd p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
181 1.1 cgd "\t\t%d data packet%s (%d byte%s) retransmitted\n");
182 1.1 cgd p2(tcps_sndacks, tcps_delack,
183 1.1 cgd "\t\t%d ack-only packet%s (%d delayed)\n");
184 1.1 cgd p(tcps_sndurg, "\t\t%d URG only packet%s\n");
185 1.1 cgd p(tcps_sndprobe, "\t\t%d window probe packet%s\n");
186 1.1 cgd p(tcps_sndwinup, "\t\t%d window update packet%s\n");
187 1.1 cgd p(tcps_sndctrl, "\t\t%d control packet%s\n");
188 1.1 cgd p(tcps_rcvtotal, "\t%d packet%s received\n");
189 1.1 cgd p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%d ack%s (for %d byte%s)\n");
190 1.1 cgd p(tcps_rcvdupack, "\t\t%d duplicate ack%s\n");
191 1.1 cgd p(tcps_rcvacktoomuch, "\t\t%d ack%s for unsent data\n");
192 1.1 cgd p2(tcps_rcvpack, tcps_rcvbyte,
193 1.1 cgd "\t\t%d packet%s (%d byte%s) received in-sequence\n");
194 1.1 cgd p2(tcps_rcvduppack, tcps_rcvdupbyte,
195 1.1 cgd "\t\t%d completely duplicate packet%s (%d byte%s)\n");
196 1.9 mycroft p(tcps_pawsdrop, "\t\t%d old duplicate packet%s\n");
197 1.1 cgd p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
198 1.1 cgd "\t\t%d packet%s with some dup. data (%d byte%s duped)\n");
199 1.1 cgd p2(tcps_rcvoopack, tcps_rcvoobyte,
200 1.1 cgd "\t\t%d out-of-order packet%s (%d byte%s)\n");
201 1.1 cgd p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
202 1.1 cgd "\t\t%d packet%s (%d byte%s) of data after window\n");
203 1.1 cgd p(tcps_rcvwinprobe, "\t\t%d window probe%s\n");
204 1.1 cgd p(tcps_rcvwinupd, "\t\t%d window update packet%s\n");
205 1.1 cgd p(tcps_rcvafterclose, "\t\t%d packet%s received after close\n");
206 1.1 cgd p(tcps_rcvbadsum, "\t\t%d discarded for bad checksum%s\n");
207 1.1 cgd p(tcps_rcvbadoff, "\t\t%d discarded for bad header offset field%s\n");
208 1.1 cgd p(tcps_rcvshort, "\t\t%d discarded because packet too short\n");
209 1.1 cgd p(tcps_connattempt, "\t%d connection request%s\n");
210 1.1 cgd p(tcps_accepts, "\t%d connection accept%s\n");
211 1.1 cgd p(tcps_connects, "\t%d connection%s established (including accepts)\n");
212 1.1 cgd p2(tcps_closed, tcps_drops,
213 1.1 cgd "\t%d connection%s closed (including %d drop%s)\n");
214 1.1 cgd p(tcps_conndrops, "\t%d embryonic connection%s dropped\n");
215 1.1 cgd p2(tcps_rttupdated, tcps_segstimed,
216 1.1 cgd "\t%d segment%s updated rtt (of %d attempt%s)\n");
217 1.1 cgd p(tcps_rexmttimeo, "\t%d retransmit timeout%s\n");
218 1.1 cgd p(tcps_timeoutdrop, "\t\t%d connection%s dropped by rexmit timeout\n");
219 1.1 cgd p(tcps_persisttimeo, "\t%d persist timeout%s\n");
220 1.1 cgd p(tcps_keeptimeo, "\t%d keepalive timeout%s\n");
221 1.1 cgd p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n");
222 1.1 cgd p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n");
223 1.9 mycroft p(tcps_predack, "\t%d correct ACK header prediction%s\n");
224 1.9 mycroft p(tcps_preddat, "\t%d correct data packet header prediction%s\n");
225 1.9 mycroft p3(tcps_pcbcachemiss, "\t%d PCB cache miss%s\n");
226 1.1 cgd #undef p
227 1.1 cgd #undef p2
228 1.9 mycroft #undef p3
229 1.1 cgd }
230 1.1 cgd
231 1.1 cgd /*
232 1.1 cgd * Dump UDP statistics structure.
233 1.1 cgd */
234 1.9 mycroft void
235 1.1 cgd udp_stats(off, name)
236 1.8 cgd u_long off;
237 1.1 cgd char *name;
238 1.1 cgd {
239 1.1 cgd struct udpstat udpstat;
240 1.9 mycroft u_long delivered;
241 1.1 cgd
242 1.1 cgd if (off == 0)
243 1.1 cgd return;
244 1.9 mycroft kread(off, (char *)&udpstat, sizeof (udpstat));
245 1.9 mycroft printf("%s:\n", name);
246 1.9 mycroft #define p(f, m) if (udpstat.f || sflag <= 1) \
247 1.9 mycroft printf(m, udpstat.f, plural(udpstat.f))
248 1.9 mycroft p(udps_ipackets, "\t%u datagram%s received\n");
249 1.9 mycroft p(udps_hdrops, "\t%u with incomplete header\n");
250 1.9 mycroft p(udps_badlen, "\t%u with bad data length field\n");
251 1.9 mycroft p(udps_badsum, "\t%u with bad checksum\n");
252 1.9 mycroft p(udps_noport, "\t%u dropped due to no socket\n");
253 1.9 mycroft p(udps_noportbcast, "\t%u broadcast/multicast datagram%s dropped due to no socket\n");
254 1.9 mycroft p(udps_fullsock, "\t%u dropped due to full socket buffers\n");
255 1.9 mycroft delivered = udpstat.udps_ipackets -
256 1.9 mycroft udpstat.udps_hdrops -
257 1.9 mycroft udpstat.udps_badlen -
258 1.9 mycroft udpstat.udps_badsum -
259 1.9 mycroft udpstat.udps_noport -
260 1.9 mycroft udpstat.udps_noportbcast -
261 1.9 mycroft udpstat.udps_fullsock;
262 1.9 mycroft if (delivered || sflag <= 1)
263 1.9 mycroft printf("\t%u delivered\n", delivered);
264 1.9 mycroft p(udps_opackets, "\t%u datagram%s output\n");
265 1.9 mycroft #undef p
266 1.1 cgd }
267 1.1 cgd
268 1.1 cgd /*
269 1.1 cgd * Dump IP statistics structure.
270 1.1 cgd */
271 1.9 mycroft void
272 1.1 cgd ip_stats(off, name)
273 1.8 cgd u_long off;
274 1.1 cgd char *name;
275 1.1 cgd {
276 1.1 cgd struct ipstat ipstat;
277 1.1 cgd
278 1.1 cgd if (off == 0)
279 1.1 cgd return;
280 1.9 mycroft kread(off, (char *)&ipstat, sizeof (ipstat));
281 1.9 mycroft printf("%s:\n", name);
282 1.9 mycroft
283 1.9 mycroft #define p(f, m) if (ipstat.f || sflag <= 1) \
284 1.9 mycroft printf(m, ipstat.f, plural(ipstat.f))
285 1.9 mycroft
286 1.9 mycroft p(ips_total, "\t%u total packet%s received\n");
287 1.9 mycroft p(ips_badsum, "\t%u bad header checksum%s\n");
288 1.9 mycroft p(ips_toosmall, "\t%u with size smaller than minimum\n");
289 1.9 mycroft p(ips_tooshort, "\t%u with data size < data length\n");
290 1.9 mycroft p(ips_badhlen, "\t%u with header length < data size\n");
291 1.9 mycroft p(ips_badlen, "\t%u with data length < header length\n");
292 1.9 mycroft p(ips_badoptions, "\t%u with bad options\n");
293 1.9 mycroft p(ips_badvers, "\t%u with incorrect version number\n");
294 1.9 mycroft p(ips_fragments, "\t%u fragment%s received\n");
295 1.9 mycroft p(ips_fragdropped, "\t%u fragment%s dropped (dup or out of space)\n");
296 1.9 mycroft p(ips_fragtimeout, "\t%u fragment%s dropped after timeout\n");
297 1.9 mycroft p(ips_reassembled, "\t%u packet%s reassembled ok\n");
298 1.9 mycroft p(ips_delivered, "\t%u packet%s for this host\n");
299 1.9 mycroft p(ips_noproto, "\t%u packet%s for unknown/unsupported protocol\n");
300 1.9 mycroft p(ips_forward, "\t%u packet%s forwarded\n");
301 1.9 mycroft p(ips_cantforward, "\t%u packet%s not forwardable\n");
302 1.9 mycroft p(ips_redirectsent, "\t%u redirect%s sent\n");
303 1.9 mycroft p(ips_localout, "\t%u packet%s sent from this host\n");
304 1.9 mycroft p(ips_rawout, "\t%u packet%s sent with fabricated ip header\n");
305 1.9 mycroft p(ips_odropped, "\t%u output packet%s dropped due to no bufs, etc.\n");
306 1.9 mycroft p(ips_noroute, "\t%u output packet%s discarded due to no route\n");
307 1.9 mycroft p(ips_fragmented, "\t%u output datagram%s fragmented\n");
308 1.9 mycroft p(ips_ofragments, "\t%u fragment%s created\n");
309 1.9 mycroft p(ips_cantfrag, "\t%u datagram%s that can't be fragmented\n");
310 1.9 mycroft #undef p
311 1.1 cgd }
312 1.1 cgd
313 1.1 cgd static char *icmpnames[] = {
314 1.1 cgd "echo reply",
315 1.1 cgd "#1",
316 1.1 cgd "#2",
317 1.1 cgd "destination unreachable",
318 1.1 cgd "source quench",
319 1.1 cgd "routing redirect",
320 1.1 cgd "#6",
321 1.1 cgd "#7",
322 1.1 cgd "echo",
323 1.1 cgd "#9",
324 1.1 cgd "#10",
325 1.1 cgd "time exceeded",
326 1.1 cgd "parameter problem",
327 1.1 cgd "time stamp",
328 1.1 cgd "time stamp reply",
329 1.1 cgd "information request",
330 1.1 cgd "information request reply",
331 1.1 cgd "address mask request",
332 1.1 cgd "address mask reply",
333 1.1 cgd };
334 1.1 cgd
335 1.1 cgd /*
336 1.1 cgd * Dump ICMP statistics.
337 1.1 cgd */
338 1.9 mycroft void
339 1.1 cgd icmp_stats(off, name)
340 1.8 cgd u_long off;
341 1.1 cgd char *name;
342 1.1 cgd {
343 1.1 cgd struct icmpstat icmpstat;
344 1.1 cgd register int i, first;
345 1.1 cgd
346 1.1 cgd if (off == 0)
347 1.1 cgd return;
348 1.9 mycroft kread(off, (char *)&icmpstat, sizeof (icmpstat));
349 1.9 mycroft printf("%s:\n", name);
350 1.9 mycroft
351 1.9 mycroft #define p(f, m) if (icmpstat.f || sflag <= 1) \
352 1.9 mycroft printf(m, icmpstat.f, plural(icmpstat.f))
353 1.9 mycroft
354 1.9 mycroft p(icps_error, "\t%u call%s to icmp_error\n");
355 1.9 mycroft p(icps_oldicmp,
356 1.9 mycroft "\t%u error%s not generated 'cuz old message was icmp\n");
357 1.1 cgd for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
358 1.1 cgd if (icmpstat.icps_outhist[i] != 0) {
359 1.1 cgd if (first) {
360 1.1 cgd printf("\tOutput histogram:\n");
361 1.1 cgd first = 0;
362 1.1 cgd }
363 1.1 cgd printf("\t\t%s: %u\n", icmpnames[i],
364 1.1 cgd icmpstat.icps_outhist[i]);
365 1.1 cgd }
366 1.9 mycroft p(icps_badcode, "\t%u message%s with bad code fields\n");
367 1.9 mycroft p(icps_tooshort, "\t%u message%s < minimum length\n");
368 1.9 mycroft p(icps_checksum, "\t%u bad checksum%s\n");
369 1.9 mycroft p(icps_badlen, "\t%u message%s with bad length\n");
370 1.1 cgd for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
371 1.1 cgd if (icmpstat.icps_inhist[i] != 0) {
372 1.1 cgd if (first) {
373 1.1 cgd printf("\tInput histogram:\n");
374 1.1 cgd first = 0;
375 1.1 cgd }
376 1.1 cgd printf("\t\t%s: %u\n", icmpnames[i],
377 1.1 cgd icmpstat.icps_inhist[i]);
378 1.1 cgd }
379 1.9 mycroft p(icps_reflect, "\t%u message response%s generated\n");
380 1.9 mycroft #undef p
381 1.6 brezak }
382 1.6 brezak
383 1.6 brezak /*
384 1.9 mycroft * Dump IGMP statistics structure.
385 1.6 brezak */
386 1.6 brezak void
387 1.6 brezak igmp_stats(off, name)
388 1.8 cgd u_long off;
389 1.6 brezak char *name;
390 1.6 brezak {
391 1.6 brezak struct igmpstat igmpstat;
392 1.6 brezak
393 1.6 brezak if (off == 0)
394 1.6 brezak return;
395 1.9 mycroft kread(off, (char *)&igmpstat, sizeof (igmpstat));
396 1.9 mycroft printf("%s:\n", name);
397 1.9 mycroft
398 1.9 mycroft #define p(f, m) if (igmpstat.f || sflag <= 1) \
399 1.9 mycroft printf(m, igmpstat.f, plural(igmpstat.f))
400 1.9 mycroft #define py(f, m) if (igmpstat.f || sflag <= 1) \
401 1.9 mycroft printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
402 1.9 mycroft p(igps_rcv_total, "\t%u message%s received\n");
403 1.9 mycroft p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
404 1.9 mycroft p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
405 1.9 mycroft py(igps_rcv_queries, "\t%u membership quer%s received\n");
406 1.9 mycroft py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
407 1.9 mycroft p(igps_rcv_reports, "\t%u membership report%s received\n");
408 1.9 mycroft p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
409 1.9 mycroft p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
410 1.9 mycroft p(igps_snd_reports, "\t%u membership report%s sent\n");
411 1.9 mycroft #undef p
412 1.9 mycroft #undef py
413 1.1 cgd }
414 1.1 cgd
415 1.1 cgd /*
416 1.1 cgd * Pretty print an Internet address (net address + port).
417 1.1 cgd * If the nflag was specified, use numbers instead of names.
418 1.1 cgd */
419 1.9 mycroft void
420 1.1 cgd inetprint(in, port, proto)
421 1.1 cgd register struct in_addr *in;
422 1.9 mycroft int port;
423 1.1 cgd char *proto;
424 1.1 cgd {
425 1.1 cgd struct servent *sp = 0;
426 1.9 mycroft char line[80], *cp;
427 1.1 cgd int width;
428 1.1 cgd
429 1.9 mycroft sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(in));
430 1.1 cgd cp = index(line, '\0');
431 1.1 cgd if (!nflag && port)
432 1.1 cgd sp = getservbyport((int)port, proto);
433 1.1 cgd if (sp || port == 0)
434 1.1 cgd sprintf(cp, "%.8s", sp ? sp->s_name : "*");
435 1.1 cgd else
436 1.1 cgd sprintf(cp, "%d", ntohs((u_short)port));
437 1.1 cgd width = Aflag ? 18 : 22;
438 1.1 cgd printf(" %-*.*s", width, width, line);
439 1.1 cgd }
440 1.1 cgd
441 1.1 cgd /*
442 1.1 cgd * Construct an Internet address representation.
443 1.9 mycroft * If the nflag has been supplied, give
444 1.1 cgd * numeric value, otherwise try for symbolic name.
445 1.1 cgd */
446 1.1 cgd char *
447 1.9 mycroft inetname(inp)
448 1.9 mycroft struct in_addr *inp;
449 1.1 cgd {
450 1.1 cgd register char *cp;
451 1.1 cgd static char line[50];
452 1.1 cgd struct hostent *hp;
453 1.1 cgd struct netent *np;
454 1.1 cgd static char domain[MAXHOSTNAMELEN + 1];
455 1.1 cgd static int first = 1;
456 1.1 cgd
457 1.1 cgd if (first && !nflag) {
458 1.1 cgd first = 0;
459 1.1 cgd if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
460 1.1 cgd (cp = index(domain, '.')))
461 1.1 cgd (void) strcpy(domain, cp + 1);
462 1.1 cgd else
463 1.1 cgd domain[0] = 0;
464 1.1 cgd }
465 1.1 cgd cp = 0;
466 1.9 mycroft if (!nflag && inp->s_addr != INADDR_ANY) {
467 1.9 mycroft int net = inet_netof(*inp);
468 1.9 mycroft int lna = inet_lnaof(*inp);
469 1.1 cgd
470 1.1 cgd if (lna == INADDR_ANY) {
471 1.1 cgd np = getnetbyaddr(net, AF_INET);
472 1.1 cgd if (np)
473 1.1 cgd cp = np->n_name;
474 1.1 cgd }
475 1.1 cgd if (cp == 0) {
476 1.9 mycroft hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
477 1.1 cgd if (hp) {
478 1.1 cgd if ((cp = index(hp->h_name, '.')) &&
479 1.1 cgd !strcmp(cp + 1, domain))
480 1.1 cgd *cp = 0;
481 1.1 cgd cp = hp->h_name;
482 1.1 cgd }
483 1.1 cgd }
484 1.1 cgd }
485 1.9 mycroft if (inp->s_addr == INADDR_ANY)
486 1.1 cgd strcpy(line, "*");
487 1.1 cgd else if (cp)
488 1.1 cgd strcpy(line, cp);
489 1.1 cgd else {
490 1.9 mycroft inp->s_addr = ntohl(inp->s_addr);
491 1.1 cgd #define C(x) ((x) & 0xff)
492 1.9 mycroft sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
493 1.9 mycroft C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
494 1.1 cgd }
495 1.1 cgd return (line);
496 1.1 cgd }
497