[BACK]Return to atalk.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / netstat

Annotation of src/usr.bin/netstat/atalk.c, Revision 1.2

1.1       denny       1: /*     $NetBSD: atalk.c,v 1.2 1997/05/22 17:21:26 christos Exp $       */
                      2:
                      3: /*
                      4:  * Copyright (c) 1983, 1988, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Berkeley and its contributors.
                     19:  * 4. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
                     35:
                     36: #ifndef lint
                     37: #if 0
                     38: static char sccsid[] = "from @(#)atalk.c       1.1 (Whistle) 6/6/96";
                     39: #else
                     40: static char rcsid[] = "$NetBSD: atalk.c,v 1.2 1997/05/22 17:21:26 christos Exp $";
                     41: #endif
                     42: #endif /* not lint */
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/queue.h>
                     46: #include <sys/socket.h>
                     47: #include <sys/socketvar.h>
                     48: #include <sys/mbuf.h>
                     49: #include <sys/protosw.h>
                     50: #include <netdb.h>
                     51:
                     52: #include <net/route.h>
                     53: #include <net/if.h>
                     54:
                     55: /* #include <netinet/tcp_fsm.h> */
                     56:
                     57: #include <netatalk/at.h>
                     58: #include <netatalk/ddp_var.h>
                     59:
                     60: #include <nlist.h>
                     61: #include <errno.h>
                     62: #include <stdio.h>
                     63: #include <string.h>
                     64: #include "netstat.h"
                     65:
                     66: struct ddpcb    ddpcb;
                     67: struct socket   sockb;
                     68:
                     69: static int first = 1;
                     70:
                     71: static char *at_pr_net __P((struct sockaddr_at *, int));
                     72: static char *at_pr_host __P((struct sockaddr_at *, int));
                     73: static char *at_pr_range __P((struct sockaddr_at *));
                     74: static char *at_pr_port __P((struct sockaddr_at *));
                     75:
                     76: /*
                     77:  * Print a summary of connections related to a Network Systems
                     78:  * protocol.  For XXX, also give state of connection.
                     79:  * Listening processes (aflag) are suppressed unless the
                     80:  * -a (all) flag is specified.
                     81:  */
                     82:
                     83: static char *
                     84: at_pr_net(sat, numeric)
                     85:        struct sockaddr_at *sat;
                     86:        int numeric;
                     87: {
                     88:        static char mybuf[50];
                     89:
                     90:        if (!numeric) {
                     91:                switch (sat->sat_addr.s_net) {
                     92:                case 0xffff:
                     93:                        return "????";
                     94:                case ATADDR_ANYNET:
                     95:                        return ("*");
                     96:                }
                     97:        }
                     98:        (void) snprintf(mybuf, sizeof(mybuf), "%hu",
                     99:            ntohs(sat->sat_addr.s_net));
                    100:        return mybuf;
                    101: }
                    102:
                    103: static char *
                    104: at_pr_host(sat, numeric)
                    105:        struct sockaddr_at *sat;
                    106:        int numeric;
                    107: {
                    108:        static char mybuf[50];
                    109:
                    110:        if (!numeric) {
                    111:                switch (sat->sat_addr.s_node) {
                    112:                case ATADDR_BCAST:
                    113:                        return "bcast";
                    114:                case ATADDR_ANYNODE:
                    115:                        return ("*");
                    116:                }
                    117:        }
                    118:        (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    119:            (unsigned int) sat->sat_addr.s_node);
                    120:        return mybuf;
                    121: }
                    122:
                    123: static char *
                    124: at_pr_port(sat)
                    125:        struct sockaddr_at *sat;
                    126: {
                    127:        static char mybuf[50];
                    128:        struct servent *serv;
                    129:
                    130:        switch (sat->sat_port) {
                    131:        case ATADDR_ANYPORT:
                    132:                return ("*");
                    133:        case 0xff:
                    134:                return "????";
                    135:        default:
                    136:                if (nflag)
                    137:                        (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    138:                            (unsigned int) sat->sat_port);
                    139:                else {
                    140:                        serv = getservbyport(sat->sat_port, "ddp");
                    141:                        if (serv == NULL)
                    142:                                (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    143:                                    (unsigned int) sat->sat_port);
                    144:                        else
                    145:                                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    146:                                    serv->s_name);
                    147:                }
                    148:
                    149:                return mybuf;
                    150:        }
                    151: }
                    152:
                    153: static char *
                    154: at_pr_range(sat)
                    155:        struct sockaddr_at *sat;
                    156: {
                    157:        static char mybuf[50];
                    158:
                    159:        if (sat->sat_range.r_netrange.nr_firstnet
                    160:            != sat->sat_range.r_netrange.nr_lastnet) {
                    161:                (void) snprintf(mybuf, sizeof(mybuf), "%d-%d",
                    162:                        ntohs(sat->sat_range.r_netrange.nr_firstnet),
                    163:                        ntohs(sat->sat_range.r_netrange.nr_lastnet));
                    164:        } else {
                    165:                (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    166:                        ntohs(sat->sat_range.r_netrange.nr_firstnet));
                    167:        }
                    168:        return mybuf;
                    169: }
                    170:
                    171:
                    172: /* what == 0 for addr only == 3
                    173:  *     1 for net
                    174:  *     2 for host
                    175:  *     4 for port
                    176:  *     8 for numeric only
                    177:  */
                    178: char *
                    179: atalk_print(sa, what)
                    180:        const struct sockaddr *sa;
                    181:        int what;
                    182: {
                    183:        struct sockaddr_at *sat = (struct sockaddr_at *) sa;
                    184:        static char mybuf[50];
                    185:        int numeric = (what & 0x08);
                    186:
                    187:        mybuf[0] = 0;
                    188:        switch (what & 0x13) {
                    189:        case 0:
                    190:                mybuf[0] = 0;
                    191:                break;
                    192:        case 1:
                    193:                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    194:                    at_pr_net(sat, numeric));
                    195:                break;
                    196:        case 2:
                    197:                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    198:                    at_pr_host(sat, numeric));
                    199:                break;
                    200:        case 3:
                    201:                (void) snprintf(mybuf, sizeof(mybuf), "%s.%s",
                    202:                        at_pr_net(sat, numeric),
                    203:                        at_pr_host(sat, numeric));
                    204:                break;
                    205:        case 0x10:
                    206:                (void) snprintf(mybuf, sizeof(mybuf), "%s", at_pr_range(sat));
                    207:        }
                    208:        if (what & 4) {
                    209:                (void) snprintf(mybuf + strlen(mybuf),
                    210:                    sizeof(mybuf) - strlen(mybuf), ".%s",
                    211:                    at_pr_port(sat));
                    212:        }
                    213:        return mybuf;
                    214: }
                    215:
                    216: char *
                    217: atalk_print2(sa, mask, what)
                    218:        const struct sockaddr *sa;
                    219:        const struct sockaddr *mask;
                    220:        int what;
                    221: {
1.2     ! millert   222:        size_t          n, l;
1.1       denny     223:        static char     buf[100];
                    224:        struct sockaddr_at *sat1, *sat2;
                    225:        struct sockaddr_at thesockaddr;
                    226:        struct sockaddr *sa2;
                    227:
                    228:        sat1 = (struct sockaddr_at *) sa;
                    229:        sat2 = (struct sockaddr_at *) mask;
                    230:        sa2 = (struct sockaddr *) & thesockaddr;
                    231:
                    232:        thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net &
                    233:            sat2->sat_addr.s_net;
                    234:        n = snprintf(buf, sizeof(buf), "%s", atalk_print(sa2, 1 | (what & 8)));
1.2     ! millert   235:        if (n >= sizeof(buf))
        !           236:                n = sizeof(buf) - 1;
1.1       denny     237:        if (sat2->sat_addr.s_net != 0xFFFF) {
                    238:                thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net |
                    239:                    ~sat2->sat_addr.s_net;
1.2     ! millert   240:                l = snprintf(buf + n, sizeof(buf) - n,
1.1       denny     241:                    "-%s", atalk_print(sa2, 1 | (what & 8)));
1.2     ! millert   242:                if (l >= sizeof(buf) - n)
        !           243:                        l = sizeof(buf) - n - 1;
        !           244:                n += l;
1.1       denny     245:        }
1.2     ! millert   246:        if (what & 2) {
        !           247:                l = snprintf(buf + n, sizeof(buf) - n, ".%s",
1.1       denny     248:                    atalk_print(sa, what & (~1)));
1.2     ! millert   249:                if (l >= sizeof(buf) - n)
        !           250:                        l = sizeof(buf) - n - 1;
        !           251:                n += l;
        !           252:        }
1.1       denny     253:        return (buf);
                    254: }
                    255:
                    256: void
                    257: atalkprotopr(off, name)
                    258:        u_long off;
                    259:        char  *name;
                    260: {
                    261:        struct ddpcb    cb;
                    262:        register struct ddpcb *prev, *next;
                    263:        struct ddpcb   *initial;
                    264:
                    265:        if (off == 0)
                    266:                return;
                    267:        if (kread(off, (char *) &initial, sizeof(struct ddpcb *)) < 0)
                    268:                return;
                    269:        ddpcb = cb;
                    270:        prev = (struct ddpcb *) off;
                    271:        for (next = initial; next != NULL; prev = next) {
                    272:                u_long          ppcb = (u_long) next;
                    273:
                    274:                if (kread((u_long) next, (char *) &ddpcb, sizeof(ddpcb)) < 0)
                    275:                        return;
                    276:                next = ddpcb.ddp_next;
                    277: #if 0
                    278:                if (!aflag && atalk_nullhost(ddpcb.ddp_lsat)) {
                    279:                        continue;
                    280:                }
                    281: #endif
                    282:                if (kread((u_long) ddpcb.ddp_socket,
                    283:                          (char *) &sockb, sizeof(sockb)) < 0)
                    284:                        return;
                    285:                if (first) {
                    286:                        printf("Active ATALK connections");
                    287:                        if (aflag)
                    288:                                printf(" (including servers)");
                    289:                        putchar('\n');
                    290:                        if (Aflag)
                    291:                                printf("%-8.8s ", "PCB");
                    292:                        printf(Aflag ?
                    293:                            "%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
                    294:                             "%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
                    295:                               "Proto", "Recv-Q", "Send-Q",
                    296:                             "Local Address", "Foreign Address", "(state)");
                    297:                        first = 0;
                    298:                }
                    299:                if (Aflag)
                    300:                        printf("%8lx ", ppcb);
                    301:                printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
                    302:                       sockb.so_snd.sb_cc);
                    303:                printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
                    304:                          (struct sockaddr *) & ddpcb.ddp_lsat, 7));
                    305:                printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
                    306:                          (struct sockaddr *) & ddpcb.ddp_fsat, 7));
                    307:                putchar('\n');
                    308:        }
                    309: }
                    310:
                    311: #define p(f, m) if (ddpstat.f || sflag <= 1) \
                    312:     printf(m, ddpstat.f, plural(ddpstat.f))
                    313: #define p2(f1, f2, m) if (ddpstat.f1 || ddpstat.f2 || sflag <= 1) \
                    314:     printf(m, ddpstat.f1, plural(ddpstat.f1), ddpstat.f2, plural(ddpstat.f2))
                    315: #define p3(f, m) if (ddpstat.f || sflag <= 1) \
                    316:     printf(m, ddpstat.f, plurales(ddpstat.f))
                    317:
                    318: /*
                    319:  * Dump DDP statistics structure.
                    320:  */
                    321: void
                    322: ddp_stats(off, name)
                    323:        u_long off;
                    324:        char *name;
                    325: {
                    326:        struct ddpstat  ddpstat;
                    327:
                    328:        if (off == 0)
                    329:                return;
                    330:        if (kread(off, (char *) &ddpstat, sizeof(ddpstat)) < 0)
                    331:                return;
                    332:        printf("%s:\n", name);
                    333:        p(ddps_short, "\t%ld packet%s with short headers\n");
                    334:        p(ddps_long, "\t%ld packet%s with long headers\n");
                    335:        p(ddps_nosum, "\t%ld packet%s with no checksum\n");
                    336:        p(ddps_tooshort, "\t%ld packet%s were too short\n");
                    337:        p(ddps_badsum, "\t%ld packet%s with bad checksum\n");
                    338:        p(ddps_toosmall, "\t%ld packet%s with not enough data\n");
                    339:        p(ddps_forward, "\t%ld packet%s forwarded\n");
                    340:        p(ddps_cantforward, "\t%ld packet%s rcvd for unreachable dest\n");
                    341:        p(ddps_nosockspace, "\t%ld packet%s dropped due to no socket space\n");
                    342: }