home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / E-zine / Magazines / crh / freebsd / rootkit / netstat / ns.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-27  |  11.0 KB  |  352 lines

  1. /*
  2.  * Copyright (c) 1983, 1988, 1993
  3.  *    The Regents of the University of California.  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    8.1 (Berkeley) 6/6/93";
  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. #include "netstat.h"
  66.  
  67. struct    nspcb nspcb;
  68. struct    sppcb sppcb;
  69. struct    socket sockb;
  70.  
  71. static char *ns_prpr __P((struct ns_addr *));
  72. static void ns_erputil __P((int, int));
  73.  
  74. static    int first = 1;
  75.  
  76. /*
  77.  * Print a summary of connections related to a Network Systems
  78.  * protocol.  For SPP, also give state of connection.
  79.  * Listening processes (aflag) are suppressed unless the
  80.  * -a (all) flag is specified.
  81.  */
  82.  
  83. void
  84. nsprotopr(off, name)
  85.     u_long 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.     kread(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.         u_long ppcb;
  102.  
  103.         next = nspcb.nsp_next;
  104.         kread((u_long)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.         kread((u_long)nspcb.nsp_socket,
  113.                 (char *)&sockb, sizeof (sockb));
  114.         ppcb = (u_long) nspcb.nsp_pcb;
  115.         if (ppcb) {
  116.             if (isspp) {
  117.                 kread(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. void
  159. spp_stats(off, name)
  160.     u_long off;
  161.     char *name;
  162. {
  163.     struct spp_istat spp_istat;
  164. #define sppstat spp_istat.newstats
  165.  
  166.     if (off == 0)
  167.         return;
  168.     kread(off, (char *)&spp_istat, sizeof (spp_istat));
  169.     printf("%s:\n", name);
  170.     ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets ");
  171.     ANY(spp_istat.gonawy, "connection", " terminated due to our end dying");
  172.     ANY(spp_istat.nonucn, "connection",
  173.         " dropped due to inability to connect");
  174.     ANY(spp_istat.noconn, "connection",
  175.         " dropped due to inability to connect");
  176.     ANY(spp_istat.notme, "connection",
  177.         " incompleted due to mismatched id's");
  178.     ANY(spp_istat.wrncon, "connection", " dropped due to mismatched id's");
  179.     ANY(spp_istat.bdreas, "packet", " dropped out of sequence");
  180.     ANY(spp_istat.lstdup, "packet", " duplicating the highest packet");
  181.     ANY(spp_istat.notyet, "packet", " refused as exceeding allocation");
  182.     ANY(sppstat.spps_connattempt, "connection", " initiated");
  183.     ANY(sppstat.spps_accepts, "connection", " accepted");
  184.     ANY(sppstat.spps_connects, "connection", " established");
  185.     ANY(sppstat.spps_drops, "connection", " dropped");
  186.     ANY(sppstat.spps_conndrops, "embryonic connection", " dropped");
  187.     ANY(sppstat.spps_closed, "connection", " closed (includes drops)");
  188.     ANY(sppstat.spps_segstimed, "packet", " where we tried to get rtt");
  189.     ANY(sppstat.spps_rttupdated, "time", " we got rtt");
  190.     ANY(sppstat.spps_delack, "delayed ack", " sent");
  191.     ANY(sppstat.spps_timeoutdrop, "connection", " dropped in rxmt timeout");
  192.     ANY(sppstat.spps_rexmttimeo, "retransmit timeout", "");
  193.     ANY(sppstat.spps_persisttimeo, "persist timeout", "");
  194.     ANY(sppstat.spps_keeptimeo, "keepalive timeout", "");
  195.     ANY(sppstat.spps_keepprobe, "keepalive probe", " sent");
  196.     ANY(sppstat.spps_keepdrops, "connection", " dropped in keepalive");
  197.     ANY(sppstat.spps_sndtotal, "total packet", " sent");
  198.     ANY(sppstat.spps_sndpack, "data packet", " sent");
  199.     ANY(sppstat.spps_sndbyte, "data byte", " sent");
  200.     ANY(sppstat.spps_sndrexmitpack, "data packet", " retransmitted");
  201.     ANY(sppstat.spps_sndrexmitbyte, "data byte", " retransmitted");
  202.     ANY(sppstat.spps_sndacks, "ack-only packet", " sent");
  203.     ANY(sppstat.spps_sndprobe, "window probe", " sent");
  204.     ANY(sppstat.spps_sndurg, "packet", " sent with URG only");
  205.     ANY(sppstat.spps_sndwinup, "window update-only packet", " sent");
  206.     ANY(sppstat.spps_sndctrl, "control (SYN|FIN|RST) packet", " sent");
  207.     ANY(sppstat.spps_sndvoid, "request", " to send a non-existant packet");
  208.     ANY(sppstat.spps_rcvtotal, "total packet", " received");
  209.     ANY(sppstat.spps_rcvpack, "packet", " received in sequence");
  210.     ANY(sppstat.spps_rcvbyte, "byte", " received in sequence");
  211.     ANY(sppstat.spps_rcvbadsum, "packet", " received with ccksum errs");
  212.     ANY(sppstat.spps_rcvbadoff, "packet", " received with bad offset");
  213.     ANY(sppstat.spps_rcvshort, "packet", " received too short");
  214.     ANY(sppstat.spps_rcvduppack, "duplicate-only packet", " received");
  215.     ANY(sppstat.spps_rcvdupbyte, "duplicate-only byte", " received");
  216.     ANY(sppstat.spps_rcvpartduppack, "packet", " with some duplicate data");
  217.     ANY(sppstat.spps_rcvpartdupbyte, "dup. byte", " in part-dup. packet");
  218.     ANY(sppstat.spps_rcvoopack, "out-of-order packet", " received");
  219.     ANY(sppstat.spps_rcvoobyte, "out-of-order byte", " received");
  220.     ANY(sppstat.spps_rcvpackafterwin, "packet", " with data after window");
  221.     ANY(sppstat.spps_rcvbyteafterwin, "byte", " rcvd after window");
  222.     ANY(sppstat.spps_rcvafterclose, "packet", " rcvd after 'close'");
  223.     ANY(sppstat.spps_rcvwinprobe, "rcvd window probe packet", "");
  224.     ANY(sppstat.spps_rcvdupack, "rcvd duplicate ack", "");
  225.     ANY(sppstat.spps_rcvacktoomuch, "rcvd ack", " for unsent data");
  226.     ANY(sppstat.spps_rcvackpack, "rcvd ack packet", "");
  227.     ANY(sppstat.spps_rcvackbyte, "byte", " acked by rcvd acks");
  228.     ANY(sppstat.spps_rcvwinupd, "rcvd window update packet", "");
  229. }
  230. #undef ANY
  231. #define ANY(x,y,z)  ((x) ? printf("\t%d %s%s%s\n",x,y,plural(x),z) : 0)
  232.  
  233. /*
  234.  * Dump IDP statistics structure.
  235.  */
  236. void
  237. idp_stats(off, name)
  238.     u_long off;
  239.     char *name;
  240. {
  241.     struct idpstat idpstat;
  242.  
  243.     if (off == 0)
  244.         return;
  245.     kread(off, (char *)&idpstat, sizeof (idpstat));
  246.     printf("%s:\n", name);
  247.     ANY(idpstat.idps_toosmall, "packet", " smaller than a header");
  248.     ANY(idpstat.idps_tooshort, "packet", " smaller than advertised");
  249.     ANY(idpstat.idps_badsum, "packet", " with bad checksums");
  250. }
  251.  
  252. static    struct {
  253.     u_short code;
  254.     char *name;
  255.     char *where;
  256. } ns_errnames[] = {
  257.     {0, "Unspecified Error", " at Destination"},
  258.     {1, "Bad Checksum", " at Destination"},
  259.     {2, "No Listener", " at Socket"},
  260.     {3, "Packet", " Refused due to lack of space at Destination"},
  261.     {01000, "Unspecified Error", " while gatewayed"},
  262.     {01001, "Bad Checksum", " while gatewayed"},
  263.     {01002, "Packet", " forwarded too many times"},
  264.     {01003, "Packet", " too large to be forwarded"},
  265.     {-1, 0, 0},
  266. };
  267.  
  268. /*
  269.  * Dump NS Error statistics structure.
  270.  */
  271. /*ARGSUSED*/
  272. void
  273. nserr_stats(off, name)
  274.     u_long off;
  275.     char *name;
  276. {
  277.     struct ns_errstat ns_errstat;
  278.     register int j;
  279.     register int histoprint = 1;
  280.     int z;
  281.  
  282.     if (off == 0)
  283.         return;
  284.     kread(off, (char *)&ns_errstat, sizeof (ns_errstat));
  285.     printf("NS error statistics:\n");
  286.     ANY(ns_errstat.ns_es_error, "call", " to ns_error");
  287.     ANY(ns_errstat.ns_es_oldshort, "error",
  288.         " ignored due to insufficient addressing");
  289.     ANY(ns_errstat.ns_es_oldns_err, "error request",
  290.         " in response to error packets");
  291.     ANY(ns_errstat.ns_es_tooshort, "error packet",
  292.         " received incomplete");
  293.     ANY(ns_errstat.ns_es_badcode, "error packet",
  294.         " received of unknown type");
  295.     for(j = 0; j < NS_ERR_MAX; j ++) {
  296.         z = ns_errstat.ns_es_outhist[j];
  297.         if (z && histoprint) {
  298.             printf("Output Error Histogram:\n");
  299.             histoprint = 0;
  300.         }
  301.         ns_erputil(z, ns_errstat.ns_es_codes[j]);
  302.  
  303.     }
  304.     histoprint = 1;
  305.     for(j = 0; j < NS_ERR_MAX; j ++) {
  306.         z = ns_errstat.ns_es_inhist[j];
  307.         if (z && histoprint) {
  308.             printf("Input Error Histogram:\n");
  309.             histoprint = 0;
  310.         }
  311.         ns_erputil(z, ns_errstat.ns_es_codes[j]);
  312.     }
  313. }
  314.  
  315. static void
  316. ns_erputil(z, c)
  317.     int z, c;
  318. {
  319.     int j;
  320.     char codebuf[30];
  321.     char *name, *where;
  322.  
  323.     for(j = 0;; j ++) {
  324.         if ((name = ns_errnames[j].name) == 0)
  325.             break;
  326.         if (ns_errnames[j].code == c)
  327.             break;
  328.     }
  329.     if (name == 0)  {
  330.         if (c > 01000)
  331.             where = "in transit";
  332.         else
  333.             where = "at destination";
  334.         sprintf(codebuf, "Unknown XNS error code 0%o", c);
  335.         name = codebuf;
  336.     } else
  337.         where =  ns_errnames[j].where;
  338.     ANY(z, name, where);
  339. }
  340.  
  341. static struct sockaddr_ns ssns = {AF_NS};
  342.  
  343. static
  344. char *ns_prpr(x)
  345.     struct ns_addr *x;
  346. {
  347.     struct sockaddr_ns *sns = &ssns;
  348.  
  349.     sns->sns_addr = *x;
  350.     return(ns_print((struct sockaddr *)sns));
  351. }
  352.