missing param to printf
[unix-history] / usr / src / usr.bin / netstat / inet.c
CommitLineData
c7fc5288 1#ifndef lint
4fbbc6d9 2static char sccsid[] = "@(#)inet.c 4.13 83/09/16";
c7fc5288
SL
3#endif
4
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <sys/socketvar.h>
8#include <sys/mbuf.h>
9#include <sys/protosw.h>
44906619 10
c7fc5288 11#include <net/route.h>
44906619
SL
12#include <netinet/in.h>
13#include <netinet/in_systm.h>
14#include <netinet/in_pcb.h>
15#include <netinet/ip.h>
16#include <netinet/ip_icmp.h>
7333c75b 17#include <netinet/icmp_var.h>
44906619
SL
18#include <netinet/ip_var.h>
19#include <netinet/tcp.h>
20#include <netinet/tcpip.h>
21#include <netinet/tcp_seq.h>
c7fc5288 22#define TCPSTATES
44906619
SL
23#include <netinet/tcp_fsm.h>
24#include <netinet/tcp_timer.h>
25#include <netinet/tcp_var.h>
26#include <netinet/tcp_debug.h>
27#include <netinet/udp.h>
28#include <netinet/udp_var.h>
29
c7fc5288
SL
30#include <netdb.h>
31
32struct inpcb inpcb;
33struct tcpcb tcpcb;
34struct socket socket;
35struct protosw proto;
36extern int kmem;
37extern int Aflag;
38extern int aflag;
39extern int nflag;
40
41static int first = 1;
42char *inetname();
43
44/*
45 * Print a summary of connections related to an Internet
46 * protocol. For TCP, also give state of connection.
47 * Listening processes (aflag) are suppressed unless the
48 * -a (all) flag is specified.
49 */
50protopr(off, name)
51 off_t off;
52 char *name;
53{
54 struct inpcb cb;
55 register struct inpcb *prev, *next;
56 int istcp;
57
58 if (off == 0) {
59 printf("%s control block: symbol not in namelist\n", name);
60 return;
61 }
62 istcp = strcmp(name, "tcp") == 0;
63 klseek(kmem, off, 0);
64 read(kmem, &cb, sizeof (struct inpcb));
65 inpcb = cb;
66 prev = (struct inpcb *)off;
67 if (first) {
68 printf("Active connections");
69 if (aflag)
70 printf(" (including servers)");
71 putchar('\n');
72 if (Aflag)
73 printf("%-8.8s ", "PCB");
74 printf("%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n",
75 "Proto", "Recv-Q", "Send-Q",
76 "Local Address", "Foreign Address", "(state)");
77 first = 0;
78 }
79 while (inpcb.inp_next != (struct inpcb *)off) {
80 char *cp;
81
82 next = inpcb.inp_next;
83 klseek(kmem, (off_t)next, 0);
84 read(kmem, &inpcb, sizeof (inpcb));
85 if (inpcb.inp_prev != prev) {
86 printf("???\n");
87 break;
88 }
89 if (!aflag &&
444a708d 90 inet_lnaof(inpcb.inp_laddr.s_addr) == INADDR_ANY) {
c7fc5288
SL
91 prev = next;
92 continue;
93 }
94 klseek(kmem, (off_t)inpcb.inp_socket, 0);
95 read(kmem, &socket, sizeof (socket));
96 if (istcp) {
97 klseek(kmem, (off_t)inpcb.inp_ppcb, 0);
98 read(kmem, &tcpcb, sizeof (tcpcb));
99 }
100 if (Aflag)
101 printf("%8x ", inpcb.inp_ppcb);
102 printf("%-5.5s %6d %6d ", name, socket.so_rcv.sb_cc,
103 socket.so_snd.sb_cc);
104 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name);
105 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name);
106 if (istcp) {
107 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
108 printf(" %d", tcpcb.t_state);
109 else
110 printf(" %s", tcpstates[tcpcb.t_state]);
111 }
112 putchar('\n');
113 prev = next;
114 }
115}
116
6df0a927
SL
117/*
118 * Dump TCP statistics structure.
119 */
120tcp_stats(off, name)
121 off_t off;
122 char *name;
123{
124 struct tcpstat tcpstat;
125
126 if (off == 0) {
127 printf("%sstat: symbol not in namelist\n", name);
128 return;
129 }
130 klseek(kmem, off, 0);
131 read(kmem, (char *)&tcpstat, sizeof (tcpstat));
d69a747c
SL
132 printf("%s:\n\t%d bad header checksum%s\n", name,
133 tcpstat.tcps_badsum, plural(tcpstat.tcps_badsum));
134 printf("\t%d bad header offset field%s\n",
135 tcpstat.tcps_badoff, plural(tcpstat.tcps_badoff));
136 printf("\t%d incomplete header%s\n",
137 tcpstat.tcps_hdrops, plural(tcpstat.tcps_hdrops));
6df0a927 138#ifdef notdef
d69a747c
SL
139 printf("\t%d bad segment%s\n",
140 tcpstat.tcps_badsegs, plural(tcpstat.badsegs));
141 printf("\t%d unacknowledged packet%s\n",
142 tcpstat.tcps_unack, plural(tcpstat.tcps_unack));
6df0a927
SL
143#endif
144}
145
146/*
147 * Dump UDP statistics structure.
148 */
149udp_stats(off, name)
150 off_t off;
151 char *name;
152{
153 struct udpstat udpstat;
154
155 if (off == 0) {
156 printf("%sstat: symbol not in namelist\n", name);
157 return;
158 }
159 klseek(kmem, off, 0);
160 read(kmem, (char *)&udpstat, sizeof (udpstat));
d69a747c
SL
161 printf("%s:\n\t%d bad header checksum%s\n", name,
162 udpstat.udps_badsum, plural(udpstat.udps_badsum));
163 printf("\t%d incomplete header%s\n",
164 udpstat.udps_hdrops, plural(udpstat.udps_hdrops));
165 printf("\t%d bad data length field%s\n",
166 udpstat.udps_badlen, plural(udpstat.udps_badlen));
6df0a927
SL
167}
168
169/*
170 * Dump IP statistics structure.
171 */
172ip_stats(off, name)
173 off_t off;
174 char *name;
175{
176 struct ipstat ipstat;
177
178 if (off == 0) {
179 printf("%sstat: symbol not in namelist\n", name);
180 return;
181 }
182 klseek(kmem, off, 0);
183 read(kmem, (char *)&ipstat, sizeof (ipstat));
d69a747c
SL
184 printf("%s:\n\t%d bad header checksum%s\n", name,
185 ipstat.ips_badsum, plural(ipstat.ips_badsum));
186 printf("\t%d with size smaller than minimum\n", ipstat.ips_tooshort);
187 printf("\t%d with data size < data length\n", ipstat.ips_toosmall);
188 printf("\t%d with header length < data size\n", ipstat.ips_badhlen);
189 printf("\t%d with data length < header length\n", ipstat.ips_badlen);
6df0a927
SL
190}
191
7333c75b
SL
192static char *icmpnames[] = {
193 "echo reply",
194 "#1",
195 "#2",
196 "destination unreachable",
197 "source quench",
198 "routing redirect",
199 "#6",
200 "#7",
201 "echo",
202 "#9",
203 "#10",
204 "time exceeded",
205 "parameter problem",
206 "time stamp",
207 "time stamp reply",
208 "information request",
209 "information request reply"
210};
211
212/*
213 * Dump ICMP statistics.
214 */
215icmp_stats(off, name)
216 off_t off;
217 char *name;
218{
219 struct icmpstat icmpstat;
220 register int i, first;
221
222 if (off == 0) {
223 printf("%sstat: symbol not in namelist\n", name);
224 return;
225 }
226 klseek(kmem, off, 0);
227 read(kmem, (char *)&icmpstat, sizeof (icmpstat));
d69a747c
SL
228 printf("%s:\n\t%d call%s to icmp_error\n", name,
229 icmpstat.icps_error, plural(icmpstat.icps_error));
230 printf("\t%d error%s not generated 'cuz old message too short\n",
231 icmpstat.icps_oldshort, plural(icmpstat.icps_oldshort));
232 printf("\t%d error%s not generated 'cuz old message was icmp\n",
233 icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp));
94ff35a7 234 for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
7333c75b
SL
235 if (icmpstat.icps_outhist[i] != 0) {
236 if (first) {
237 printf("\tOutput histogram:\n");
238 first = 0;
239 }
240 printf("\t\t%s: %d\n", icmpnames[i],
241 icmpstat.icps_outhist[i]);
242 }
d69a747c
SL
243 printf("\t%d message%s < minimum length\n",
244 icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort));
4fbbc6d9
SL
245 printf("\t%d bad checksum%s\n",
246 icmpstat.icps_checksum, plural(icmpstat.icps_checksum));
d69a747c
SL
247 printf("\t%d message%s with bad length\n",
248 icmpstat.icps_badlen, plural(icmpstat.icps_badlen));
249 printf("\t%d message response%s generated\n",
250 icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
94ff35a7 251 for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
7333c75b
SL
252 if (icmpstat.icps_inhist[i] != 0) {
253 if (first) {
254 printf("\tInput histogram:\n");
255 first = 0;
256 }
257 printf("\t\t%s: %d\n", icmpnames[i],
258 icmpstat.icps_inhist[i]);
259 }
260}
261
c7fc5288
SL
262/*
263 * Pretty print an Internet address (net address + port).
264 * If the nflag was specified, use numbers instead of names.
265 */
266inetprint(in, port, proto)
267 register struct in_addr *in;
268 int port;
269 char *proto;
270{
271 struct servent *sp = 0;
272 char line[80], *cp, *index();
273
274 sprintf(line, "%.10s.", inetname(*in));
275 cp = index(line, '\0');
c7fc5288 276 if (!nflag && port)
9bce7b73 277 sp = getservbyport(port, proto);
c7fc5288
SL
278 if (sp || port == 0)
279 sprintf(cp, "%.8s", sp ? sp->s_name : "*");
280 else
1f34f70d 281 sprintf(cp, "%d", ntohs((u_short)port));
c7fc5288
SL
282 printf(" %-18.18s", line);
283}
284
c7fc5288
SL
285/*
286 * Construct an Internet address representation.
287 * If the nflag has been supplied, give
288 * numeric value, otherwise try for symbolic name.
289 */
290char *
291inetname(in)
292 struct in_addr in;
293{
294 char *cp = 0;
295 static char line[50];
296
297 if (!nflag) {
444a708d
SL
298 if (inet_lnaof(in) == INADDR_ANY) {
299 struct netent *np;
c7fc5288 300
444a708d 301 np = getnetbyaddr(inet_netof(in), AF_INET);
c7fc5288
SL
302 if (np)
303 cp = np->n_name;
304 } else {
9bce7b73 305 struct hostent *hp;
c7fc5288 306
3394f0b5
SL
307 hp = gethostbyaddr(&in, sizeof (struct in_addr),
308 AF_INET);
c7fc5288
SL
309 if (hp)
310 cp = hp->h_name;
311 }
312 }
313 if (in.s_addr == INADDR_ANY)
314 strcpy(line, "*");
315 else if (cp)
316 strcpy(line, cp);
317 else {
318 u_char *ucp = (u_char *)&in;
319 sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]);
320 }
321 return (line);
322}