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

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