Annotation of cci/usr/src/etc/nstat/inet.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)inet.c     4.14 (Berkeley) 83/09/21";
                      3: #endif
                      4: 
                      5: #include <sys/types.h>
                      6: #include <sys/socket.h>
                      7: #include <sys/socketvar.h>
                      8: #include <sys/mbuf.h>
                      9: #include <sys/protosw.h>
                     10: 
                     11: #include <net/route.h>
                     12: #include <netinet/in.h>
                     13: #include <netinet/in_systm.h>
                     14: #include <netinet/in_pcb.h>
                     15: #include <netinet/ip.h>
                     16: #include <netinet/ip_icmp.h>
                     17: #include <netinet/icmp_var.h>
                     18: #include <netinet/ip_var.h>
                     19: #include <netinet/tcp.h>
                     20: #include <netinet/tcpip.h>
                     21: #include <netinet/tcp_seq.h>
                     22: #define TCPSTATES
                     23: #include <netinet/tcp_fsm.h>
                     24: #include <netinet/tcp_timer.h>
                     25: #include <netinet/tcp_var.h>
                     26: #include <netinet/tcp_debug.h>
                     27: #include <netinet/udp.h>
                     28: #include <netinet/udp_var.h>
                     29: #include <net/if.h>
                     30: 
                     31: #include <netdb.h>
                     32: #include <nlist.h>
                     33: #include "nstat.h"
                     34: 
                     35: struct inpcb inpcb;
                     36: struct tcpcb tcpcb;
                     37: struct socket sock;
                     38: struct protosw proto;
                     39: 
                     40: extern  long   flaggiven;
                     41: extern int     kmem;           /* file descriptor of kmem file */
                     42: extern char    *system;
                     43: 
                     44: static int first = 1;
                     45: char   *inetname();
                     46: 
                     47: static int     getvm;
                     48: struct nlist   inetnl[] = {
                     49: #                      define  N_TCB           0
                     50:        { "_tcb" },
                     51: 
                     52: #                      define  N_TCPSTAT       1
                     53:        { "_tcpstat" },
                     54: #                      define  N_TCPSTUDY      2
                     55:        { "_tcpstudy" },
                     56: 
                     57: #                      define  N_UDB           3
                     58:        { "_udb" },
                     59: #                      define  N_UDPSTAT       4
                     60:        { "_udpstat" },
                     61: 
                     62: #                      define  N_IPSTAT        5
                     63:        { "_ipstat" },
                     64: #                      define  N_IPINTR        6
                     65:        { "_ipintrq" },
                     66: #                      define N_IPSTUDY        7
                     67:        { "_ipstudy" },
                     68: 
                     69: #                      define  N_ICMPSTAT      8
                     70:        { "_icmpstat" },
                     71: 
                     72: #                      define  N_RAWCB         9
                     73:        { "_rawcb" },
                     74: 
                     75:        { "" },
                     76: };
                     77: 
                     78: struct protoy {
                     79:        u_char  pr_index;               /* index into nlist of cb head */
                     80:        u_char  pr_sindex;              /* index into nlist of stat block */
                     81:        char    *pr_name;               /* well-known name */
                     82: } protoy[] = {
                     83:        { N_TCB,        N_TCPSTAT,              "tcp" },
                     84:        { N_UDB,        N_UDPSTAT,              "udp" },
                     85:        { -1,           N_IPSTAT,               "ip" },
                     86:        { -1,           N_ICMPSTAT,             "icmp" },
                     87:        { -1,           -1,                     0 }
                     88: };
                     89: 
                     90: /*
                     91:  * Print a summary of connections related to an Internet
                     92:  * protocol.  For TCP, also give state of connection.
                     93:  * Listening processes (aflag) are suppressed unless the
                     94:  * -a (all) flag is specified.
                     95:  */
                     96: protopr(name)
                     97:        char *name;
                     98: {
                     99:        off_t off = 0;
                    100:        struct inpcb cb;
                    101:        register struct inpcb *prev, *next;
                    102:        int istcp;
                    103: 
                    104:        struct protoy   *p;
                    105: 
                    106:        if (!getvm) {
                    107:                nlist(system, inetnl);
                    108:                getvm++;
                    109:        }
                    110:        for (p= &protoy[0]; p->pr_name; p++) {
                    111:                if (strcmp(p->pr_name, name) == 0) {
                    112:                        off = inetnl[p->pr_index].n_value;
                    113:                        break;
                    114:                }
                    115:        }
                    116:        if (off == 0) {
                    117:                printf("%s control block: symbol not in namelist\n", name);
                    118:                return;
                    119:        }
                    120:        istcp = strcmp(name, "tcp") == 0;
                    121:        klseek(kmem, off, 0);
                    122:        read(kmem, &cb, sizeof (struct inpcb));
                    123:        inpcb = cb;
                    124:        prev = (struct inpcb *)off;
                    125:        if (first) {
                    126:                printf("Active connections");
                    127:                printf(" (including servers)");
                    128:                putchar('\n');
                    129:                if (Aflag)
                    130:                        printf("%-8.8s ", "PCB");
                    131:                printf("%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s %s\n",
                    132:                        "Proto", "Recv-Q", "Send-Q",
                    133:                        "Local Address", "Foreign Address", "(state)", 
                    134: /*                     "(retry)");*/
                    135:                        "");
                    136:                first = 0;
                    137:        }
                    138:        while (inpcb.inp_next != (struct inpcb *)off) {
                    139:                char *cp;
                    140: 
                    141:                next = inpcb.inp_next;
                    142:                klseek(kmem, (off_t)next, 0);
                    143:                read(kmem, &inpcb, sizeof (inpcb));
                    144:                if (inpcb.inp_prev != prev) {
                    145:                        printf("???\n");
                    146:                        break;
                    147:                }
                    148:                klseek(kmem, (off_t)inpcb.inp_socket, 0);
                    149:                read(kmem, &sock, sizeof (sock));
                    150:                if (istcp) {
                    151:                        klseek(kmem, (off_t)inpcb.inp_ppcb, 0);
                    152:                        read(kmem, &tcpcb, sizeof (tcpcb));
                    153:                }
                    154:                if (Aflag)
                    155:                        printf("%8x ", inpcb.inp_ppcb);
                    156:                printf("%-5.5s %6d %6d ", name, sock.so_rcv.sb_cc,
                    157:                        sock.so_snd.sb_cc);
                    158:                inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name);
                    159:                inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name);
                    160:                if (istcp) {
                    161:                        if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
                    162:                                printf(" %d", tcpcb.t_state);
                    163:                        else
                    164:                                printf(" %s", tcpstates[tcpcb.t_state]);
                    165:                        /* printf(" (%d)", tcpcb.t_rxtshift); */
                    166:                }
                    167:                putchar('\n');
                    168:                if (Aflag) {
                    169:                        printf("\tinpcb:%x,", next);
                    170:                        if (inpcb.inp_route.ro_dst.sa_family==AF_INET) {
                    171:                                struct  sockaddr_in     *sin;
                    172:                                sin = (struct sockaddr_in *)&inpcb.inp_route.ro_dst;
                    173:                                printf(" ro_dst:");
                    174:                                inetprint(&sin->sin_addr, sin->sin_port, name);
                    175:                                if (inpcb.inp_route.ro_rt)
                    176:                                        printrt(inpcb.inp_route.ro_rt);
                    177:                        }
                    178:                        putchar('\n');
                    179:                        putchar('\n');
                    180:                }
                    181:                prev = next;
                    182:        }
                    183: }
                    184: 
                    185: /*
                    186:  * Dump TCP statistics structure.
                    187:  */
                    188: tcp_stats()
                    189: {
                    190:        off_t off;
                    191:        struct tcpstat tcpstat;
                    192:        struct tcpstudy tcpstudy;
                    193: 
                    194:        struct protoy   *p;
                    195:        char    *name = "tcp";
                    196: 
                    197:        if (!getvm) {
                    198:                nlist(system, inetnl);
                    199:                getvm++;
                    200:        }
                    201:        for (p= &protoy[0]; p->pr_name; p++) {
                    202:                if (strcmp(p->pr_name, name) == 0) {
                    203:                        off = inetnl[p->pr_sindex].n_value;
                    204:                        break;
                    205:                }
                    206:        }
                    207:        if (off == 0) {
                    208:                printf("%sstat: symbol not in namelist\n", name);
                    209:                return;
                    210:        }
                    211:        klseek(kmem, off, 0);
                    212:        read(kmem, (char *)&tcpstat, sizeof (tcpstat));
                    213: 
                    214:        printf("%s:\n\t%d bad header checksum%s\n", name,
                    215:                tcpstat.tcps_badsum, plural(tcpstat.tcps_badsum));
                    216:        printf("\t%d bad header offset field%s\n",
                    217:                tcpstat.tcps_badoff, plural(tcpstat.tcps_badoff));
                    218:        printf("\t%d recv incomplete header%s\n",
                    219:                tcpstat.tcps_hdrops, plural(tcpstat.tcps_hdrops));
                    220:        printf("\t%d disconnect due to xmit timedout\n", tcpstat.tcps_xdrops);
                    221:        printf("\t%d bad segment%s\n",
                    222:                tcpstat.tcps_badsegs, plural(tcpstat.tcps_badsegs));
                    223:        printf("\t%d retries due to unacknowledged packet%s\n",
                    224:                tcpstat.tcps_unack, plural(tcpstat.tcps_unack));
                    225: /*
                    226: /*     if (!inetnl[N_TCPSTUDY].n_value) {
                    227: /*             printf("%sstat: symbol tcpstudy not in namelist\n",name);
                    228: /*             return;
                    229: /*     }
                    230: /*     klseek(kmem,(long)inetnl[N_TCPSTUDY].n_value, 0);
                    231: /*     read(kmem, (char *)&tcpstudy, sizeof(tcpstudy));
                    232: /*
                    233: /*     printf("\t# of Incoming Packets Dropped Due To: \n");
                    234: /*     printf("\t\taddr not in pcb: %d\n",tcpstudy.tcps_notinpcb);
                    235: /*     printf("\t\tcontrol block doesnot have tcp control block: %d\n",
                    236: /*                                             tcpstudy.tcps_notcpcb);
                    237: /*     printf("\t\tstate is not in sync: %d\n", tcpstudy.tcps_badstate);
                    238: /*     printf("\t\tcannot connect: %d\n", tcpstudy.tcps_noconnect);
                    239: /*     printf("\t\tack out of seq: %d\n", tcpstudy.tcps_ackoutofseq);
                    240: /*     printf("\t\tdata out of window: %d\n", tcpstudy.tcps_outwinedge);
                    241: /**/
                    242: }
                    243: 
                    244: /*
                    245:  * Dump UDP statistics structure.
                    246:  */
                    247: udp_stats()
                    248: {
                    249:        off_t off;
                    250:        struct udpstat udpstat;
                    251: 
                    252:        struct  protoy  *p;
                    253:        char    *name = "udp";
                    254: 
                    255:        if (!getvm) {
                    256:                nlist(system, inetnl);
                    257:                getvm++;
                    258:        }
                    259:        for (p= &protoy[0]; p->pr_name; p++) {
                    260:                if (strcmp(p->pr_name, name) == 0) {
                    261:                        off = inetnl[p->pr_sindex].n_value;
                    262:                        break;
                    263:                }
                    264:        }
                    265:        if (off == 0) {
                    266:                printf("%sstat: symbol not in namelist\n", name);
                    267:                return;
                    268:        }
                    269:        klseek(kmem, off, 0);
                    270:        read(kmem, (char *)&udpstat, sizeof (udpstat));
                    271:        printf("%s:\n\t%d bad header checksum%s\n", name,
                    272:                udpstat.udps_badsum, plural(udpstat.udps_badsum));
                    273:        printf("\t%d incomplete header%s\n",
                    274:                udpstat.udps_hdrops, plural(udpstat.udps_hdrops));
                    275:        printf("\t%d bad data length field%s\n",
                    276:                udpstat.udps_badlen, plural(udpstat.udps_badlen));
                    277: }
                    278: 
                    279: /*
                    280:  * Dump IP statistics structure.
                    281:  */
                    282: ip_stats()
                    283: {
                    284:        off_t off;
                    285:        off_t off2;
                    286:        struct ipstat ipstat;
                    287:        struct ipstudy ipstudy;
                    288:        struct  ifqueue ipint;
                    289: 
                    290:        struct  protoy  *p;
                    291:        char    *name   = "ip";
                    292: 
                    293:        if (!getvm) {
                    294:                nlist(system, inetnl);
                    295:                getvm++;
                    296:        }
                    297:        for (p= &protoy[0]; p->pr_name; p++) {
                    298:                if (strcmp(p->pr_name, name) == 0) {
                    299:                        off = inetnl[p->pr_sindex].n_value;
                    300:                        break;
                    301:                }
                    302:        }
                    303:        if (off == 0) {
                    304:                printf("%sstat: symbol not in namelist\n", name);
                    305:                return;
                    306:        }
                    307: 
                    308:        klseek(kmem, off, 0);
                    309:        read(kmem, (char *)&ipstat, sizeof (ipstat));
                    310: 
                    311:        printf("%s:\n\t%d bad header checksum%s\n", name,
                    312:                ipstat.ips_badsum, plural(ipstat.ips_badsum));
                    313:        printf("\t%d with size smaller than minimum\n", ipstat.ips_tooshort);
                    314:        printf("\t%d with data size < data length\n", ipstat.ips_toosmall);
                    315:        printf("\t%d with header length < data size\n", ipstat.ips_badhlen);
                    316:        printf("\t%d with data length < header length\n", ipstat.ips_badlen);
                    317: 
                    318: /*     off2 = inetnl[N_IPINTR].n_value;
                    319: /*     if (off2 == 0) {
                    320: /*             printf("ipintrq symbol not in namelist\n");
                    321: /*             return;
                    322: /*     }
                    323: /*     klseek(kmem, off2, 0);
                    324: /*     read(kmem, (char *)&ipint, sizeof (ipint));
                    325: /*
                    326: /*     printf("\tipinput q:%d dropped due to full queue\n", ipint.ifq_drops);
                    327: /*     printf("\tipinput q:%d len \n", ipint.ifq_len);
                    328: /*     printf("\tipinput q:%d maxlen \n", ipint.ifq_maxlen);
                    329: /**/
                    330: 
                    331: /*     off2 = inetnl[N_IPSTUDY].n_value;
                    332: /*     if (off2==0) {
                    333: /*             printf("ipstudy symbol not in namelist\n");
                    334: /*             return;
                    335: /*     }
                    336: /*     klseek(kmem, off2, 0);
                    337: /*     read(kmem, (char *)&ipstudy, sizeof(ipstudy));
                    338: /*     printf("\tPackets Dropped Due To:\n");
                    339: /*     printf("\t\tno ifnet (use full addr) for strictroute: %d\n",
                    340: /*             ipstudy.ips_ssnoifaddr);
                    341: /*     printf("\t\tno interface (use net#) for strictroute: %d\n",
                    342: /*             ipstudy.ips_ssnoifnet);
                    343: /*     printf("\t\tbad option length: %d\n", ipstudy.ips_oplen);
                    344: /*     printf("\t\tcant tell host from net: %d\n", 
                    345: /*                     ipstudy.ips_cantdiffnethost);
                    346: /*     printf("\t\ttime exceeded: %d\n", ipstudy.ips_timxceed);
                    347: /*     printf("\t\tmessage length too big: %d\n", ipstudy.ips_msgsize);
                    348: /*     printf("\t\tbad port: %d\n",ipstudy.ips_badport);
                    349: /*     printf("\t\thost or net unreached: %d\n", ipstudy.ips_unreach);
                    350: /**/
                    351: }
                    352: 
                    353: static char *icmpnames[] = {
                    354:        "echo reply",
                    355:        "#1",
                    356:        "#2",
                    357:        "destination unreachable",
                    358:        "source quench",
                    359:        "routing redirect",
                    360:        "#6",
                    361:        "#7",
                    362:        "echo",
                    363:        "#9",
                    364:        "#10",
                    365:        "time exceeded",
                    366:        "parameter problem",
                    367:        "time stamp",
                    368:        "time stamp reply",
                    369:        "information request",
                    370:        "information request reply"
                    371: };
                    372: 
                    373: /*
                    374:  * Dump ICMP statistics.
                    375:  */
                    376: icmp_stats()
                    377: {
                    378:        off_t off;
                    379:        struct icmpstat icmpstat;
                    380:        register int i, first;
                    381: 
                    382:        struct protoy   *p;
                    383:        char    *name = "icmp";
                    384: 
                    385:        if (!getvm) {
                    386:                nlist(system, inetnl);
                    387:                ++getvm;
                    388:        }
                    389:        for (p= &protoy[0]; p->pr_name; p++) {
                    390:                if (strcmp(p->pr_name, name) == 0) {
                    391:                        off = inetnl[p->pr_sindex].n_value;
                    392:                        break;
                    393:                }
                    394:        }
                    395:        if (off == 0) {
                    396:                printf("%sstat: symbol not in namelist\n", name);
                    397:                return;
                    398:        }
                    399:        klseek(kmem, off, 0);
                    400:        read(kmem, (char *)&icmpstat, sizeof (icmpstat));
                    401:        printf("%s:\n\t%d call%s to icmp_error\n", name,
                    402:                icmpstat.icps_error, plural(icmpstat.icps_error));
                    403:        printf("\t%d error%s not generated 'cuz old message too short\n",
                    404:                icmpstat.icps_oldshort, plural(icmpstat.icps_oldshort));
                    405:        printf("\t%d error%s not generated 'cuz old message was icmp\n",
                    406:                icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp));
                    407:        for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
                    408:                if (icmpstat.icps_outhist[i] != 0) {
                    409:                        if (first) {
                    410:                                printf("\tOutput histogram:\n");
                    411:                                first = 0;
                    412:                        }
                    413:                        printf("\t\t%s: %d\n", icmpnames[i],
                    414:                                icmpstat.icps_outhist[i]);
                    415:                }
                    416:        printf("\t%d message%s with bad code fields\n",
                    417:                icmpstat.icps_badcode, plural(icmpstat.icps_badcode));
                    418:        printf("\t%d message%s < minimum length\n",
                    419:                icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort));
                    420:        printf("\t%d bad checksum%s\n",
                    421:                icmpstat.icps_checksum, plural(icmpstat.icps_checksum));
                    422:        printf("\t%d message%s with bad length\n",
                    423:                icmpstat.icps_badlen, plural(icmpstat.icps_badlen));
                    424:        printf("\t%d message response%s generated\n",
                    425:                icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
                    426:        for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++)
                    427:                if (icmpstat.icps_inhist[i] != 0) {
                    428:                        if (first) {
                    429:                                printf("\tInput histogram:\n");
                    430:                                first = 0;
                    431:                        }
                    432:                        printf("\t\t%s: %d\n", icmpnames[i],
                    433:                                icmpstat.icps_inhist[i]);
                    434:                }
                    435: }
                    436: 
                    437: /*
                    438:  * Pretty print an Internet address (net address + port).
                    439:  * If the nflag was specified, use numbers instead of names.
                    440:  */
                    441: inetprint(in, port, proto)
                    442:        register struct in_addr *in;
                    443:        int port;
                    444:        char *proto;
                    445: {
                    446:        struct servent *sp = 0;
                    447:        char line[80], *cp, *index();
                    448: 
                    449:        sprintf(line, "%.10s.", inetname(*in));
                    450:        cp = index(line, '\0');
                    451:        if (!nflag && port)
                    452:                sp = getservbyport(port, proto);
                    453:        if (sp || port == 0)
                    454:                sprintf(cp, "%.8s", sp ? sp->s_name : "*");
                    455:        else
                    456:                sprintf(cp, "%d", ntohs((u_short)port));
                    457:        printf(" %-18.18s", line);
                    458: }
                    459: 
                    460: /*
                    461:  * Construct an Internet address representation.
                    462:  * If the nflag has been supplied, give 
                    463:  * numeric value, otherwise try for symbolic name.
                    464:  */
                    465: char *
                    466: inetname(in)
                    467:        struct in_addr in;
                    468: {
                    469:        char *cp = 0;
                    470:        static char line[50];
                    471: 
                    472:        if (!nflag) {
                    473:                if (inet_lnaof(in) == INADDR_ANY) {
                    474:                        struct netent *np;
                    475: 
                    476:                        np = getnetbyaddr(inet_netof(in), AF_INET);
                    477:                        if (np)
                    478:                                cp = np->n_name;
                    479:                } else {
                    480:                        struct hostent *hp;
                    481: 
                    482:                        hp = gethostbyaddr(&in, sizeof (struct in_addr),
                    483:                                AF_INET);
                    484:                        if (hp)
                    485:                                cp = hp->h_name;
                    486:                }
                    487:        }
                    488:        if (in.s_addr == INADDR_ANY)
                    489:                strcpy(line, "*");
                    490:        else if (cp)
                    491:                strcpy(line, cp);
                    492:        else {
                    493:                u_char *ucp = (u_char *)&in;
                    494:                sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]);
                    495:        }
                    496:        return (line);
                    497: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.