[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.6

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