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