put back -s option
[unix-history] / usr / src / usr.bin / netstat / inet.c
CommitLineData
c7fc5288 1#ifndef lint
6df0a927 2static char sccsid[] = "@(#)inet.c 4.6 82/12/05";
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>
17#include <netinet/ip_var.h>
18#include <netinet/tcp.h>
19#include <netinet/tcpip.h>
20#include <netinet/tcp_seq.h>
c7fc5288 21#define TCPSTATES
44906619
SL
22#include <netinet/tcp_fsm.h>
23#include <netinet/tcp_timer.h>
24#include <netinet/tcp_var.h>
25#include <netinet/tcp_debug.h>
26#include <netinet/udp.h>
27#include <netinet/udp_var.h>
28
c7fc5288
SL
29#include <netdb.h>
30
31struct inpcb inpcb;
32struct tcpcb tcpcb;
33struct socket socket;
34struct protosw proto;
35extern int kmem;
36extern int Aflag;
37extern int aflag;
38extern int nflag;
39
40static int first = 1;
41char *inetname();
42
43/*
44 * Print a summary of connections related to an Internet
45 * protocol. For TCP, also give state of connection.
46 * Listening processes (aflag) are suppressed unless the
47 * -a (all) flag is specified.
48 */
49protopr(off, name)
50 off_t off;
51 char *name;
52{
53 struct inpcb cb;
54 register struct inpcb *prev, *next;
55 int istcp;
56
57 if (off == 0) {
58 printf("%s control block: symbol not in namelist\n", name);
59 return;
60 }
61 istcp = strcmp(name, "tcp") == 0;
62 klseek(kmem, off, 0);
63 read(kmem, &cb, sizeof (struct inpcb));
64 inpcb = cb;
65 prev = (struct inpcb *)off;
66 if (first) {
67 printf("Active connections");
68 if (aflag)
69 printf(" (including servers)");
70 putchar('\n');
71 if (Aflag)
72 printf("%-8.8s ", "PCB");
73 printf("%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n",
74 "Proto", "Recv-Q", "Send-Q",
75 "Local Address", "Foreign Address", "(state)");
76 first = 0;
77 }
78 while (inpcb.inp_next != (struct inpcb *)off) {
79 char *cp;
80
81 next = inpcb.inp_next;
82 klseek(kmem, (off_t)next, 0);
83 read(kmem, &inpcb, sizeof (inpcb));
84 if (inpcb.inp_prev != prev) {
85 printf("???\n");
86 break;
87 }
88 if (!aflag &&
444a708d 89 inet_lnaof(inpcb.inp_laddr.s_addr) == INADDR_ANY) {
c7fc5288
SL
90 prev = next;
91 continue;
92 }
93 klseek(kmem, (off_t)inpcb.inp_socket, 0);
94 read(kmem, &socket, sizeof (socket));
95 if (istcp) {
96 klseek(kmem, (off_t)inpcb.inp_ppcb, 0);
97 read(kmem, &tcpcb, sizeof (tcpcb));
98 }
99 if (Aflag)
100 printf("%8x ", inpcb.inp_ppcb);
101 printf("%-5.5s %6d %6d ", name, socket.so_rcv.sb_cc,
102 socket.so_snd.sb_cc);
103 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name);
104 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name);
105 if (istcp) {
106 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
107 printf(" %d", tcpcb.t_state);
108 else
109 printf(" %s", tcpstates[tcpcb.t_state]);
110 }
111 putchar('\n');
112 prev = next;
113 }
114}
115
6df0a927
SL
116/*
117 * Dump TCP statistics structure.
118 */
119tcp_stats(off, name)
120 off_t off;
121 char *name;
122{
123 struct tcpstat tcpstat;
124
125 if (off == 0) {
126 printf("%sstat: symbol not in namelist\n", name);
127 return;
128 }
129 klseek(kmem, off, 0);
130 read(kmem, (char *)&tcpstat, sizeof (tcpstat));
131 printf("%s:\n\t%d bad header checksums\n", name, tcpstat.tcps_badsum);
132 printf("\t%d bad header offset fields\n", tcpstat.tcps_badoff);
133 printf("\t%d incomplete headers\n", tcpstat.tcps_hdrops);
134#ifdef notdef
135 printf("\t%d bad segments\n", tcpstat.tcps_badsegs);
136 printf("\t%d unacknowledged packets\n", tcpstat.tcps_unack);
137#endif
138}
139
140/*
141 * Dump UDP statistics structure.
142 */
143udp_stats(off, name)
144 off_t off;
145 char *name;
146{
147 struct udpstat udpstat;
148
149 if (off == 0) {
150 printf("%sstat: symbol not in namelist\n", name);
151 return;
152 }
153 klseek(kmem, off, 0);
154 read(kmem, (char *)&udpstat, sizeof (udpstat));
155 printf("%s:\n\t%d bad header checksums\n", name, udpstat.udps_badsum);
156 printf("\t%d incomplete headers\n", udpstat.udps_hdrops);
157 printf("\t%d bad data length fields\n", udpstat.udps_badlen);
158}
159
160/*
161 * Dump IP statistics structure.
162 */
163ip_stats(off, name)
164 off_t off;
165 char *name;
166{
167 struct ipstat ipstat;
168
169 if (off == 0) {
170 printf("%sstat: symbol not in namelist\n", name);
171 return;
172 }
173 klseek(kmem, off, 0);
174 read(kmem, (char *)&ipstat, sizeof (ipstat));
175 printf("%s:\n\t%d bad header checksums\n", name, ipstat.ips_badsum);
176 printf("\t%d incomplete packets\n", ipstat.ips_tooshort);
177}
178
c7fc5288
SL
179/*
180 * Pretty print an Internet address (net address + port).
181 * If the nflag was specified, use numbers instead of names.
182 */
183inetprint(in, port, proto)
184 register struct in_addr *in;
185 int port;
186 char *proto;
187{
188 struct servent *sp = 0;
189 char line[80], *cp, *index();
190
191 sprintf(line, "%.10s.", inetname(*in));
192 cp = index(line, '\0');
193#if vax || pdp11
194 port = ntohs((u_short)port);
195#endif
196 if (!nflag && port)
9bce7b73 197 sp = getservbyport(port, proto);
c7fc5288
SL
198 if (sp || port == 0)
199 sprintf(cp, "%.8s", sp ? sp->s_name : "*");
200 else
201 sprintf(cp, "%d", port);
202 printf(" %-18.18s", line);
203}
204
c7fc5288
SL
205/*
206 * Construct an Internet address representation.
207 * If the nflag has been supplied, give
208 * numeric value, otherwise try for symbolic name.
209 */
210char *
211inetname(in)
212 struct in_addr in;
213{
214 char *cp = 0;
215 static char line[50];
216
217 if (!nflag) {
444a708d
SL
218 if (inet_lnaof(in) == INADDR_ANY) {
219 struct netent *np;
c7fc5288 220
444a708d 221 np = getnetbyaddr(inet_netof(in), AF_INET);
c7fc5288
SL
222 if (np)
223 cp = np->n_name;
224 } else {
9bce7b73 225 struct hostent *hp;
c7fc5288 226
3394f0b5
SL
227 hp = gethostbyaddr(&in, sizeof (struct in_addr),
228 AF_INET);
c7fc5288
SL
229 if (hp)
230 cp = hp->h_name;
231 }
232 }
233 if (in.s_addr == INADDR_ANY)
234 strcpy(line, "*");
235 else if (cp)
236 strcpy(line, cp);
237 else {
238 u_char *ucp = (u_char *)&in;
239 sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]);
240 }
241 return (line);
242}