xref: /minix3/minix/usr.bin/trace/ioctl/net.c (revision 03ac74ede908465cc64c671bbd209e761dc765dc)
1 
2 #include "inc.h"
3 
4 #include <sys/ioctl.h>
5 #include <sys/ucred.h>
6 #include <net/gen/in.h>
7 #include <net/gen/ether.h>
8 #include <net/gen/eth_io.h>
9 #include <net/gen/arp_io.h>
10 #include <net/gen/ip_io.h>
11 #include <net/gen/route.h>
12 #include <net/gen/tcp.h>
13 #include <net/gen/tcp_io.h>
14 #include <net/gen/udp.h>
15 #include <net/gen/udp_io.h>
16 #include <net/gen/udp_io_hdr.h>
17 #include <net/gen/psip_io.h>
18 #include <arpa/inet.h>
19 
20 #include <net/route.h>
21 #include <netinet6/in6_var.h>
22 #include <netinet6/nd6.h>
23 #include <net80211/ieee80211_ioctl.h>
24 
25 const char *
26 net_ioctl_name(unsigned long req)
27 {
28 
29 	switch (req) {
30 	NAME(FIONREAD);
31 	/* sys/sockio.h */
32 	NAME(SIOCSHIWAT);		/* TODO: print argument */
33 	NAME(SIOCGHIWAT);		/* TODO: print argument */
34 	NAME(SIOCSLOWAT);		/* TODO: print argument */
35 	NAME(SIOCGLOWAT);		/* TODO: print argument */
36 	NAME(SIOCSPGRP);		/* TODO: print argument */
37 	NAME(SIOCGPGRP);		/* TODO: print argument */
38 	NAME(SIOCADDRT);		/* TODO: print argument */
39 	NAME(SIOCDELRT);		/* TODO: print argument */
40 	NAME(SIOCSIFADDR);		/* TODO: print argument */
41 	NAME(SIOCGIFADDR);		/* TODO: print argument */
42 	NAME(SIOCSIFDSTADDR);		/* TODO: print argument */
43 	NAME(SIOCGIFDSTADDR);		/* TODO: print argument */
44 	NAME(SIOCSIFFLAGS);		/* TODO: print argument */
45 	NAME(SIOCGIFFLAGS);		/* TODO: print argument */
46 	NAME(SIOCGIFBRDADDR);		/* TODO: print argument */
47 	NAME(SIOCSIFBRDADDR);		/* TODO: print argument */
48 	NAME(SIOCGIFCONF);		/* TODO: print argument */
49 	NAME(SIOCGIFNETMASK);		/* TODO: print argument */
50 	NAME(SIOCSIFNETMASK);		/* TODO: print argument */
51 	NAME(SIOCGIFMETRIC);		/* TODO: print argument */
52 	NAME(SIOCSIFMETRIC);		/* TODO: print argument */
53 	NAME(SIOCDIFADDR);		/* TODO: print argument */
54 	NAME(SIOCAIFADDR);		/* TODO: print argument */
55 	NAME(SIOCGIFALIAS);		/* TODO: print argument */
56 	NAME(SIOCGIFAFLAG_IN);		/* TODO: print argument */
57 	NAME(SIOCALIFADDR);		/* TODO: print argument */
58 	NAME(SIOCGLIFADDR);		/* TODO: print argument */
59 	NAME(SIOCDLIFADDR);		/* TODO: print argument */
60 	NAME(SIOCSIFADDRPREF);		/* TODO: print argument */
61 	NAME(SIOCGIFADDRPREF);		/* TODO: print argument */
62 	NAME(SIOCADDMULTI);		/* TODO: print argument */
63 	NAME(SIOCDELMULTI);		/* TODO: print argument */
64 	NAME(SIOCSIFMEDIA);		/* TODO: print argument */
65 	NAME(SIOCGIFMEDIA);		/* TODO: print argument */
66 	NAME(SIOCSIFGENERIC);		/* TODO: print argument */
67 	NAME(SIOCGIFGENERIC);		/* TODO: print argument */
68 	NAME(SIOCSIFPHYADDR);		/* TODO: print argument */
69 	NAME(SIOCGIFPSRCADDR);		/* TODO: print argument */
70 	NAME(SIOCGIFPDSTADDR);		/* TODO: print argument */
71 	NAME(SIOCDIFPHYADDR);		/* TODO: print argument */
72 	NAME(SIOCSLIFPHYADDR);		/* TODO: print argument */
73 	NAME(SIOCGLIFPHYADDR);		/* TODO: print argument */
74 	NAME(SIOCSIFMTU);		/* TODO: print argument */
75 	NAME(SIOCGIFMTU);		/* TODO: print argument */
76 	NAME(SIOCSDRVSPEC);		/* TODO: print argument */
77 	NAME(SIOCGDRVSPEC);		/* TODO: print argument */
78 	NAME(SIOCIFCREATE);		/* TODO: print argument */
79 	NAME(SIOCIFDESTROY);		/* TODO: print argument */
80 	NAME(SIOCIFGCLONERS);		/* TODO: print argument */
81 	NAME(SIOCGIFDLT);		/* TODO: print argument */
82 	NAME(SIOCGIFCAP);		/* TODO: print argument */
83 	NAME(SIOCSIFCAP);		/* TODO: print argument */
84 	NAME(SIOCSVH);			/* TODO: print argument */
85 	NAME(SIOCGVH);			/* TODO: print argument */
86 	NAME(SIOCINITIFADDR);		/* TODO: print argument */
87 	NAME(SIOCGIFDATA);		/* TODO: print argument */
88 	NAME(SIOCZIFDATA);		/* TODO: print argument */
89 	NAME(SIOCGLINKSTR);		/* TODO: print argument */
90 	NAME(SIOCSLINKSTR);		/* TODO: print argument */
91 	NAME(SIOCGETHERCAP);		/* TODO: print argument */
92 	NAME(SIOCGIFINDEX);		/* TODO: print argument */
93 	NAME(SIOCSETPFSYNC);		/* TODO: print argument */
94 	NAME(SIOCGETPFSYNC);		/* TODO: print argument */
95 	/* netinet6/in6_var.h */
96 	NAME(SIOCSIFADDR_IN6);		/* TODO: print argument */
97 	NAME(SIOCGIFADDR_IN6);		/* TODO: print argument */
98 	NAME(SIOCGIFDSTADDR_IN6);	/* TODO: print argument */
99 	NAME(SIOCGIFNETMASK_IN6);	/* TODO: print argument */
100 	NAME(SIOCDIFADDR_IN6);		/* TODO: print argument */
101 	NAME(SIOCGIFPSRCADDR_IN6);	/* TODO: print argument */
102 	NAME(SIOCGIFPDSTADDR_IN6);	/* TODO: print argument */
103 	NAME(SIOCGIFAFLAG_IN6);		/* TODO: print argument */
104 	NAME(SIOCGDRLST_IN6);		/* TODO: print argument */
105 	NAME(SIOCSNDFLUSH_IN6);		/* TODO: print argument */
106 	NAME(SIOCGNBRINFO_IN6);		/* TODO: print argument */
107 	NAME(SIOCSRTRFLUSH_IN6);	/* TODO: print argument */
108 	NAME(SIOCGIFSTAT_IN6);		/* TODO: print argument */
109 	NAME(SIOCGIFSTAT_ICMP6);	/* TODO: print argument */
110 	NAME(SIOCSDEFIFACE_IN6);	/* TODO: print argument */
111 	NAME(SIOCGDEFIFACE_IN6);	/* TODO: print argument */
112 	NAME(SIOCSIFINFO_FLAGS);	/* TODO: print argument */
113 	NAME(SIOCSIFPREFIX_IN6);	/* TODO: print argument */
114 	NAME(SIOCGIFPREFIX_IN6);	/* TODO: print argument */
115 	NAME(SIOCDIFPREFIX_IN6);	/* TODO: print argument */
116 	NAME(SIOCAIFPREFIX_IN6);	/* TODO: print argument */
117 	NAME(SIOCCIFPREFIX_IN6);	/* TODO: print argument */
118 	NAME(SIOCGIFALIFETIME_IN6);	/* TODO: print argument */
119 	NAME(SIOCAIFADDR_IN6);		/* TODO: print argument */
120 	NAME(SIOCGIFINFO_IN6);		/* TODO: print argument */
121 	NAME(SIOCSIFINFO_IN6);		/* TODO: print argument */
122 	NAME(SIOCSIFPHYADDR_IN6);	/* TODO: print argument */
123 	NAME(SIOCAADDRCTL_POLICY);	/* TODO: print argument */
124 	NAME(SIOCDADDRCTL_POLICY);	/* TODO: print argument */
125 	/* net80211/ieee80211_ioctl.h */
126 	NAME(SIOCS80211NWID);		/* TODO: print argument */
127 	NAME(SIOCG80211NWID);		/* TODO: print argument */
128 	/* old MINIX inet ioctls */
129 	NAME(NWIOSETHOPT);	/* TODO: print argument */
130 	NAME(NWIOGETHOPT);	/* TODO: print argument */
131 	NAME(NWIOGETHSTAT);	/* TODO: print argument */
132 	NAME(NWIOARPGIP);	/* TODO: print argument */
133 	NAME(NWIOARPGNEXT);	/* TODO: print argument */
134 	NAME(NWIOARPSIP);	/* TODO: print argument */
135 	NAME(NWIOARPDIP);	/* TODO: print argument */
136 	NAME(NWIOSIPCONF2);	/* TODO: print argument */
137 	NAME(NWIOSIPCONF);	/* TODO: print argument */
138 	NAME(NWIOGIPCONF2);	/* TODO: print argument */
139 	NAME(NWIOGIPCONF);	/* TODO: print argument */
140 	NAME(NWIOSIPOPT);
141 	NAME(NWIOGIPOPT);
142 	NAME(NWIOGIPOROUTE);	/* TODO: print argument */
143 	NAME(NWIOSIPOROUTE);	/* TODO: print argument */
144 	NAME(NWIODIPOROUTE);	/* TODO: print argument */
145 	NAME(NWIOGIPIROUTE);	/* TODO: print argument */
146 	NAME(NWIOSIPIROUTE);	/* TODO: print argument */
147 	NAME(NWIODIPIROUTE);	/* TODO: print argument */
148 	NAME(NWIOSTCPCONF);
149 	NAME(NWIOGTCPCONF);
150 	NAME(NWIOTCPCONN);
151 	NAME(NWIOTCPLISTEN);
152 	NAME(NWIOTCPATTACH);	/* TODO: print argument */
153 	NAME(NWIOTCPSHUTDOWN);	/* no argument */
154 	NAME(NWIOSTCPOPT);
155 	NAME(NWIOGTCPOPT);
156 	NAME(NWIOTCPPUSH);	/* no argument */
157 	NAME(NWIOTCPLISTENQ);
158 	NAME(NWIOGTCPCOOKIE);
159 	NAME(NWIOTCPACCEPTTO);
160 	NAME(NWIOTCPGERROR);
161 	NAME(NWIOSUDPOPT);
162 	NAME(NWIOGUDPOPT);
163 	NAME(NWIOUDPPEEK);	/* TODO: print argument */
164 	NAME(NWIOSPSIPOPT);	/* TODO: print argument */
165 	NAME(NWIOGPSIPOPT);	/* TODO: print argument */
166 	NAME(NWIOGUDSFADDR);
167 	NAME(NWIOSUDSTADDR);
168 	NAME(NWIOSUDSADDR);
169 	NAME(NWIOGUDSADDR);
170 	NAME(NWIOGUDSPADDR);
171 	NAME(NWIOSUDSTYPE);
172 	NAME(NWIOSUDSBLOG);
173 	NAME(NWIOSUDSCONN);
174 	NAME(NWIOSUDSSHUT);
175 	NAME(NWIOSUDSPAIR);
176 	NAME(NWIOSUDSACCEPT);
177 	NAME(NWIOSUDSCTRL);
178 	NAME(NWIOGUDSCTRL);
179 	NAME(NWIOGUDSSOTYPE);
180 	NAME(NWIOGUDSPEERCRED);
181 	NAME(NWIOGUDSSNDBUF);
182 	NAME(NWIOSUDSSNDBUF);
183 	NAME(NWIOGUDSRCVBUF);
184 	NAME(NWIOSUDSRCVBUF);
185 	}
186 
187 	return NULL;
188 }
189 
190 static const struct flags ipopt_flags[] = {
191 	FLAG_ZERO(NWIO_NOFLAGS),
192 	FLAG_MASK(NWIO_ACC_MASK, NWIO_EXCL),
193 	FLAG_MASK(NWIO_ACC_MASK, NWIO_SHARED),
194 	FLAG_MASK(NWIO_ACC_MASK, NWIO_COPY),
195 	FLAG(NWIO_EN_LOC),
196 	FLAG(NWIO_DI_LOC),
197 	FLAG(NWIO_EN_BROAD),
198 	FLAG(NWIO_DI_BROAD),
199 	FLAG(NWIO_REMSPEC),
200 	FLAG(NWIO_REMANY),
201 	FLAG(NWIO_PROTOSPEC),
202 	FLAG(NWIO_PROTOANY),
203 	FLAG(NWIO_HDR_O_SPEC),
204 	FLAG(NWIO_HDR_O_ANY),
205 	FLAG(NWIO_RWDATONLY),
206 	FLAG(NWIO_RWDATALL),
207 };
208 
209 static void
210 put_ipaddr(struct trace_proc * proc, const char * name, ipaddr_t ipaddr)
211 {
212 	struct in_addr in;
213 
214 	in.s_addr = ipaddr;
215 
216 	put_in_addr(proc, name, in);
217 }
218 
219 static void
220 put_ipproto(struct trace_proc * proc, const char * name, ipproto_t proto)
221 {
222 	const char *text = NULL;
223 
224 	if (!valuesonly) {
225 		switch (proto) {
226 		TEXT(IPPROTO_ICMP);
227 		TEXT(IPPROTO_TCP);
228 		TEXT(IPPROTO_UDP);
229 		}
230 	}
231 
232 	if (text != NULL)
233 		put_field(proc, name, text);
234 	else
235 		put_value(proc, name, "%u", proto);
236 }
237 
238 static const struct flags tcpconf_flags[] = {
239 	FLAG_ZERO(NWTC_NOFLAGS),
240 	FLAG_MASK(NWTC_ACC_MASK, NWTC_EXCL),
241 	FLAG_MASK(NWTC_ACC_MASK, NWTC_SHARED),
242 	FLAG_MASK(NWTC_ACC_MASK, NWTC_COPY),
243 	FLAG_MASK(NWTC_LOCPORT_MASK, NWTC_LP_UNSET),
244 	FLAG_MASK(NWTC_LOCPORT_MASK, NWTC_LP_SET),
245 	FLAG_MASK(NWTC_LOCPORT_MASK, NWTC_LP_SEL),
246 	FLAG(NWTC_SET_RA),
247 	FLAG(NWTC_UNSET_RA),
248 	FLAG(NWTC_SET_RP),
249 	FLAG(NWTC_UNSET_RP),
250 };
251 
252 #define put_port(proc, name, port) \
253 	put_value(proc, name, "%u", ntohs(port))
254 
255 static const struct flags tcpcl_flags[] = {
256 	FLAG_ZERO(TCF_DEFAULT),
257 	FLAG(TCF_ASYNCH),
258 };
259 
260 static const struct flags tcpopt_flags[] = {
261 	FLAG_ZERO(NWTO_NOFLAG),
262 	FLAG(NWTO_SND_URG),
263 	FLAG(NWTO_SND_NOTURG),
264 	FLAG(NWTO_RCV_URG),
265 	FLAG(NWTO_RCV_NOTURG),
266 	FLAG(NWTO_BSD_URG),
267 	FLAG(NWTO_NOTBSD_URG),
268 	FLAG(NWTO_DEL_RST),
269 	FLAG(NWTO_BULK),
270 	FLAG(NWTO_NOBULK),
271 };
272 
273 static const struct flags udpopt_flags[] = {
274 	FLAG_ZERO(NWUO_NOFLAGS),
275 	FLAG_MASK(NWUO_ACC_MASK, NWUO_EXCL),
276 	FLAG_MASK(NWUO_ACC_MASK, NWUO_SHARED),
277 	FLAG_MASK(NWUO_ACC_MASK, NWUO_COPY),
278 	FLAG_MASK(NWUO_LOCPORT_MASK, NWUO_LP_SET),
279 	FLAG_MASK(NWUO_LOCPORT_MASK, NWUO_LP_SEL),
280 	FLAG_MASK(NWUO_LOCPORT_MASK, NWUO_LP_ANY),
281 	FLAG(NWUO_EN_LOC),
282 	FLAG(NWUO_DI_LOC),
283 	FLAG(NWUO_EN_BROAD),
284 	FLAG(NWUO_DI_BROAD),
285 	FLAG(NWUO_RP_SET),
286 	FLAG(NWUO_RP_ANY),
287 	FLAG(NWUO_RA_SET),
288 	FLAG(NWUO_RA_ANY),
289 	FLAG(NWUO_RWDATONLY),
290 	FLAG(NWUO_RWDATALL),
291 	FLAG(NWUO_EN_IPOPT),
292 	FLAG(NWUO_DI_IPOPT),
293 };
294 
295 static void
296 put_struct_uucred(struct trace_proc * proc, const char * name, int flags,
297 	vir_bytes addr)
298 {
299 	struct uucred cred;
300 
301 	if (!put_open_struct(proc, name, flags, addr, &cred, sizeof(cred)))
302 		return;
303 
304 	put_value(proc, "cr_uid", "%u", cred.cr_uid);
305 	if (verbose > 0) {
306 		put_value(proc, "cr_gid", "%u", cred.cr_gid);
307 		if (verbose > 1)
308 			put_value(proc, "cr_ngroups", "%d", cred.cr_ngroups);
309 		put_groups(proc, "cr_groups", PF_LOCADDR,
310 		    (vir_bytes)&cred.cr_groups, cred.cr_ngroups);
311 	}
312 
313 	put_close_struct(proc, verbose > 0);
314 }
315 
316 static void
317 put_msg_control(struct trace_proc * proc, struct msg_control * ptr)
318 {
319 	struct msghdr msg;
320 	struct cmsghdr *cmsg;
321 	size_t len;
322 	unsigned int i;
323 
324 	if (ptr->msg_controllen > sizeof(ptr->msg_control)) {
325 		put_field(proc, NULL, "..");
326 
327 		return;
328 	}
329 
330 	put_open(proc, NULL, PF_NONAME, "[", ", ");
331 
332 	memset(&msg, 0, sizeof(msg));
333 	msg.msg_control = ptr->msg_control;
334 	msg.msg_controllen = ptr->msg_controllen;
335 
336 	/*
337 	 * TODO: decide if we need a verbosity-based limit here.  The argument
338 	 * in favor of printing everything is that upon receipt, SCM_RIGHTS
339 	 * actually creates new file descriptors, which is pretty essential in
340 	 * terms of figuring out what is happening in a process.  In addition,
341 	 * these calls should be sufficiently rare that the lengthy output is
342 	 * not really disruptive for the general output flow.
343 	 */
344 	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
345 	    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
346 		put_open(proc, NULL, 0, "{", ", ");
347 
348 		if (verbose > 0)
349 			put_value(proc, "cmsg_len", "%u", cmsg->cmsg_len);
350 		if (!valuesonly && cmsg->cmsg_level == SOL_SOCKET)
351 			put_field(proc, "cmsg_level", "SOL_SOCKET");
352 		else
353 			put_value(proc, "cmsg_level", "%d", cmsg->cmsg_level);
354 		if (cmsg->cmsg_level == SOL_SOCKET)
355 			put_cmsg_type(proc, "cmsg_type", cmsg->cmsg_type);
356 
357 		len = cmsg->cmsg_len - CMSG_LEN(0);
358 
359 		/* Print the contents of the messages that we know. */
360 		if (cmsg->cmsg_level == SOL_SOCKET &&
361 		    cmsg->cmsg_type == SCM_RIGHTS) {
362 			put_open(proc, NULL, PF_NONAME, "[", ", ");
363 			for (i = 0; i < len / sizeof(int); i++)
364 				put_fd(proc, NULL,
365 				    ((int *)CMSG_DATA(cmsg))[i]);
366 			put_close(proc, "]");
367 		} else if (cmsg->cmsg_level == SOL_SOCKET &&
368 		    cmsg->cmsg_type == SCM_CREDS) {
369 			put_struct_uucred(proc, NULL, PF_LOCADDR,
370 			    (vir_bytes)CMSG_DATA(cmsg));
371 		} else if (len > 0)
372 			put_field(proc, NULL, "..");
373 
374 		put_close(proc, "}");
375 	}
376 
377 	put_close(proc, "]");
378 }
379 
380 int
381 net_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr, int dir)
382 {
383 	const char *text;
384 	nwio_ipopt_t *ipopt;
385 	nwio_tcpconf_t *nwtc;
386 	nwio_tcpcl_t *nwtcl;
387 	nwio_tcpopt_t *nwto;
388 	tcp_cookie_t *cookie;
389 	nwio_udpopt_t *nwuo;
390 	struct sockaddr_un *sun;
391 	int i;
392 
393 	switch (req) {
394 	case FIONREAD:
395 		/*
396 		 * Arguably this does not belong here, but as of writing, the
397 		 * network services are the only ones actually implementing
398 		 * support for this IOCTL, and we don't have a more suitable
399 		 * place to put it either.
400 		 */
401 		if (ptr == NULL)
402 			return IF_IN;
403 
404 		put_value(proc, NULL, "%d", *(int *)ptr);
405 		return IF_ALL;
406 
407 	case NWIOSIPOPT:
408 	case NWIOGIPOPT:
409 		if ((ipopt = (nwio_ipopt_t *)ptr) == NULL)
410 			return dir;
411 
412 		put_flags(proc, "nwio_flags", ipopt_flags, COUNT(ipopt_flags),
413 		    "0x%x", ipopt->nwio_flags);
414 
415 		if (ipopt->nwio_flags & NWIO_REMSPEC)
416 			put_ipaddr(proc, "nwio_rem", ipopt->nwio_rem);
417 		if (ipopt->nwio_flags & NWIO_PROTOSPEC)
418 			put_ipproto(proc, "nwio_proto", ipopt->nwio_proto);
419 
420 		return 0; /* TODO: the remaining fields */
421 
422 	case NWIOSTCPCONF:
423 	case NWIOGTCPCONF:
424 		if ((nwtc = (nwio_tcpconf_t *)ptr) == NULL)
425 			return dir;
426 
427 		put_flags(proc, "nwtc_flags", tcpconf_flags,
428 		    COUNT(tcpconf_flags), "0x%x", nwtc->nwtc_flags);
429 
430 		/* The local address cannot be set, just retrieved. */
431 		if (req == NWIOGTCPCONF)
432 			put_ipaddr(proc, "nwtc_locaddr", nwtc->nwtc_locaddr);
433 
434 		if ((nwtc->nwtc_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SET)
435 			put_port(proc, "nwtc_locport", nwtc->nwtc_locport);
436 
437 		if (nwtc->nwtc_flags & NWTC_SET_RA)
438 			put_ipaddr(proc, "nwtc_remaddr", nwtc->nwtc_remaddr);
439 
440 		if (nwtc->nwtc_flags & NWTC_SET_RP)
441 			put_port(proc, "nwtc_remport", nwtc->nwtc_remport);
442 
443 		return IF_ALL;
444 
445 	case NWIOTCPCONN:
446 	case NWIOTCPLISTEN:
447 		if ((nwtcl = (nwio_tcpcl_t *)ptr) == NULL)
448 			return dir;
449 
450 		put_flags(proc, "nwtcl_flags", tcpcl_flags,
451 		    COUNT(tcpcl_flags), "0x%x", nwtcl->nwtcl_flags);
452 
453 		/* We pretend the unused nwtcl_ttl field does not exist. */
454 		return IF_ALL;
455 
456 	case NWIOSTCPOPT:
457 	case NWIOGTCPOPT:
458 		if ((nwto = (nwio_tcpopt_t *)ptr) == NULL)
459 			return dir;
460 
461 		put_flags(proc, "nwto_flags", tcpopt_flags,
462 		    COUNT(tcpopt_flags), "0x%x", nwto->nwto_flags);
463 		return IF_ALL;
464 
465 	case NWIOTCPLISTENQ:
466 	case NWIOSUDSBLOG:
467 		if (ptr == NULL)
468 			return IF_OUT;
469 
470 		put_value(proc, NULL, "%d", *(int *)ptr);
471 		return IF_ALL;
472 
473 	case NWIOGTCPCOOKIE:
474 	case NWIOTCPACCEPTTO:
475 		if ((cookie = (tcp_cookie_t *)ptr) == NULL)
476 			return dir;
477 
478 		put_value(proc, "tc_ref", "%"PRIu32, cookie->tc_ref);
479 		if (verbose > 0)
480 			put_buf(proc, "tc_secret", PF_LOCADDR,
481 			    (vir_bytes)&cookie->tc_secret,
482 			    sizeof(cookie->tc_secret));
483 		return (verbose > 0) ? IF_ALL : 0;
484 
485 	case NWIOTCPGERROR:
486 		if (ptr == NULL)
487 			return IF_IN;
488 
489 		i = *(int *)ptr;
490 		if (!valuesonly && (text = get_error_name(i)) != NULL)
491 			put_field(proc, NULL, text);
492 		else
493 			put_value(proc, NULL, "%d", i);
494 		return IF_ALL;
495 
496 	case NWIOSUDPOPT:
497 	case NWIOGUDPOPT:
498 		if ((nwuo = (nwio_udpopt_t *)ptr) == NULL)
499 			return dir;
500 
501 		put_flags(proc, "nwuo_flags", udpopt_flags,
502 		    COUNT(udpopt_flags), "0x%x", nwuo->nwuo_flags);
503 
504 		/* The local address cannot be set, just retrieved. */
505 		if (req == NWIOGUDPOPT)
506 			put_ipaddr(proc, "nwuo_locaddr", nwuo->nwuo_locaddr);
507 
508 		if ((nwuo->nwuo_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SET)
509 			put_port(proc, "nwuo_locport", nwuo->nwuo_locport);
510 
511 		if (nwuo->nwuo_flags & NWUO_RA_SET)
512 			put_ipaddr(proc, "nwuo_remaddr", nwuo->nwuo_remaddr);
513 
514 		if (nwuo->nwuo_flags & NWUO_RP_SET)
515 			put_port(proc, "nwuo_remport", nwuo->nwuo_remport);
516 
517 		return IF_ALL;
518 
519 	case NWIOGUDSFADDR:
520 	case NWIOSUDSTADDR:
521 	case NWIOSUDSADDR:
522 	case NWIOGUDSADDR:
523 	case NWIOGUDSPADDR:
524 	case NWIOSUDSCONN:
525 	case NWIOSUDSACCEPT:
526 		if ((sun = (struct sockaddr_un *)ptr) == NULL)
527 			return dir;
528 
529 		put_socket_family(proc, "sun_family", sun->sun_family);
530 
531 		/* This could be extended to a generic sockaddr printer.. */
532 		if (sun->sun_family == AF_LOCAL) {
533 			put_buf(proc, "sun_path", PF_LOCADDR | PF_PATH,
534 			    (vir_bytes)&sun->sun_path, sizeof(sun->sun_path));
535 			return IF_ALL; /* skipping sun_len, it's unused */
536 		} else
537 			return 0;
538 
539 	case NWIOSUDSTYPE:
540 	case NWIOGUDSSOTYPE:
541 		if (ptr == NULL)
542 			return dir;
543 
544 		put_socket_type(proc, NULL, *(int *)ptr);
545 		return IF_ALL;
546 
547 	case NWIOSUDSSHUT:
548 		if (ptr == NULL)
549 			return IF_OUT;
550 
551 		put_shutdown_how(proc, NULL, *(int *)ptr);
552 		return IF_ALL;
553 
554 	case NWIOSUDSPAIR:
555 		if (ptr == NULL)
556 			return IF_OUT;
557 
558 		put_dev(proc, NULL, *(dev_t *)ptr);
559 		return IF_ALL;
560 
561 	case NWIOSUDSCTRL:
562 		if (ptr == NULL)
563 			return IF_OUT;
564 
565 		/* FALLTHROUGH */
566 	case NWIOGUDSCTRL:
567 		if (ptr == NULL)
568 			return IF_IN;
569 
570 		put_msg_control(proc, (struct msg_control *)ptr);
571 		return IF_ALL;
572 
573 	case NWIOGUDSPEERCRED:
574 		if (ptr == NULL)
575 			return IF_IN;
576 
577 		put_struct_uucred(proc, NULL, PF_LOCADDR, (vir_bytes)ptr);
578 		return IF_ALL;
579 
580 	case NWIOGUDSSNDBUF:
581 	case NWIOSUDSSNDBUF:
582 	case NWIOGUDSRCVBUF:
583 	case NWIOSUDSRCVBUF:
584 		if (ptr == NULL)
585 			return dir;
586 
587 		put_value(proc, NULL, "%zu", *(size_t *)ptr);
588 		return IF_ALL;
589 
590 	default:
591 		return 0;
592 	}
593 }
594