ssufixlen --> slen; fix other minor bugs concerning masks.
[unix-history] / usr / src / usr.bin / netstat / ns.c
CommitLineData
a1f8d2f2 1/*
b36fc510 2 * Copyright (c) 1985, 1988 Regents of the University of California.
ee3f90a5
MK
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
b36fc510
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
a1f8d2f2
KS
16 */
17
a1f8d2f2 18#ifndef lint
b36fc510
KB
19static char sccsid[] = "@(#)ns.c 5.9 (Berkeley) %G%";
20#endif /* not lint */
a1f8d2f2
KS
21
22#include <stdio.h>
23#include <errno.h>
24#include <nlist.h>
25
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <sys/socketvar.h>
29#include <sys/mbuf.h>
30#include <sys/protosw.h>
31
32#include <net/route.h>
33#include <net/if.h>
34
35#include <netinet/tcp_fsm.h>
a1f8d2f2
KS
36
37#include <netns/ns.h>
38#include <netns/ns_pcb.h>
39#include <netns/idp.h>
40#include <netns/idp_var.h>
41#include <netns/ns_error.h>
42#include <netns/sp.h>
43#include <netns/spidp.h>
cacc72f7 44#include <netns/spp_timer.h>
a1f8d2f2
KS
45#include <netns/spp_var.h>
46#define SANAMES
47#include <netns/spp_debug.h>
48
49
50struct nspcb nspcb;
51struct sppcb sppcb;
52struct socket sockb;
a1f8d2f2
KS
53extern int kmem;
54extern int Aflag;
55extern int aflag;
56extern int nflag;
f7c99b06 57extern char *plural();
a1f8d2f2
KS
58char *ns_prpr();
59
60static int first = 1;
61
62/*
63 * Print a summary of connections related to a Network Systems
64 * protocol. For SPP, also give state of connection.
65 * Listening processes (aflag) are suppressed unless the
66 * -a (all) flag is specified.
67 */
68
69nsprotopr(off, name)
70 off_t off;
71 char *name;
72{
73 struct nspcb cb;
74 register struct nspcb *prev, *next;
75 int isspp;
76
4a920942 77 if (off == 0)
a1f8d2f2 78 return;
a1f8d2f2
KS
79 isspp = strcmp(name, "spp") == 0;
80 klseek(kmem, off, 0);
f7c99b06 81 read(kmem, (char *)&cb, sizeof (struct nspcb));
a1f8d2f2
KS
82 nspcb = cb;
83 prev = (struct nspcb *)off;
4a920942
MK
84 if (nspcb.nsp_next == (struct nspcb *)off)
85 return;
a1f8d2f2 86 for (;nspcb.nsp_next != (struct nspcb *)off; prev = next) {
a1f8d2f2
KS
87 off_t ppcb;
88
89 next = nspcb.nsp_next;
90 klseek(kmem, (off_t)next, 0);
f7c99b06 91 read(kmem, (char *)&nspcb, sizeof (nspcb));
a1f8d2f2
KS
92 if (nspcb.nsp_prev != prev) {
93 printf("???\n");
94 break;
95 }
96 if (!aflag && ns_nullhost(nspcb.nsp_faddr) ) {
97 continue;
98 }
99 klseek(kmem, (off_t)nspcb.nsp_socket, 0);
f7c99b06 100 read(kmem, (char *)&sockb, sizeof (sockb));
a1f8d2f2
KS
101 ppcb = (off_t) nspcb.nsp_pcb;
102 if (ppcb) {
103 if (isspp) {
104 klseek(kmem, ppcb, 0);
f7c99b06 105 read(kmem, (char *)&sppcb, sizeof (sppcb));
a1f8d2f2
KS
106 } else continue;
107 } else
108 if (isspp) continue;
26ebe146
MK
109 if (first) {
110 printf("Active NS connections");
111 if (aflag)
112 printf(" (including servers)");
113 putchar('\n');
114 if (Aflag)
115 printf("%-8.8s ", "PCB");
116 printf(Aflag ?
117 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
118 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
119 "Proto", "Recv-Q", "Send-Q",
120 "Local Address", "Foreign Address", "(state)");
121 first = 0;
122 }
a1f8d2f2
KS
123 if (Aflag)
124 printf("%8x ", ppcb);
125 printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
126 sockb.so_snd.sb_cc);
127 printf(" %-22.22s", ns_prpr(&nspcb.nsp_laddr));
128 printf(" %-22.22s", ns_prpr(&nspcb.nsp_faddr));
129 if (isspp) {
130 extern char *tcpstates[];
f7c99b06 131 if (sppcb.s_state >= TCP_NSTATES)
a1f8d2f2
KS
132 printf(" %d", sppcb.s_state);
133 else
134 printf(" %s", tcpstates[sppcb.s_state]);
135 }
136 putchar('\n');
137 prev = next;
138 }
139}
42e83ef1 140#define ANY(x,y,z) ((x) ? printf("\t%d %s%s%s -- %s\n",x,y,plural(x),z,"x") : 0)
a1f8d2f2
KS
141
142/*
143 * Dump SPP statistics structure.
144 */
145spp_stats(off, name)
146 off_t off;
147 char *name;
148{
149 struct spp_istat spp_istat;
42e83ef1 150#define sppstat spp_istat.newstats
a1f8d2f2 151
4a920942 152 if (off == 0)
a1f8d2f2 153 return;
a1f8d2f2
KS
154 klseek(kmem, off, 0);
155 read(kmem, (char *)&spp_istat, sizeof (spp_istat));
156 printf("%s:\n", name);
157 ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets ");
158 ANY(spp_istat.gonawy, "connection", " terminated due to our end dying");
159 ANY(spp_istat.nonucn, "connection", " dropped due to inability to connect");
160 ANY(spp_istat.noconn, "connection", " dropped due to inability to connect");
161 ANY(spp_istat.notme, "connection", " incompleted due to mismatched id's");
162 ANY(spp_istat.wrncon, "connection", " dropped due to mismatched id's");
163 ANY(spp_istat.bdreas, "packet", " dropped out of sequence");
164 ANY(spp_istat.lstdup, "packet", " duplicating the highest packet");
165 ANY(spp_istat.notyet, "packet", " refused as exceeding allocation");
42e83ef1
KS
166 ANY(sppstat.spps_connattempt, "connection", " initiated");
167 ANY(sppstat.spps_accepts, "connection", " accepted");
168 ANY(sppstat.spps_connects, "connection", " established");
169 ANY(sppstat.spps_drops, "connection", " dropped");
170 ANY(sppstat.spps_conndrops, "embryonic connection", " dropped");
171 ANY(sppstat.spps_closed, "connection", " closed (includes drops)");
172 ANY(sppstat.spps_segstimed, "packet", " where we tried to get rtt");
173 ANY(sppstat.spps_rttupdated, "time", " we got rtt");
174 ANY(sppstat.spps_delack, "delayed ack", " sent");
175 ANY(sppstat.spps_timeoutdrop, "connection", " dropped in rxmt timeout");
176 ANY(sppstat.spps_rexmttimeo, "retransmit timeout", "");
177 ANY(sppstat.spps_persisttimeo, "persist timeout", "");
178 ANY(sppstat.spps_keeptimeo, "keepalive timeout", "");
179 ANY(sppstat.spps_keepprobe, "keepalive probe", " sent");
180 ANY(sppstat.spps_keepdrops, "connection", " dropped in keepalive");
181 ANY(sppstat.spps_sndtotal, "total packet", " sent");
182 ANY(sppstat.spps_sndpack, "data packet", " sent");
183 ANY(sppstat.spps_sndbyte, "data byte", " sent");
184 ANY(sppstat.spps_sndrexmitpack, "data packet", " retransmitted");
185 ANY(sppstat.spps_sndrexmitbyte, "data byte", " retransmitted");
186 ANY(sppstat.spps_sndacks, "ack-only packet", " sent");
187 ANY(sppstat.spps_sndprobe, "window probe", " sent");
188 ANY(sppstat.spps_sndurg, "packet", " sent with URG only");
189 ANY(sppstat.spps_sndwinup, "window update-only packet", " sent");
190 ANY(sppstat.spps_sndctrl, "control (SYN|FIN|RST) packet", " sent");
191 ANY(sppstat.spps_sndvoid, "request", " to send a non-existant packet");
192 ANY(sppstat.spps_rcvtotal, "total packet", " received");
193 ANY(sppstat.spps_rcvpack, "packet", " received in sequence");
194 ANY(sppstat.spps_rcvbyte, "byte", " received in sequence");
195 ANY(sppstat.spps_rcvbadsum, "packet", " received with ccksum errs");
196 ANY(sppstat.spps_rcvbadoff, "packet", " received with bad offset");
197 ANY(sppstat.spps_rcvshort, "packet", " received too short");
198 ANY(sppstat.spps_rcvduppack, "duplicate-only packet", " received");
199 ANY(sppstat.spps_rcvdupbyte, "duplicate-only byte", " received");
200 ANY(sppstat.spps_rcvpartduppack, "packet", " with some duplicate data");
201 ANY(sppstat.spps_rcvpartdupbyte, "dup. byte", " in part-dup. packet");
202 ANY(sppstat.spps_rcvoopack, "out-of-order packet", " received");
203 ANY(sppstat.spps_rcvoobyte, "out-of-order byte", " received");
204 ANY(sppstat.spps_rcvpackafterwin, "packet", " with data after window");
205 ANY(sppstat.spps_rcvbyteafterwin, "byte", " rcvd after window");
206 ANY(sppstat.spps_rcvafterclose, "packet", " rcvd after 'close'");
207 ANY(sppstat.spps_rcvwinprobe, "rcvd window probe packet", "");
208 ANY(sppstat.spps_rcvdupack, "rcvd duplicate ack", "");
209 ANY(sppstat.spps_rcvacktoomuch, "rcvd ack", " for unsent data");
210 ANY(sppstat.spps_rcvackpack, "rcvd ack packet", "");
211 ANY(sppstat.spps_rcvackbyte, "byte", " acked by rcvd acks");
212 ANY(sppstat.spps_rcvwinupd, "rcvd window update packet", "");
a1f8d2f2 213}
42e83ef1
KS
214#undef ANY
215#define ANY(x,y,z) ((x) ? printf("\t%d %s%s%s\n",x,y,plural(x),z) : 0)
a1f8d2f2
KS
216
217/*
218 * Dump IDP statistics structure.
219 */
220idp_stats(off, name)
221 off_t off;
222 char *name;
223{
224 struct idpstat idpstat;
225
4a920942 226 if (off == 0)
a1f8d2f2 227 return;
a1f8d2f2
KS
228 klseek(kmem, off, 0);
229 read(kmem, (char *)&idpstat, sizeof (idpstat));
f7c99b06 230 printf("%s:\n", name);
a1f8d2f2
KS
231 ANY(idpstat.idps_toosmall, "packet", " smaller than a header");
232 ANY(idpstat.idps_tooshort, "packet", " smaller than advertised");
233 ANY(idpstat.idps_badsum, "packet", " with bad checksums");
234}
235
42e83ef1
KS
236static struct {
237 u_short code;
238 char *name;
239 char *where;
240} ns_errnames[] = {
241 {0, "Unspecified Error", " at Destination"},
242 {1, "Bad Checksum", " at Destination"},
243 {2, "No Listener", " at Socket"},
244 {3, "Packet", " Refused due to lack of space at Destination"},
245 {01000, "Unspecified Error", " while gatewayed"},
246 {01001, "Bad Checksum", " while gatewayed"},
247 {01002, "Packet", " forwarded too many times"},
248 {01003, "Packet", " too large to be forwarded"},
249 {-1, 0, 0},
a1f8d2f2
KS
250};
251
252/*
253 * Dump NS Error statistics structure.
254 */
f7c99b06 255/*ARGSUSED*/
a1f8d2f2
KS
256nserr_stats(off, name)
257 off_t off;
258 char *name;
259{
260 struct ns_errstat ns_errstat;
261 register int j;
262 register int histoprint = 1;
263 int z;
264
4a920942 265 if (off == 0)
a1f8d2f2 266 return;
a1f8d2f2
KS
267 klseek(kmem, off, 0);
268 read(kmem, (char *)&ns_errstat, sizeof (ns_errstat));
269 printf("NS error statistics:\n");
270 ANY(ns_errstat.ns_es_error, "call", " to ns_error");
271 ANY(ns_errstat.ns_es_oldshort, "error",
272 " ignored due to insufficient addressing");
273 ANY(ns_errstat.ns_es_oldns_err, "error request",
274 " in response to error packets");
275 ANY(ns_errstat.ns_es_tooshort, "error packet",
276 " received incomplete");
277 ANY(ns_errstat.ns_es_badcode, "error packet",
278 " received of unknown type");
279 for(j = 0; j < NS_ERR_MAX; j ++) {
280 z = ns_errstat.ns_es_outhist[j];
281 if (z && histoprint) {
282 printf("Output Error Histogram:\n");
283 histoprint = 0;
284 }
42e83ef1
KS
285 ns_erputil(z, ns_errstat.ns_es_codes[j]);
286
a1f8d2f2
KS
287 }
288 histoprint = 1;
289 for(j = 0; j < NS_ERR_MAX; j ++) {
290 z = ns_errstat.ns_es_inhist[j];
291 if (z && histoprint) {
292 printf("Input Error Histogram:\n");
293 histoprint = 0;
294 }
42e83ef1
KS
295 ns_erputil(z, ns_errstat.ns_es_codes[j]);
296 }
297}
298static
299ns_erputil(z, c)
300{
301 int j;
302 char codebuf[30];
303 char *name, *where;
304 for(j = 0;; j ++) {
305 if ((name = ns_errnames[j].name) == 0)
306 break;
307 if (ns_errnames[j].code == c)
308 break;
a1f8d2f2 309 }
42e83ef1
KS
310 if (name == 0) {
311 if (c > 01000)
312 where = "in transit";
313 else
314 where = "at destination";
315 sprintf(codebuf, "Unknown XNS error code 0%o", c);
316 name = codebuf;
317 } else
318 where = ns_errnames[j].where;
319 ANY(z, name, where);
a1f8d2f2
KS
320}
321static struct sockaddr_ns ssns = {AF_NS};
322
323char *ns_prpr(x)
324struct ns_addr *x;
325{
326 extern char *ns_print();
327 struct sockaddr_ns *sns = &ssns;
328 sns->sns_addr = *x;
329 return(ns_print(sns));
330}