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

1.17    ! chl         1: /*     $OpenBSD: atalk.c,v 1.16 2007/12/19 01:47:00 deraadt 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: #include <sys/param.h>
                     34: #include <sys/queue.h>
                     35: #include <sys/socket.h>
                     36: #include <sys/socketvar.h>
                     37: #include <sys/mbuf.h>
                     38: #include <sys/protosw.h>
1.15      deraadt    39: #include <sys/sysctl.h>
1.1       denny      40: #include <netdb.h>
                     41:
                     42: #include <net/route.h>
                     43: #include <net/if.h>
                     44:
                     45: /* #include <netinet/tcp_fsm.h> */
                     46:
                     47: #include <netatalk/at.h>
                     48: #include <netatalk/ddp_var.h>
                     49:
1.17    ! chl        50: #include <err.h>
1.1       denny      51: #include <errno.h>
                     52: #include <stdio.h>
                     53: #include <string.h>
                     54: #include "netstat.h"
                     55:
                     56: struct ddpcb    ddpcb;
                     57: struct socket   sockb;
                     58:
                     59: static int first = 1;
                     60:
1.7       millert    61: static char *at_pr_net(struct sockaddr_at *, int);
                     62: static char *at_pr_host(struct sockaddr_at *, int);
                     63: static char *at_pr_range(struct sockaddr_at *);
                     64: static char *at_pr_port(struct sockaddr_at *);
1.1       denny      65:
                     66: /*
                     67:  * Print a summary of connections related to a Network Systems
                     68:  * protocol.  For XXX, also give state of connection.
                     69:  * Listening processes (aflag) are suppressed unless the
                     70:  * -a (all) flag is specified.
                     71:  */
                     72:
                     73: static char *
1.10      deraadt    74: at_pr_net(struct sockaddr_at *sat, int numeric)
1.1       denny      75: {
                     76:        static char mybuf[50];
                     77:
                     78:        if (!numeric) {
                     79:                switch (sat->sat_addr.s_net) {
                     80:                case 0xffff:
                     81:                        return "????";
                     82:                case ATADDR_ANYNET:
                     83:                        return ("*");
                     84:                }
                     85:        }
1.6       mickey     86:        (void) snprintf(mybuf, sizeof(mybuf), "%hu",
1.1       denny      87:            ntohs(sat->sat_addr.s_net));
                     88:        return mybuf;
                     89: }
                     90:
                     91: static char *
1.10      deraadt    92: at_pr_host(struct sockaddr_at *sat, int numeric)
1.1       denny      93: {
                     94:        static char mybuf[50];
                     95:
                     96:        if (!numeric) {
                     97:                switch (sat->sat_addr.s_node) {
                     98:                case ATADDR_BCAST:
                     99:                        return "bcast";
                    100:                case ATADDR_ANYNODE:
                    101:                        return ("*");
                    102:                }
                    103:        }
1.6       mickey    104:        (void) snprintf(mybuf, sizeof(mybuf), "%d",
1.1       denny     105:            (unsigned int) sat->sat_addr.s_node);
                    106:        return mybuf;
                    107: }
                    108:
                    109: static char *
1.10      deraadt   110: at_pr_port(struct sockaddr_at *sat)
1.1       denny     111: {
                    112:        static char mybuf[50];
                    113:        struct servent *serv;
                    114:
                    115:        switch (sat->sat_port) {
                    116:        case ATADDR_ANYPORT:
                    117:                return ("*");
                    118:        case 0xff:
                    119:                return "????";
                    120:        default:
                    121:                if (nflag)
                    122:                        (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    123:                            (unsigned int) sat->sat_port);
                    124:                else {
                    125:                        serv = getservbyport(sat->sat_port, "ddp");
                    126:                        if (serv == NULL)
                    127:                                (void) snprintf(mybuf, sizeof(mybuf), "%d",
                    128:                                    (unsigned int) sat->sat_port);
                    129:                        else
                    130:                                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    131:                                    serv->s_name);
                    132:                }
1.6       mickey    133:
1.1       denny     134:                return mybuf;
                    135:        }
                    136: }
                    137:
                    138: static char *
1.10      deraadt   139: at_pr_range(struct sockaddr_at *sat)
1.1       denny     140: {
                    141:        static char mybuf[50];
                    142:
1.10      deraadt   143:        if (sat->sat_range.r_netrange.nr_firstnet !=
                    144:            sat->sat_range.r_netrange.nr_lastnet) {
1.1       denny     145:                (void) snprintf(mybuf, sizeof(mybuf), "%d-%d",
1.8       deraadt   146:                    ntohs(sat->sat_range.r_netrange.nr_firstnet),
                    147:                    ntohs(sat->sat_range.r_netrange.nr_lastnet));
1.1       denny     148:        } else {
                    149:                (void) snprintf(mybuf, sizeof(mybuf), "%d",
1.8       deraadt   150:                    ntohs(sat->sat_range.r_netrange.nr_firstnet));
1.1       denny     151:        }
                    152:        return mybuf;
                    153: }
                    154:
                    155:
                    156: /* what == 0 for addr only == 3
                    157:  *     1 for net
                    158:  *     2 for host
                    159:  *     4 for port
                    160:  *     8 for numeric only
                    161:  */
                    162: char *
1.10      deraadt   163: atalk_print(const struct sockaddr *sa, int what)
1.1       denny     164: {
                    165:        struct sockaddr_at *sat = (struct sockaddr_at *) sa;
                    166:        static char mybuf[50];
                    167:        int numeric = (what & 0x08);
                    168:
                    169:        mybuf[0] = 0;
                    170:        switch (what & 0x13) {
                    171:        case 0:
                    172:                mybuf[0] = 0;
                    173:                break;
                    174:        case 1:
                    175:                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    176:                    at_pr_net(sat, numeric));
                    177:                break;
                    178:        case 2:
                    179:                (void) snprintf(mybuf, sizeof(mybuf), "%s",
                    180:                    at_pr_host(sat, numeric));
                    181:                break;
                    182:        case 3:
                    183:                (void) snprintf(mybuf, sizeof(mybuf), "%s.%s",
1.8       deraadt   184:                    at_pr_net(sat, numeric),
                    185:                    at_pr_host(sat, numeric));
1.1       denny     186:                break;
                    187:        case 0x10:
                    188:                (void) snprintf(mybuf, sizeof(mybuf), "%s", at_pr_range(sat));
                    189:        }
                    190:        if (what & 4) {
                    191:                (void) snprintf(mybuf + strlen(mybuf),
                    192:                    sizeof(mybuf) - strlen(mybuf), ".%s",
                    193:                    at_pr_port(sat));
                    194:        }
                    195:        return mybuf;
                    196: }
                    197:
                    198: char *
1.10      deraadt   199: atalk_print2(const struct sockaddr *sa, const struct sockaddr *mask, int what)
1.1       denny     200: {
1.6       mickey    201:        size_t          n, l;
1.12      deraadt   202:        static char     buf[100];
1.1       denny     203:        struct sockaddr_at *sat1, *sat2;
                    204:        struct sockaddr_at thesockaddr;
                    205:        struct sockaddr *sa2;
                    206:
                    207:        sat1 = (struct sockaddr_at *) sa;
                    208:        sat2 = (struct sockaddr_at *) mask;
                    209:        sa2 = (struct sockaddr *) & thesockaddr;
                    210:
                    211:        thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net &
                    212:            sat2->sat_addr.s_net;
1.9       deraadt   213:        if ((n = snprintf(buf, sizeof(buf), "%s",
                    214:            atalk_print(sa2, 1 | (what & 8)))) >= sizeof(buf))
1.2       millert   215:                n = sizeof(buf) - 1;
1.9       deraadt   216:        else if (n < 0)
1.4       brian     217:                n = 0;  /* What else can be done ? */
1.1       denny     218:        if (sat2->sat_addr.s_net != 0xFFFF) {
                    219:                thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net |
                    220:                    ~sat2->sat_addr.s_net;
1.9       deraadt   221:                if ((l = snprintf(buf + n, sizeof(buf) - n,
                    222:                    "-%s", atalk_print(sa2, 1 | (what & 8)))) >= sizeof(buf) - n)
1.2       millert   223:                        l = sizeof(buf) - n - 1;
1.4       brian     224:                if (l > 0)
                    225:                        n += l;
1.1       denny     226:        }
1.2       millert   227:        if (what & 2) {
                    228:                l = snprintf(buf + n, sizeof(buf) - n, ".%s",
1.1       denny     229:                    atalk_print(sa, what & (~1)));
1.2       millert   230:                if (l >= sizeof(buf) - n)
                    231:                        l = sizeof(buf) - n - 1;
1.4       brian     232:                if (l > 0)
                    233:                        n += l;
1.2       millert   234:        }
1.1       denny     235:        return (buf);
                    236: }
                    237:
                    238: void
1.10      deraadt   239: atalkprotopr(u_long off, char *name)
1.1       denny     240: {
                    241:        struct ddpcb    cb;
1.5       mpech     242:        struct ddpcb *prev, *next;
1.1       denny     243:        struct ddpcb   *initial;
                    244:
                    245:        if (off == 0)
                    246:                return;
1.13      jaredy    247:        if (kread(off, &initial, sizeof(struct ddpcb *)) < 0)
1.1       denny     248:                return;
                    249:        ddpcb = cb;
                    250:        prev = (struct ddpcb *) off;
                    251:        for (next = initial; next != NULL; prev = next) {
1.6       mickey    252:                u_long  ppcb = (u_long) next;
1.1       denny     253:
1.13      jaredy    254:                if (kread((u_long) next, &ddpcb, sizeof(ddpcb)) < 0)
1.1       denny     255:                        return;
                    256:                next = ddpcb.ddp_next;
                    257: #if 0
                    258:                if (!aflag && atalk_nullhost(ddpcb.ddp_lsat)) {
                    259:                        continue;
                    260:                }
                    261: #endif
1.13      jaredy    262:                if (kread((u_long) ddpcb.ddp_socket, &sockb,
                    263:                    sizeof(sockb)) < 0)
1.1       denny     264:                        return;
                    265:                if (first) {
                    266:                        printf("Active ATALK connections");
                    267:                        if (aflag)
                    268:                                printf(" (including servers)");
                    269:                        putchar('\n');
                    270:                        if (Aflag)
                    271:                                printf("%-8.8s ", "PCB");
                    272:                        printf(Aflag ?
                    273:                            "%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
1.8       deraadt   274:                            "%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
                    275:                            "Proto", "Recv-Q", "Send-Q",
                    276:                            "Local Address", "Foreign Address", "(state)");
1.1       denny     277:                        first = 0;
                    278:                }
                    279:                if (Aflag)
                    280:                        printf("%8lx ", ppcb);
                    281:                printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
1.6       mickey    282:                    sockb.so_snd.sb_cc);
1.1       denny     283:                printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
1.8       deraadt   284:                    (struct sockaddr *) & ddpcb.ddp_lsat, 7));
1.1       denny     285:                printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
1.8       deraadt   286:                    (struct sockaddr *) & ddpcb.ddp_fsat, 7));
1.1       denny     287:                putchar('\n');
                    288:        }
                    289: }
                    290:
                    291: #define p(f, m) if (ddpstat.f || sflag <= 1) \
1.8       deraadt   292:        printf(m, ddpstat.f, plural(ddpstat.f))
1.1       denny     293: #define p2(f1, f2, m) if (ddpstat.f1 || ddpstat.f2 || sflag <= 1) \
1.8       deraadt   294:        printf(m, ddpstat.f1, plural(ddpstat.f1), ddpstat.f2, plural(ddpstat.f2))
1.1       denny     295: #define p3(f, m) if (ddpstat.f || sflag <= 1) \
1.8       deraadt   296:        printf(m, ddpstat.f, plurales(ddpstat.f))
1.1       denny     297:
                    298: /*
                    299:  * Dump DDP statistics structure.
                    300:  */
                    301: void
1.15      deraadt   302: ddp_stats(char *name)
1.1       denny     303: {
                    304:        struct ddpstat  ddpstat;
1.15      deraadt   305:        int mib[] = { CTL_NET, AF_APPLETALK, ATPROTO_DDP, DDPCTL_STATS };
                    306:        size_t len = sizeof(ddpstat);
1.1       denny     307:
1.15      deraadt   308:        if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
                    309:            &ddpstat, &len, NULL, 0) == -1) {
                    310:                if (errno != ENOPROTOOPT)
                    311:                        warn(name);
1.1       denny     312:                return;
1.15      deraadt   313:        }
                    314:
1.1       denny     315:        printf("%s:\n", name);
                    316:        p(ddps_short, "\t%ld packet%s with short headers\n");
                    317:        p(ddps_long, "\t%ld packet%s with long headers\n");
                    318:        p(ddps_nosum, "\t%ld packet%s with no checksum\n");
                    319:        p(ddps_tooshort, "\t%ld packet%s were too short\n");
                    320:        p(ddps_badsum, "\t%ld packet%s with bad checksum\n");
                    321:        p(ddps_toosmall, "\t%ld packet%s with not enough data\n");
                    322:        p(ddps_forward, "\t%ld packet%s forwarded\n");
                    323:        p(ddps_cantforward, "\t%ld packet%s rcvd for unreachable dest\n");
                    324:        p(ddps_nosockspace, "\t%ld packet%s dropped due to no socket space\n");
                    325: }