# 2.11BSD#431 - /usr/src/ucb/PORT/systat/netstat.c

##### Functions

    closenetstat      X
    cmdnetstat        X
    fetchnetstat      X
    initnetstat       X
    labelnetstat      X
    opennetstat       X
    shownetstat       X

##### Macros

    C                 X
    FADDR             X
    LADDR             X
    NIF_FACHG         X
    NIF_LACHG         X
    PROTO             X
    RCVCC             X
    SNDCC             X
    STATE             X
    TCPSTATES         X
    X_TCB             X
    X_UDB             X
    YMAX              X
    streq             X

##### struct's

    netinfo           X

       1: /*
       2:  * Copyright (c) 1980 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: #ifndef lint
       8: static char sccsid[] = "@(#)netstat.c	5.2 (Berkeley) 12/11/85";
       9: #endif not lint
      10:
      11: /*
      12:  * netstat
      13:  */
      14: #include "systat.h"
      15:
      16: #include <sys/socket.h>
      17: #include <sys/socketvar.h>
      18: #include <sys/mbuf.h>
      19: #include <sys/protosw.h>
      20:
      21: #include <net/route.h>
      22: #include <netinet/in_systm.h>
      23: #include <netinet/in_pcb.h>
      24: #include <netinet/ip.h>
      25: #include <netinet/ip_icmp.h>
      26: #include <netinet/icmp_var.h>
      27: #include <netinet/ip_var.h>
      28: #include <netinet/tcp.h>
      29: #include <netinet/tcpip.h>
      30: #include <netinet/tcp_seq.h>
      31: #define TCPSTATES
      32: #include <netinet/tcp_fsm.h>
      33: #include <netinet/tcp_timer.h>
      34: #include <netinet/tcp_var.h>
      35: #include <netinet/tcp_debug.h>
      36: #include <netinet/udp.h>
      37: #include <netinet/udp_var.h>
      38:
      39: #define streq(a,b)  (strcmp(a,b)==0)
      40: #define YMAX(w)     ((w)->_maxy-1)
      41:
      42: WINDOW *
      43: opennetstat()
      44: {
      45:
      46:     sethostent(1);
      47:     setnetent(1);
      48:     return (subwin(stdscr, LINES-5-1, 0, 5, 0));
      49: }
      50:
      51: struct netinfo {
      52:     struct  netinfo *ni_forw, *ni_prev;
      53:     short   ni_line;        /* line on screen */
      54:     short   ni_seen;        /* 0 when not present in list */
      55:     short   ni_flags;
      56: #define NIF_LACHG   0x1     /* local address changed */
      57: #define NIF_FACHG   0x2     /* foreign address changed */
      58:     short   ni_state;       /* tcp state */
      59:     char    *ni_proto;      /* protocol */
      60:     struct  in_addr ni_laddr;   /* local address */
      61:     long    ni_lport;       /* local port */
      62:     struct  in_addr ni_faddr;   /* foreign address */
      63:     long    ni_fport;       /* foreign port */
      64:     long    ni_rcvcc;       /* rcv buffer character count */
      65:     long    ni_sndcc;       /* snd buffer character count */
      66: };
      67:
      68: static struct {
      69:     struct  netinfo *ni_forw, *ni_prev;
      70: } netcb;
      71:
      72: static  int aflag = 0;
      73: static  int nflag = 0;
      74: static  int lastrow = 1;
      75: static  char *inetname();
      76:
      77: closenetstat(w)
      78:         WINDOW *w;
      79: {
      80:     register struct netinfo *p;
      81:
      82:     endhostent();
      83:     endnetent();
      84:     p = netcb.ni_forw;
      85:     while (p != (struct netinfo *)&netcb) {
      86:         if (p->ni_line != -1)
      87:             lastrow--;
      88:         p->ni_line = -1;
      89:         p = p->ni_forw;
      90:     }
      91:         if (w != NULL) {
      92:         wclear(w);
      93:         wrefresh(w);
      94:         delwin(w);
      95:     }
      96: }
      97:
      98: static struct nlist nlst[] = {
      99: #define X_TCB   0
     100:     { "_tcb" },
     101: #define X_UDB   1
     102:     { "_udb" },
     103:         { "" },
     104: };
     105:
     106: initnetstat()
     107: {
     108:
     109:     nlist("/vmunix", nlst);
     110:     if (nlst[X_TCB].n_value == 0) {
     111:         error("No symbols in namelist");
     112:         return(0);
     113:     }
     114:     netcb.ni_forw = netcb.ni_prev = (struct netinfo *)&netcb;
     115:     protos = TCP|UDP;
     116:     return(1);
     117: }
     118:
     119: fetchnetstat()
     120: {
     121:     register struct inpcb *prev, *next;
     122:     register struct netinfo *p;
     123:     struct inpcb inpcb;
     124:     struct socket sockb;
     125:     struct tcpcb tcpcb;
     126:     off_t off;
     127:     int istcp;
     128:
     129:     if (nlst[X_TCB].n_value == 0)
     130:         return;
     131:     for (p = netcb.ni_forw; p != (struct netinfo *)&netcb; p = p->ni_forw)
     132:         p->ni_seen = 0;
     133:     if (protos == 0)
     134:         error("No protocols to display");
     135:     if (protos&TCP)
     136:         off = nlst[X_TCB].n_value, istcp = 1;
     137:     else if (protos&UDP)
     138:         off = nlst[X_UDB].n_value, istcp = 0;
     139: again:
     140:     lseek(kmem, off, L_SET);
     141:     read(kmem, &inpcb, sizeof (struct inpcb));
     142:     prev = (struct inpcb *)off;
     143:     for (; inpcb.inp_next != (struct inpcb *)off; prev = next) {
     144:         next = inpcb.inp_next;
     145:         lseek(kmem, (off_t)next, L_SET);
     146:         read(kmem, &inpcb, sizeof (inpcb));
     147:         if (inpcb.inp_prev != prev) {
     148:             p = netcb.ni_forw;
     149:             for (; p != (struct netinfo *)&netcb; p = p->ni_forw)
     150:                 p->ni_seen = 1;
     151:             error("Kernel state in transition");
     152:             return;
     153:         }
     154:         if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
     155:             continue;
     156:         if (nhosts && !checkhost(&inpcb))
     157:             continue;
     158:         if (nports && !checkport(&inpcb))
     159:             continue;
     160:         lseek(kmem, (off_t)inpcb.inp_socket, L_SET);
     161:         read(kmem, &sockb, sizeof (sockb));
     162:         lseek(kmem, (off_t)inpcb.inp_ppcb, L_SET);
     163:         if (istcp) {
     164:             read(kmem, &tcpcb, sizeof (tcpcb));
     165:             enter(&inpcb, &sockb, tcpcb.t_state, "tcp");
     166:         } else
     167:             enter(&inpcb, &sockb, 0, "udp");
     168:     }
     169:     if (istcp && (protos&UDP)) {
     170:         istcp = 0;
     171:         off = nlst[X_UDB].n_value;
     172:         goto again;
     173:     }
     174: }
     175:
     176: static
     177: enter(inp, so, state, proto)
     178:     register struct inpcb *inp;
     179:     register struct socket *so;
     180:     int state;
     181:     char *proto;
     182: {
     183:     register struct netinfo *p;
     184:
     185:     /*
     186: 	 * Only take exact matches, any sockets with
     187: 	 * previously unbound addresses will be deleted
     188: 	 * below in the display routine because they
     189: 	 * will appear as ``not seen'' in the kernel
     190: 	 * data structures.
     191: 	 */
     192:     for (p = netcb.ni_forw; p != (struct netinfo *)&netcb; p = p->ni_forw) {
     193:         if (!streq(proto, p->ni_proto))
     194:             continue;
     195:         if (p->ni_lport != inp->inp_lport ||
     196:             p->ni_laddr.s_addr != inp->inp_laddr.s_addr)
     197:             continue;
     198:         if (p->ni_faddr.s_addr == inp->inp_faddr.s_addr &&
     199:             p->ni_fport == inp->inp_fport)
     200:             break;
     201:     }
     202:     if (p == (struct netinfo *)&netcb) {
     203:         p = (struct netinfo *)malloc(sizeof (*p));
     204:         if (p == 0) {
     205:             error("Out of memory");
     206:             return;
     207:         }
     208:         insque(p, &netcb);
     209:         p->ni_line = -1;
     210:         p->ni_laddr = inp->inp_laddr;
     211:         p->ni_lport = inp->inp_lport;
     212:         p->ni_faddr = inp->inp_faddr;
     213:         p->ni_fport = inp->inp_fport;
     214:         p->ni_proto = proto;
     215:         p->ni_flags = NIF_LACHG|NIF_FACHG;
     216:     }
     217:     p->ni_rcvcc = so->so_rcv.sb_cc;
     218:     p->ni_sndcc = so->so_snd.sb_cc;
     219:     p->ni_state = state;
     220:     p->ni_seen = 1;
     221: }
     222:
     223: /* column locations */
     224: #define LADDR   0
     225: #define FADDR   LADDR+23
     226: #define PROTO   FADDR+23
     227: #define RCVCC   PROTO+6
     228: #define SNDCC   RCVCC+7
     229: #define STATE   SNDCC+7
     230:
     231: labelnetstat()
     232: {
     233:
     234:         if (nlst[X_TCB].n_type == 0)
     235:                 return;
     236:         wmove(wnd, 0, 0); wclrtobot(wnd);
     237:     mvwaddstr(wnd, 0, LADDR, "Local Address");
     238:     mvwaddstr(wnd, 0, FADDR, "Foreign Address");
     239:     mvwaddstr(wnd, 0, PROTO, "Proto");
     240:     mvwaddstr(wnd, 0, RCVCC, "Recv-Q");
     241:     mvwaddstr(wnd, 0, SNDCC, "Send-Q");
     242:     mvwaddstr(wnd, 0, STATE, "(state)");
     243: }
     244:
     245: shownetstat()
     246: {
     247:     register struct netinfo *p, *q;
     248:
     249:     /*
     250: 	 * First, delete any connections that have gone
     251: 	 * away and adjust the position of connections
     252: 	 * below to reflect the deleted line.
     253: 	 */
     254:     p = netcb.ni_forw;
     255:     while (p != (struct netinfo *)&netcb) {
     256:         if (p->ni_line == -1 || p->ni_seen) {
     257:             p = p->ni_forw;
     258:             continue;
     259:         }
     260:         wmove(wnd, p->ni_line, 0); wdeleteln(wnd);
     261:         q = netcb.ni_forw;
     262:         for (; q != (struct netinfo *)&netcb; q = q->ni_forw)
     263:             if (q != p && q->ni_line > p->ni_line) {
     264:                 q->ni_line--;
     265:                 /* this shouldn't be necessary */
     266:                 q->ni_flags |= NIF_LACHG|NIF_FACHG;
     267:             }
     268:         lastrow--;
     269:         q = p->ni_forw;
     270:         remque(p);
     271:         free((char *)p);
     272:         p = q;
     273:     }
     274:     /*
     275: 	 * Update existing connections and add new ones.
     276: 	 */
     277:     for (p = netcb.ni_forw; p != (struct netinfo *)&netcb; p = p->ni_forw) {
     278:         if (p->ni_line == -1) {
     279:             /*
     280: 			 * Add a new entry if possible.
     281: 			 */
     282:             if (lastrow > YMAX(wnd))
     283:                 continue;
     284:             p->ni_line = lastrow++;
     285:             p->ni_flags |= NIF_LACHG|NIF_FACHG;
     286:         }
     287:         if (p->ni_flags & NIF_LACHG) {
     288:             wmove(wnd, p->ni_line, LADDR);
     289:             inetprint(&p->ni_laddr, p->ni_lport, p->ni_proto);
     290:             p->ni_flags &= ~NIF_LACHG;
     291:         }
     292:         if (p->ni_flags & NIF_FACHG) {
     293:             wmove(wnd, p->ni_line, FADDR);
     294:             inetprint(&p->ni_faddr, p->ni_fport, p->ni_proto);
     295:             p->ni_flags &= ~NIF_FACHG;
     296:         }
     297:         mvwaddstr(wnd, p->ni_line, PROTO, p->ni_proto);
     298:         mvwprintw(wnd, p->ni_line, RCVCC, "%6d", p->ni_rcvcc);
     299:         mvwprintw(wnd, p->ni_line, SNDCC, "%6d", p->ni_sndcc);
     300:         if (streq(p->ni_proto, "tcp"))
     301:             if (p->ni_state < 0 || p->ni_state >= TCP_NSTATES)
     302:                 mvwprintw(wnd, p->ni_line, STATE, "%d",
     303:                     p->ni_state);
     304:             else
     305:                 mvwaddstr(wnd, p->ni_line, STATE,
     306:                     tcpstates[p->ni_state]);
     307:         wclrtoeol(wnd);
     308:     }
     309:     if (lastrow < YMAX(wnd)) {
     310:         wmove(wnd, lastrow, 0); wclrtobot(wnd);
     311:         wmove(wnd, YMAX(wnd), 0); wdeleteln(wnd);   /* XXX */
     312:     }
     313: }
     314:
     315: /*
     316:  * Pretty print an Internet address (net address + port).
     317:  * If the nflag was specified, use numbers instead of names.
     318:  */
     319: static
     320: inetprint(in, port, proto)
     321:     register struct in_addr *in;
     322:     int port;
     323:     char *proto;
     324: {
     325:     struct servent *sp = 0;
     326:     char line[80], *cp, *index();
     327:
     328:     sprintf(line, "%.*s.", 16, inetname(*in));
     329:     cp = index(line, '\0');
     330:     if (!nflag && port)
     331:         sp = getservbyport(port, proto);
     332:     if (sp || port == 0)
     333:         sprintf(cp, "%.8s", sp ? sp->s_name : "*");
     334:     else
     335:         sprintf(cp, "%d", ntohs((u_short)port));
     336:     /* pad to full column to clear any garbage */
     337:     cp = index(line, '\0');
     338:     while (cp - line < 22)
     339:         *cp++ = ' ';
     340:     *cp = '\0';
     341:     waddstr(wnd, line);
     342: }
     343:
     344: /*
     345:  * Construct an Internet address representation.
     346:  * If the nflag has been supplied, give
     347:  * numeric value, otherwise try for symbolic name.
     348:  */
     349: static char *
     350: inetname(in)
     351:     struct in_addr in;
     352: {
     353:     char *cp = 0;
     354:     static char line[50];
     355:     struct hostent *hp;
     356:     struct netent *np;
     357:
     358:     if (!nflag && in.s_addr != INADDR_ANY) {
     359:         int net = inet_netof(in);
     360:         int lna = inet_lnaof(in);
     361:
     362:         if (lna == INADDR_ANY) {
     363:             np = getnetbyaddr(net, AF_INET);
     364:             if (np)
     365:                 cp = np->n_name;
     366:         }
     367:         if (cp == 0) {
     368:             hp = gethostbyaddr(&in, sizeof (in), AF_INET);
     369:             if (hp)
     370:                 cp = hp->h_name;
     371:         }
     372:     }
     373:     if (in.s_addr == INADDR_ANY)
     374:         strcpy(line, "*");
     375:     else if (cp)
     376:         strcpy(line, cp);
     377:     else {
     378:         in.s_addr = ntohl(in.s_addr);
     379: #define C(x)    ((x) & 0xff)
     380:         sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
     381:             C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
     382:     }
     383:     return (line);
     384: }
     385:
     386: cmdnetstat(cmd, args)
     387:         char *cmd, *args;
     388: {
     389:     register struct netinfo *p;
     390:
     391:     if (prefix(cmd, "all")) {
     392:         aflag = !aflag;
     393:         goto fixup;
     394:     }
     395:     if  (prefix(cmd, "numbers") || prefix(cmd, "names")) {
     396:         int new;
     397:
     398:         new = prefix(cmd, "numbers");
     399:         if (new == nflag)
     400:             return (1);
     401:         p = netcb.ni_forw;
     402:         for (; p != (struct netinfo *)&netcb; p = p->ni_forw) {
     403:             if (p->ni_line == -1)
     404:                 continue;
     405:             p->ni_flags |= NIF_LACHG|NIF_FACHG;
     406:         }
     407:         nflag = new;
     408:         goto redisplay;
     409:     }
     410:     if (!netcmd(cmd, args))
     411:         return (0);
     412: fixup:
     413:     fetchnetstat();
     414: redisplay:
     415:     shownetstat();
     416:     refresh();
     417:     return (1);
     418: }

#### Defined functions

closenetstat defined in line 77; used 2 times

- in /usr/src/ucb/PORT/systat/cmdtab.c line 29, 49

cmdnetstat defined in line 386; used 2 times

- in /usr/src/ucb/PORT/systat/cmdtab.c line 29, 49

enter defined in line 176; used 2 times

- in line 165-167(2)

fetchnetstat defined in line 119; used 3 times

- in line 413
- in /usr/src/ucb/PORT/systat/cmdtab.c line 28, 48

inetname defined in line 349; used 2 times

- in line 75, 328

inetprint defined in line 319; used 2 times

- in line 289-294(2)

initnetstat defined in line 106; used 2 times

- in /usr/src/ucb/PORT/systat/cmdtab.c line 29, 49

labelnetstat defined in line 231; used 2 times

- in /usr/src/ucb/PORT/systat/cmdtab.c line 28, 48

opennetstat defined in line 42; used 2 times

- in /usr/src/ucb/PORT/systat/cmdtab.c line 30, 49

shownetstat defined in line 245; used 3 times

- in line 415
- in /usr/src/ucb/PORT/systat/cmdtab.c line 28, 48

#### Defined variables

aflag defined in line 72; used 3 times

- in line 154, 392(2)

lastrow defined in line 74; used 6 times

- in line 87, 268, 282-284(2), 309-310(2)

nflag defined in line 73; used 4 times

- in line 330, 358, 399, 407

nlst defined in line 98; used 7 times

- in line 109-110(2), 129, 136-138(2), 171, 234

sccsid defined in line 8; never used

#### Defined struct's

netinfo defined in line 51; used 36 times

- in line 52(2), 69(2), 80-85(4), 114(2), 122(2), 131(2), 149(2), 183(2), 192(2), 202-203(4), 247(2), 255(2), 262(2), 277(2), 389(2), 402(2)

#### Defined macros

C defined in line 379; used 4 times

- in line 380-381(4)

FADDR defined in line 225; used 3 times

- in line 226, 238, 293

LADDR defined in line 224; used 3 times

- in line 225, 237, 288

NIF_FACHG defined in line 57; used 6 times

- in line 215, 266, 285, 292-295(2), 405

NIF_LACHG defined in line 56; used 6 times

- in line 215, 266, 285-290(3), 405

PROTO defined in line 226; used 3 times

- in line 227, 239, 297

RCVCC defined in line 227; used 3 times

- in line 228, 240, 298

SNDCC defined in line 228; used 3 times

- in line 229, 241, 299

STATE defined in line 229; used 3 times

- in line 242, 302-305(2)

TCPSTATES defined in line 31; never used
X_TCB defined in line 99; used 4 times

- in line 110, 129, 136, 234

X_UDB defined in line 101; used 2 times

- in line 138, 171

YMAX defined in line 40; used 3 times

- in line 282, 309-311(2)

streq defined in line 39; used 2 times

- in line 193, 300

Last modified: 1986-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1682 |