1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: 8: #ifndef lint 9: static char sccsid[] = "@(#)ns.c 5.3 (Berkeley) 9/12/85"; 10: #endif not lint 11: 12: #include <stdio.h> 13: #include <errno.h> 14: #include <nlist.h> 15: 16: #include <sys/types.h> 17: #include <sys/socket.h> 18: #include <sys/socketvar.h> 19: #include <sys/mbuf.h> 20: #include <sys/protosw.h> 21: 22: #include <net/route.h> 23: #include <net/if.h> 24: 25: #include <netinet/tcp_fsm.h> 26: #include <netinet/tcp_timer.h> 27: 28: #include <netns/ns.h> 29: #include <netns/ns_pcb.h> 30: #include <netns/idp.h> 31: #include <netns/idp_var.h> 32: #include <netns/ns_error.h> 33: #include <netns/sp.h> 34: #include <netns/spidp.h> 35: #include <netns/spp_var.h> 36: #define SANAMES 37: #include <netns/spp_debug.h> 38: 39: 40: struct nspcb nspcb; 41: struct sppcb sppcb; 42: struct socket sockb; 43: struct protosw proto; 44: extern int kmem; 45: extern int Aflag; 46: extern int aflag; 47: extern int nflag; 48: char *ns_prpr(); 49: 50: static int first = 1; 51: 52: /* 53: * Print a summary of connections related to a Network Systems 54: * protocol. For SPP, also give state of connection. 55: * Listening processes (aflag) are suppressed unless the 56: * -a (all) flag is specified. 57: */ 58: 59: nsprotopr(off, name) 60: off_t off; 61: char *name; 62: { 63: struct nspcb cb; 64: register struct nspcb *prev, *next; 65: int isspp; 66: 67: if (off == 0) 68: return; 69: isspp = strcmp(name, "spp") == 0; 70: klseek(kmem, off, 0); 71: read(kmem, &cb, sizeof (struct nspcb)); 72: nspcb = cb; 73: prev = (struct nspcb *)off; 74: if (nspcb.nsp_next == (struct nspcb *)off) 75: return; 76: for (;nspcb.nsp_next != (struct nspcb *)off; prev = next) { 77: char *cp; 78: off_t ppcb; 79: 80: next = nspcb.nsp_next; 81: klseek(kmem, (off_t)next, 0); 82: read(kmem, &nspcb, sizeof (nspcb)); 83: if (nspcb.nsp_prev != prev) { 84: printf("???\n"); 85: break; 86: } 87: if (!aflag && ns_nullhost(nspcb.nsp_faddr) ) { 88: continue; 89: } 90: klseek(kmem, (off_t)nspcb.nsp_socket, 0); 91: read(kmem, &sockb, sizeof (sockb)); 92: ppcb = (off_t) nspcb.nsp_pcb; 93: if (ppcb) { 94: if (isspp) { 95: klseek(kmem, ppcb, 0); 96: read(kmem, &sppcb, sizeof (sppcb)); 97: } else continue; 98: } else 99: if (isspp) continue; 100: if (first) { 101: printf("Active NS connections"); 102: if (aflag) 103: printf(" (including servers)"); 104: putchar('\n'); 105: if (Aflag) 106: printf("%-8.8s ", "PCB"); 107: printf(Aflag ? 108: "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 109: "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 110: "Proto", "Recv-Q", "Send-Q", 111: "Local Address", "Foreign Address", "(state)"); 112: first = 0; 113: } 114: if (Aflag) 115: printf("%8x ", ppcb); 116: printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, 117: sockb.so_snd.sb_cc); 118: printf(" %-22.22s", ns_prpr(&nspcb.nsp_laddr)); 119: printf(" %-22.22s", ns_prpr(&nspcb.nsp_faddr)); 120: if (isspp) { 121: extern char *tcpstates[]; 122: if (sppcb.s_state < 0 || sppcb.s_state >= TCP_NSTATES) 123: printf(" %d", sppcb.s_state); 124: else 125: printf(" %s", tcpstates[sppcb.s_state]); 126: } 127: putchar('\n'); 128: prev = next; 129: } 130: } 131: #define ANY(x,y,z) ((x) ? printf("\t%d %s%s%s\n",x,y,plural(x),z) : 0) 132: 133: /* 134: * Dump SPP statistics structure. 135: */ 136: spp_stats(off, name) 137: off_t off; 138: char *name; 139: { 140: struct spp_istat spp_istat; 141: 142: if (off == 0) 143: return; 144: klseek(kmem, off, 0); 145: read(kmem, (char *)&spp_istat, sizeof (spp_istat)); 146: printf("%s:\n", name); 147: ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets "); 148: ANY(spp_istat.gonawy, "connection", " terminated due to our end dying"); 149: ANY(spp_istat.nonucn, "connection", " dropped due to inability to connect"); 150: ANY(spp_istat.noconn, "connection", " dropped due to inability to connect"); 151: ANY(spp_istat.notme, "connection", " incompleted due to mismatched id's"); 152: ANY(spp_istat.wrncon, "connection", " dropped due to mismatched id's"); 153: ANY(spp_istat.bdreas, "packet", " dropped out of sequence"); 154: ANY(spp_istat.lstdup, "packet", " duplicating the highest packet"); 155: ANY(spp_istat.notyet, "packet", " refused as exceeding allocation"); 156: } 157: 158: /* 159: * Dump IDP statistics structure. 160: */ 161: idp_stats(off, name) 162: off_t off; 163: char *name; 164: { 165: struct idpstat idpstat; 166: 167: if (off == 0) 168: return; 169: klseek(kmem, off, 0); 170: read(kmem, (char *)&idpstat, sizeof (idpstat)); 171: ANY(idpstat.idps_toosmall, "packet", " smaller than a header"); 172: ANY(idpstat.idps_tooshort, "packet", " smaller than advertised"); 173: ANY(idpstat.idps_badsum, "packet", " with bad checksums"); 174: } 175: 176: static char *((ns_errnames[])[2]) = { 177: {"Unspecified Error", " at Destination"}, 178: {"Bad Checksum", " at Destination"}, 179: {"No Listener", " at Socket"}, 180: {"Packet", " Refused due to lack of space at Destination"}, 181: {"Unspecified Error", " while gatewayed"}, 182: {"Bad Checksum", " while gatewayed"}, 183: {"Packet", " forwarded too many times"}, 184: {"Packet", " too large to be forwarded"}, 185: }; 186: 187: /* 188: * Dump NS Error statistics structure. 189: */ 190: nserr_stats(off, name) 191: off_t off; 192: char *name; 193: { 194: struct ns_errstat ns_errstat; 195: register int j; 196: register int histoprint = 1; 197: int z; 198: 199: if (off == 0) 200: return; 201: klseek(kmem, off, 0); 202: read(kmem, (char *)&ns_errstat, sizeof (ns_errstat)); 203: printf("NS error statistics:\n"); 204: ANY(ns_errstat.ns_es_error, "call", " to ns_error"); 205: ANY(ns_errstat.ns_es_oldshort, "error", 206: " ignored due to insufficient addressing"); 207: ANY(ns_errstat.ns_es_oldns_err, "error request", 208: " in response to error packets"); 209: ANY(ns_errstat.ns_es_tooshort, "error packet", 210: " received incomplete"); 211: ANY(ns_errstat.ns_es_badcode, "error packet", 212: " received of unknown type"); 213: for(j = 0; j < NS_ERR_MAX; j ++) { 214: z = ns_errstat.ns_es_outhist[j]; 215: if (z && histoprint) { 216: printf("Output Error Histogram:\n"); 217: histoprint = 0; 218: } 219: ANY(z, ns_errnames[j][0], ns_errnames[j][1]); 220: } 221: histoprint = 1; 222: for(j = 0; j < NS_ERR_MAX; j ++) { 223: z = ns_errstat.ns_es_inhist[j]; 224: if (z && histoprint) { 225: printf("Input Error Histogram:\n"); 226: histoprint = 0; 227: } 228: ANY(z, ns_errnames[j][0], ns_errnames[j][1]); 229: } 230: } 231: static struct sockaddr_ns ssns = {AF_NS}; 232: 233: char *ns_prpr(x) 234: struct ns_addr *x; 235: { 236: extern char *ns_print(); 237: struct sockaddr_ns *sns = &ssns; 238: sns->sns_addr = *x; 239: return(ns_print(sns)); 240: }