home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / netstat / ns.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-23  |  10.9 KB  |  347 lines

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