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>
21 net_ioctl_name(unsigned long req
)
26 NAME(NWIOSETHOPT
); /* TODO: print argument */
27 NAME(NWIOGETHOPT
); /* TODO: print argument */
28 NAME(NWIOGETHSTAT
); /* TODO: print argument */
29 NAME(NWIOARPGIP
); /* TODO: print argument */
30 NAME(NWIOARPGNEXT
); /* TODO: print argument */
31 NAME(NWIOARPSIP
); /* TODO: print argument */
32 NAME(NWIOARPDIP
); /* TODO: print argument */
33 NAME(NWIOSIPCONF2
); /* TODO: print argument */
34 NAME(NWIOSIPCONF
); /* TODO: print argument */
35 NAME(NWIOGIPCONF2
); /* TODO: print argument */
36 NAME(NWIOGIPCONF
); /* TODO: print argument */
39 NAME(NWIOGIPOROUTE
); /* TODO: print argument */
40 NAME(NWIOSIPOROUTE
); /* TODO: print argument */
41 NAME(NWIODIPOROUTE
); /* TODO: print argument */
42 NAME(NWIOGIPIROUTE
); /* TODO: print argument */
43 NAME(NWIOSIPIROUTE
); /* TODO: print argument */
44 NAME(NWIODIPIROUTE
); /* TODO: print argument */
49 NAME(NWIOTCPATTACH
); /* TODO: print argument */
50 NAME(NWIOTCPSHUTDOWN
); /* no argument */
53 NAME(NWIOTCPPUSH
); /* no argument */
56 NAME(NWIOTCPACCEPTTO
);
60 NAME(NWIOUDPPEEK
); /* TODO: print argument */
61 NAME(NWIOSPSIPOPT
); /* TODO: print argument */
62 NAME(NWIOGPSIPOPT
); /* TODO: print argument */
77 NAME(NWIOGUDSPEERCRED
);
87 static const struct flags ipopt_flags
[] = {
88 FLAG_ZERO(NWIO_NOFLAGS
),
89 FLAG_MASK(NWIO_ACC_MASK
, NWIO_EXCL
),
90 FLAG_MASK(NWIO_ACC_MASK
, NWIO_SHARED
),
91 FLAG_MASK(NWIO_ACC_MASK
, NWIO_COPY
),
100 FLAG(NWIO_HDR_O_SPEC
),
101 FLAG(NWIO_HDR_O_ANY
),
102 FLAG(NWIO_RWDATONLY
),
107 put_ipaddr(struct trace_proc
* proc
, const char * name
, ipaddr_t ipaddr
)
114 /* Is this an acceptable encapsulation? */
115 put_value(proc
, name
, "[%s]", inet_ntoa(in
));
117 put_value(proc
, name
, "0x%08x", ntohl(ipaddr
));
121 put_ipproto(struct trace_proc
* proc
, const char * name
, ipproto_t proto
)
123 const char *text
= NULL
;
134 put_field(proc
, name
, text
);
136 put_value(proc
, name
, "%u", proto
);
139 static const struct flags tcpconf_flags
[] = {
140 FLAG_ZERO(NWTC_NOFLAGS
),
141 FLAG_MASK(NWTC_ACC_MASK
, NWTC_EXCL
),
142 FLAG_MASK(NWTC_ACC_MASK
, NWTC_SHARED
),
143 FLAG_MASK(NWTC_ACC_MASK
, NWTC_COPY
),
144 FLAG_MASK(NWTC_LOCPORT_MASK
, NWTC_LP_UNSET
),
145 FLAG_MASK(NWTC_LOCPORT_MASK
, NWTC_LP_SET
),
146 FLAG_MASK(NWTC_LOCPORT_MASK
, NWTC_LP_SEL
),
153 #define put_port(proc, name, port) \
154 put_value(proc, name, "%u", ntohs(port))
156 static const struct flags tcpcl_flags
[] = {
157 FLAG_ZERO(TCF_DEFAULT
),
161 static const struct flags tcpopt_flags
[] = {
162 FLAG_ZERO(NWTO_NOFLAG
),
164 FLAG(NWTO_SND_NOTURG
),
166 FLAG(NWTO_RCV_NOTURG
),
168 FLAG(NWTO_NOTBSD_URG
),
174 static const struct flags udpopt_flags
[] = {
175 FLAG_ZERO(NWUO_NOFLAGS
),
176 FLAG_MASK(NWUO_ACC_MASK
, NWUO_EXCL
),
177 FLAG_MASK(NWUO_ACC_MASK
, NWUO_SHARED
),
178 FLAG_MASK(NWUO_ACC_MASK
, NWUO_COPY
),
179 FLAG_MASK(NWUO_LOCPORT_MASK
, NWUO_LP_SET
),
180 FLAG_MASK(NWUO_LOCPORT_MASK
, NWUO_LP_SEL
),
181 FLAG_MASK(NWUO_LOCPORT_MASK
, NWUO_LP_ANY
),
190 FLAG(NWUO_RWDATONLY
),
197 put_family(struct trace_proc
* proc
, const char * name
, int family
)
199 const char *text
= NULL
;
202 /* TODO: add all the other protocols */
212 put_field(proc
, name
, text
);
214 put_value(proc
, name
, "%d", family
);
217 static const struct flags sock_type
[] = {
218 FLAG_MASK(~SOCK_FLAGS_MASK
, SOCK_STREAM
),
219 FLAG_MASK(~SOCK_FLAGS_MASK
, SOCK_DGRAM
),
220 FLAG_MASK(~SOCK_FLAGS_MASK
, SOCK_RAW
),
221 FLAG_MASK(~SOCK_FLAGS_MASK
, SOCK_RDM
),
222 FLAG_MASK(~SOCK_FLAGS_MASK
, SOCK_SEQPACKET
),
225 FLAG(SOCK_NOSIGPIPE
),
229 put_shutdown_how(struct trace_proc
* proc
, const char * name
, int how
)
231 const char *text
= NULL
;
242 put_field(proc
, name
, text
);
244 put_value(proc
, name
, "%d", how
);
248 put_struct_uucred(struct trace_proc
* proc
, const char * name
, int flags
,
253 if (!put_open_struct(proc
, name
, flags
, addr
, &cred
, sizeof(cred
)))
256 put_value(proc
, "cr_uid", "%u", cred
.cr_uid
);
258 put_value(proc
, "cr_gid", "%u", cred
.cr_gid
);
260 put_value(proc
, "cr_ngroups", "%d", cred
.cr_ngroups
);
261 put_groups(proc
, "cr_groups", PF_LOCADDR
,
262 (vir_bytes
)&cred
.cr_groups
, cred
.cr_ngroups
);
265 put_close_struct(proc
, verbose
> 0);
269 put_cmsg_type(struct trace_proc
* proc
, const char * name
, int type
)
271 const char *text
= NULL
;
282 put_field(proc
, name
, text
);
284 put_value(proc
, name
, "%d", type
);
288 put_msg_control(struct trace_proc
* proc
, struct msg_control
* ptr
)
291 struct cmsghdr
*cmsg
;
295 if (ptr
->msg_controllen
> sizeof(ptr
->msg_control
)) {
296 put_field(proc
, NULL
, "..");
301 put_open(proc
, NULL
, PF_NONAME
, "[", ", ");
303 memset(&msg
, 0, sizeof(msg
));
304 msg
.msg_control
= ptr
->msg_control
;
305 msg
.msg_controllen
= ptr
->msg_controllen
;
308 * TODO: decide if we need a verbosity-based limit here. The argument
309 * in favor of printing everything is that upon receipt, SCM_RIGHTS
310 * actually creates new file descriptors, which is pretty essential in
311 * terms of figuring out what is happening in a process. In addition,
312 * these calls should be sufficiently rare that the lengthy output is
313 * not really disruptive for the general output flow.
315 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= NULL
;
316 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
317 put_open(proc
, NULL
, 0, "{", ", ");
320 put_value(proc
, "cmsg_len", "%u", cmsg
->cmsg_len
);
321 if (!valuesonly
&& cmsg
->cmsg_level
== SOL_SOCKET
)
322 put_field(proc
, "cmsg_level", "SOL_SOCKET");
324 put_value(proc
, "cmsg_level", "%d", cmsg
->cmsg_level
);
325 if (cmsg
->cmsg_level
== SOL_SOCKET
)
326 put_cmsg_type(proc
, "cmsg_type", cmsg
->cmsg_type
);
328 len
= cmsg
->cmsg_len
- CMSG_LEN(0);
330 /* Print the contents of the messages that we know. */
331 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
332 cmsg
->cmsg_type
== SCM_RIGHTS
) {
333 put_open(proc
, NULL
, PF_NONAME
, "[", ", ");
334 for (i
= 0; i
< len
/ sizeof(int); i
++)
336 ((int *)CMSG_DATA(cmsg
))[i
]);
337 put_close(proc
, "]");
338 } else if (cmsg
->cmsg_level
== SOL_SOCKET
&&
339 cmsg
->cmsg_type
== SCM_CREDS
) {
340 put_struct_uucred(proc
, NULL
, PF_LOCADDR
,
341 (vir_bytes
)CMSG_DATA(cmsg
));
343 put_field(proc
, NULL
, "..");
345 put_close(proc
, "}");
348 put_close(proc
, "]");
352 net_ioctl_arg(struct trace_proc
* proc
, unsigned long req
, void * ptr
, int dir
)
356 nwio_tcpconf_t
*nwtc
;
359 tcp_cookie_t
*cookie
;
361 struct sockaddr_un
*sun
;
367 * Arguably this does not belong here, but as of writing, the
368 * network services are the only ones actually implementing
369 * support for this IOCTL, and we don't have a more suitable
370 * place to put it either.
375 put_value(proc
, NULL
, "%d", *(int *)ptr
);
380 if ((ipopt
= (nwio_ipopt_t
*)ptr
) == NULL
)
383 put_flags(proc
, "nwio_flags", ipopt_flags
, COUNT(ipopt_flags
),
384 "0x%x", ipopt
->nwio_flags
);
386 if (ipopt
->nwio_flags
& NWIO_REMSPEC
)
387 put_ipaddr(proc
, "nwio_rem", ipopt
->nwio_rem
);
388 if (ipopt
->nwio_flags
& NWIO_PROTOSPEC
)
389 put_ipproto(proc
, "nwio_proto", ipopt
->nwio_proto
);
391 return 0; /* TODO: the remaining fields */
395 if ((nwtc
= (nwio_tcpconf_t
*)ptr
) == NULL
)
398 put_flags(proc
, "nwtc_flags", tcpconf_flags
,
399 COUNT(tcpconf_flags
), "0x%x", nwtc
->nwtc_flags
);
401 /* The local address cannot be set, just retrieved. */
402 if (req
== NWIOGTCPCONF
)
403 put_ipaddr(proc
, "nwtc_locaddr", nwtc
->nwtc_locaddr
);
405 if ((nwtc
->nwtc_flags
& NWTC_LOCPORT_MASK
) == NWTC_LP_SET
)
406 put_port(proc
, "nwtc_locport", nwtc
->nwtc_locport
);
408 if (nwtc
->nwtc_flags
& NWTC_SET_RA
)
409 put_ipaddr(proc
, "nwtc_remaddr", nwtc
->nwtc_remaddr
);
411 if (nwtc
->nwtc_flags
& NWTC_SET_RP
)
412 put_port(proc
, "nwtc_remport", nwtc
->nwtc_remport
);
418 if ((nwtcl
= (nwio_tcpcl_t
*)ptr
) == NULL
)
421 put_flags(proc
, "nwtcl_flags", tcpcl_flags
,
422 COUNT(tcpcl_flags
), "0x%x", nwtcl
->nwtcl_flags
);
424 /* We pretend the unused nwtcl_ttl field does not exist. */
429 if ((nwto
= (nwio_tcpopt_t
*)ptr
) == NULL
)
432 put_flags(proc
, "nwto_flags", tcpopt_flags
,
433 COUNT(tcpopt_flags
), "0x%x", nwto
->nwto_flags
);
441 put_value(proc
, NULL
, "%d", *(int *)ptr
);
445 case NWIOTCPACCEPTTO
:
446 if ((cookie
= (tcp_cookie_t
*)ptr
) == NULL
)
449 put_value(proc
, "tc_ref", "%"PRIu32
, cookie
->tc_ref
);
451 put_buf(proc
, "tc_secret", PF_LOCADDR
,
452 (vir_bytes
)&cookie
->tc_secret
,
453 sizeof(cookie
->tc_secret
));
454 return (verbose
> 0) ? IF_ALL
: 0;
461 if (!valuesonly
&& (text
= get_error_name(i
)) != NULL
)
462 put_field(proc
, NULL
, text
);
464 put_value(proc
, NULL
, "%d", i
);
469 if ((nwuo
= (nwio_udpopt_t
*)ptr
) == NULL
)
472 put_flags(proc
, "nwuo_flags", udpopt_flags
,
473 COUNT(udpopt_flags
), "0x%x", nwuo
->nwuo_flags
);
475 /* The local address cannot be set, just retrieved. */
476 if (req
== NWIOGUDPOPT
)
477 put_ipaddr(proc
, "nwuo_locaddr", nwuo
->nwuo_locaddr
);
479 if ((nwuo
->nwuo_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_SET
)
480 put_port(proc
, "nwuo_locport", nwuo
->nwuo_locport
);
482 if (nwuo
->nwuo_flags
& NWUO_RA_SET
)
483 put_ipaddr(proc
, "nwuo_remaddr", nwuo
->nwuo_remaddr
);
485 if (nwuo
->nwuo_flags
& NWUO_RP_SET
)
486 put_port(proc
, "nwuo_remport", nwuo
->nwuo_remport
);
497 if ((sun
= (struct sockaddr_un
*)ptr
) == NULL
)
500 put_family(proc
, "sun_family", sun
->sun_family
);
502 /* This could be extended to a generic sockaddr printer.. */
503 if (sun
->sun_family
== AF_LOCAL
) {
504 put_buf(proc
, "sun_path", PF_LOCADDR
| PF_PATH
,
505 (vir_bytes
)&sun
->sun_path
, sizeof(sun
->sun_path
));
506 return IF_ALL
; /* skipping sun_len, it's unused */
515 put_flags(proc
, NULL
, sock_type
, COUNT(sock_type
), "0x%x",
523 put_shutdown_how(proc
, NULL
, *(int *)ptr
);
530 put_dev(proc
, NULL
, *(dev_t
*)ptr
);
542 put_msg_control(proc
, (struct msg_control
*)ptr
);
545 case NWIOGUDSPEERCRED
:
549 put_struct_uucred(proc
, NULL
, PF_LOCADDR
, (vir_bytes
)ptr
);
559 put_value(proc
, NULL
, "%zu", *(size_t *)ptr
);