|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)inet.c 4.14 (Berkeley) 83/09/21";
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>
10:
11: #include <net/route.h>
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/icmp_var.h>
18: #include <netinet/ip_var.h>
19: #include <netinet/tcp.h>
20: #include <netinet/tcpip.h>
21: #include <netinet/tcp_seq.h>
22: #define TCPSTATES
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:
30: #include <netdb.h>
31:
32: struct inpcb inpcb;
33: struct tcpcb tcpcb;
34: struct socket socket;
35: struct protosw proto;
36: extern int kmem;
37: extern int Aflag;
38: extern int aflag;
39: extern int nflag;
40:
41: static int first = 1;
42: char *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: */
50: protopr(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 &&
90: inet_lnaof(inpcb.inp_laddr.s_addr) == INADDR_ANY) {
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:
117: /*
118: * Dump TCP statistics structure.
119: */
120: tcp_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));
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));
138: #ifdef notdef
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));
143: #endif
144: }
145:
146: /*
147: * Dump UDP statistics structure.
148: */
149: udp_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));
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));
167: }
168:
169: /*
170: * Dump IP statistics structure.
171: */
172: ip_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));
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);
190: }
191:
192: static 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: */
215: icmp_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));
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));
234: for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
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: }
243: printf("\t%d message%s with bad code fields\n",
244: icmpstat.icps_badcode, plural(icmpstat.icps_badcode));
245: printf("\t%d message%s < minimum length\n",
246: icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort));
247: printf("\t%d bad checksum%s\n",
248: icmpstat.icps_checksum, plural(icmpstat.icps_checksum));
249: printf("\t%d message%s with bad length\n",
250: icmpstat.icps_badlen, plural(icmpstat.icps_badlen));
251: printf("\t%d message response%s generated\n",
252: icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
253: for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
254: if (icmpstat.icps_inhist[i] != 0) {
255: if (first) {
256: printf("\tInput histogram:\n");
257: first = 0;
258: }
259: printf("\t\t%s: %d\n", icmpnames[i],
260: icmpstat.icps_inhist[i]);
261: }
262: }
263:
264: /*
265: * Pretty print an Internet address (net address + port).
266: * If the nflag was specified, use numbers instead of names.
267: */
268: inetprint(in, port, proto)
269: register struct in_addr *in;
270: int port;
271: char *proto;
272: {
273: struct servent *sp = 0;
274: char line[80], *cp, *index();
275:
276: sprintf(line, "%.10s.", inetname(*in));
277: cp = index(line, '\0');
278: if (!nflag && port)
279: sp = getservbyport(port, proto);
280: if (sp || port == 0)
281: sprintf(cp, "%.8s", sp ? sp->s_name : "*");
282: else
283: sprintf(cp, "%d", ntohs((u_short)port));
284: printf(" %-18.18s", line);
285: }
286:
287: /*
288: * Construct an Internet address representation.
289: * If the nflag has been supplied, give
290: * numeric value, otherwise try for symbolic name.
291: */
292: char *
293: inetname(in)
294: struct in_addr in;
295: {
296: char *cp = 0;
297: static char line[50];
298:
299: if (!nflag) {
300: if (inet_lnaof(in) == INADDR_ANY) {
301: struct netent *np;
302:
303: np = getnetbyaddr(inet_netof(in), AF_INET);
304: if (np)
305: cp = np->n_name;
306: } else {
307: struct hostent *hp;
308:
309: hp = gethostbyaddr(&in, sizeof (struct in_addr),
310: AF_INET);
311: if (hp)
312: cp = hp->h_name;
313: }
314: }
315: if (in.s_addr == INADDR_ANY)
316: strcpy(line, "*");
317: else if (cp)
318: strcpy(line, cp);
319: else {
320: u_char *ucp = (u_char *)∈
321: sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]);
322: }
323: return (line);
324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.