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