Annotation of src/usr.bin/netstat/atalk.c, Revision 1.1
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: {
! 222: int n;
! 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)));
! 235: if (sat2->sat_addr.s_net != 0xFFFF) {
! 236: thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net |
! 237: ~sat2->sat_addr.s_net;
! 238: n += snprintf(buf + n, sizeof(buf) - n,
! 239: "-%s", atalk_print(sa2, 1 | (what & 8)));
! 240: }
! 241: if (what & 2)
! 242: n += snprintf(buf + n, sizeof(buf) - n, ".%s",
! 243: atalk_print(sa, what & (~1)));
! 244: return (buf);
! 245: }
! 246:
! 247: void
! 248: atalkprotopr(off, name)
! 249: u_long off;
! 250: char *name;
! 251: {
! 252: struct ddpcb cb;
! 253: register struct ddpcb *prev, *next;
! 254: struct ddpcb *initial;
! 255:
! 256: if (off == 0)
! 257: return;
! 258: if (kread(off, (char *) &initial, sizeof(struct ddpcb *)) < 0)
! 259: return;
! 260: ddpcb = cb;
! 261: prev = (struct ddpcb *) off;
! 262: for (next = initial; next != NULL; prev = next) {
! 263: u_long ppcb = (u_long) next;
! 264:
! 265: if (kread((u_long) next, (char *) &ddpcb, sizeof(ddpcb)) < 0)
! 266: return;
! 267: next = ddpcb.ddp_next;
! 268: #if 0
! 269: if (!aflag && atalk_nullhost(ddpcb.ddp_lsat)) {
! 270: continue;
! 271: }
! 272: #endif
! 273: if (kread((u_long) ddpcb.ddp_socket,
! 274: (char *) &sockb, sizeof(sockb)) < 0)
! 275: return;
! 276: if (first) {
! 277: printf("Active ATALK connections");
! 278: if (aflag)
! 279: printf(" (including servers)");
! 280: putchar('\n');
! 281: if (Aflag)
! 282: printf("%-8.8s ", "PCB");
! 283: printf(Aflag ?
! 284: "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
! 285: "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
! 286: "Proto", "Recv-Q", "Send-Q",
! 287: "Local Address", "Foreign Address", "(state)");
! 288: first = 0;
! 289: }
! 290: if (Aflag)
! 291: printf("%8lx ", ppcb);
! 292: printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
! 293: sockb.so_snd.sb_cc);
! 294: printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
! 295: (struct sockaddr *) & ddpcb.ddp_lsat, 7));
! 296: printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
! 297: (struct sockaddr *) & ddpcb.ddp_fsat, 7));
! 298: putchar('\n');
! 299: }
! 300: }
! 301:
! 302: #define p(f, m) if (ddpstat.f || sflag <= 1) \
! 303: printf(m, ddpstat.f, plural(ddpstat.f))
! 304: #define p2(f1, f2, m) if (ddpstat.f1 || ddpstat.f2 || sflag <= 1) \
! 305: printf(m, ddpstat.f1, plural(ddpstat.f1), ddpstat.f2, plural(ddpstat.f2))
! 306: #define p3(f, m) if (ddpstat.f || sflag <= 1) \
! 307: printf(m, ddpstat.f, plurales(ddpstat.f))
! 308:
! 309: /*
! 310: * Dump DDP statistics structure.
! 311: */
! 312: void
! 313: ddp_stats(off, name)
! 314: u_long off;
! 315: char *name;
! 316: {
! 317: struct ddpstat ddpstat;
! 318:
! 319: if (off == 0)
! 320: return;
! 321: if (kread(off, (char *) &ddpstat, sizeof(ddpstat)) < 0)
! 322: return;
! 323: printf("%s:\n", name);
! 324: p(ddps_short, "\t%ld packet%s with short headers\n");
! 325: p(ddps_long, "\t%ld packet%s with long headers\n");
! 326: p(ddps_nosum, "\t%ld packet%s with no checksum\n");
! 327: p(ddps_tooshort, "\t%ld packet%s were too short\n");
! 328: p(ddps_badsum, "\t%ld packet%s with bad checksum\n");
! 329: p(ddps_toosmall, "\t%ld packet%s with not enough data\n");
! 330: p(ddps_forward, "\t%ld packet%s forwarded\n");
! 331: p(ddps_cantforward, "\t%ld packet%s rcvd for unreachable dest\n");
! 332: p(ddps_nosockspace, "\t%ld packet%s dropped due to no socket space\n");
! 333: }