Annotation of src/usr.bin/netstat/atalk.c, Revision 1.20
1.20 ! bluhm 1: /* $OpenBSD: atalk.c,v 1.19 2010/06/29 03:09:29 blambert 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: void
1.20 ! bluhm 199: atalkprotopr(u_long off, char *name, int af, u_long pcbaddr)
1.1 denny 200: {
201: struct ddpcb cb;
1.5 mpech 202: struct ddpcb *prev, *next;
1.1 denny 203: struct ddpcb *initial;
204:
205: if (off == 0)
206: return;
1.13 jaredy 207: if (kread(off, &initial, sizeof(struct ddpcb *)) < 0)
1.1 denny 208: return;
209: ddpcb = cb;
210: prev = (struct ddpcb *) off;
211: for (next = initial; next != NULL; prev = next) {
1.6 mickey 212: u_long ppcb = (u_long) next;
1.1 denny 213:
1.13 jaredy 214: if (kread((u_long) next, &ddpcb, sizeof(ddpcb)) < 0)
1.1 denny 215: return;
216: next = ddpcb.ddp_next;
1.20 ! bluhm 217: if (Pflag) {
! 218: if (pcbaddr == ppcb)
! 219: socket_dump((u_long)ddpcb.ddp_socket);
! 220: continue;
! 221: }
1.1 denny 222: #if 0
223: if (!aflag && atalk_nullhost(ddpcb.ddp_lsat)) {
224: continue;
225: }
226: #endif
1.13 jaredy 227: if (kread((u_long) ddpcb.ddp_socket, &sockb,
228: sizeof(sockb)) < 0)
1.1 denny 229: return;
230: if (first) {
231: printf("Active ATALK connections");
232: if (aflag)
233: printf(" (including servers)");
234: putchar('\n');
235: if (Aflag)
236: printf("%-8.8s ", "PCB");
237: printf(Aflag ?
238: "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
1.8 deraadt 239: "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
240: "Proto", "Recv-Q", "Send-Q",
241: "Local Address", "Foreign Address", "(state)");
1.1 denny 242: first = 0;
243: }
244: if (Aflag)
245: printf("%8lx ", ppcb);
246: printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
1.6 mickey 247: sockb.so_snd.sb_cc);
1.1 denny 248: printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
1.8 deraadt 249: (struct sockaddr *) & ddpcb.ddp_lsat, 7));
1.1 denny 250: printf(Aflag ? " %-18.18s" : " %-22.22s", atalk_print(
1.8 deraadt 251: (struct sockaddr *) & ddpcb.ddp_fsat, 7));
1.1 denny 252: putchar('\n');
253: }
254: }
255:
256: #define p(f, m) if (ddpstat.f || sflag <= 1) \
1.8 deraadt 257: printf(m, ddpstat.f, plural(ddpstat.f))
1.1 denny 258: #define p2(f1, f2, m) if (ddpstat.f1 || ddpstat.f2 || sflag <= 1) \
1.8 deraadt 259: printf(m, ddpstat.f1, plural(ddpstat.f1), ddpstat.f2, plural(ddpstat.f2))
1.1 denny 260: #define p3(f, m) if (ddpstat.f || sflag <= 1) \
1.8 deraadt 261: printf(m, ddpstat.f, plurales(ddpstat.f))
1.1 denny 262:
263: /*
264: * Dump DDP statistics structure.
265: */
266: void
1.15 deraadt 267: ddp_stats(char *name)
1.1 denny 268: {
269: struct ddpstat ddpstat;
1.15 deraadt 270: int mib[] = { CTL_NET, AF_APPLETALK, ATPROTO_DDP, DDPCTL_STATS };
271: size_t len = sizeof(ddpstat);
1.1 denny 272:
1.15 deraadt 273: if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
274: &ddpstat, &len, NULL, 0) == -1) {
275: if (errno != ENOPROTOOPT)
276: warn(name);
1.1 denny 277: return;
1.15 deraadt 278: }
279:
1.1 denny 280: printf("%s:\n", name);
281: p(ddps_short, "\t%ld packet%s with short headers\n");
282: p(ddps_long, "\t%ld packet%s with long headers\n");
283: p(ddps_nosum, "\t%ld packet%s with no checksum\n");
284: p(ddps_tooshort, "\t%ld packet%s were too short\n");
285: p(ddps_badsum, "\t%ld packet%s with bad checksum\n");
286: p(ddps_toosmall, "\t%ld packet%s with not enough data\n");
287: p(ddps_forward, "\t%ld packet%s forwarded\n");
288: p(ddps_cantforward, "\t%ld packet%s rcvd for unreachable dest\n");
289: p(ddps_nosockspace, "\t%ld packet%s dropped due to no socket space\n");
290: }