1 /* UNIX Domain Sockets - stat.c - network status */
4 #include <sys/socketvar.h>
8 * Fill the given 'ki' structure with information about the socket 'uds'.
11 uds_get_info(struct kinfo_pcb
* ki
, const struct udssock
* uds
)
17 type
= uds_get_type(uds
);
18 peer
= uds_get_peer(uds
);
20 ki
->ki_pcbaddr
= (uint64_t)(uintptr_t)uds
;
21 ki
->ki_ppcbaddr
= (uint64_t)(uintptr_t)uds
;
22 ki
->ki_sockaddr
= (uint64_t)(uintptr_t)&uds
->uds_sock
;
23 ki
->ki_family
= AF_UNIX
;
25 ki
->ki_protocol
= UDSPROTO_UDS
;
27 if (uds
->uds_flags
& UDSF_CONNWAIT
)
28 ki
->ki_pflags
|= UNP_CONNWAIT
;
29 if (uds
->uds_flags
& UDSF_PASSCRED
)
30 ki
->ki_pflags
|= UNP_WANTCRED
;
31 if (type
!= SOCK_DGRAM
&& uds
->uds_cred
.unp_pid
!= -1) {
32 if (uds_is_listening(uds
))
33 ki
->ki_pflags
|= UNP_EIDSBIND
;
34 else if (uds_is_connecting(uds
) || uds_is_connected(uds
))
35 ki
->ki_pflags
|= UNP_EIDSVALID
;
37 /* Not sure about NetBSD connection states. First attempt here. */
38 if (uds_is_connecting(uds
))
39 ki
->ki_sostate
= SS_ISCONNECTING
;
40 else if (uds_is_connected(uds
))
41 ki
->ki_sostate
= SS_ISCONNECTED
;
42 else if (uds_is_disconnected(uds
))
43 ki
->ki_sostate
= SS_ISDISCONNECTED
;
44 ki
->ki_rcvq
= uds
->uds_len
;
45 /* We currently mirror the peer's receive queue size when connected. */
46 if (uds_is_connected(uds
))
47 ki
->ki_sndq
= peer
->uds_len
;
48 /* The source is not set for bound connection-type sockets here. */
49 if (type
== SOCK_DGRAM
|| uds_is_listening(uds
))
50 uds_make_addr(uds
->uds_path
, (size_t)uds
->uds_pathlen
,
53 uds_make_addr(peer
->uds_path
, (size_t)peer
->uds_pathlen
,
55 /* TODO: we should set ki_inode and ki_vnode, but to what? */
56 ki
->ki_conn
= (uint64_t)(uintptr_t)peer
;
57 if (!TAILQ_EMPTY(&uds
->uds_queue
))
59 (uint64_t)(uintptr_t)TAILQ_FIRST(&uds
->uds_queue
);
60 if (uds_has_link(uds
))
62 (uint64_t)(uintptr_t)TAILQ_NEXT(uds
, uds_next
);
66 * Remote MIB implementation of CTL_NET PF_LOCAL {SOCK_STREAM,SOCK_DGRAM,
67 * SOCK_SEQPACKET} 0. This function handles all queries on the
68 * "net.local.{stream,dgram,seqpacket}.pcblist" sysctl(7) nodes.
70 * The 0 for "pcblist" is a MINIXism: we use it to keep our arrays small.
71 * NetBSD numbers these nodes dynamically and so they have numbers above
72 * CREATE_BASE. That also means that no userland application can possibly
73 * hardcode their numbers, and must perform lookups by name. In turn, that
74 * means that we can safely change the 0 to another number if NetBSD ever
75 * introduces statically numbered nodes in these subtrees.
78 net_local_pcblist(struct rmib_call
* call
, struct rmib_node
* node __unused
,
79 struct rmib_oldp
* oldp
, struct rmib_newp
* newp __unused
)
84 int r
, type
, size
, max
;
86 if (call
->call_namelen
!= 4)
89 /* The first two added name fields are not used. */
91 size
= call
->call_name
[2];
92 if (size
< 0 || (size_t)size
> sizeof(ki
))
96 max
= call
->call_name
[3];
98 type
= call
->call_oname
[2];
102 for (uds
= uds_enum(NULL
, type
); uds
!= NULL
;
103 uds
= uds_enum(uds
, type
)) {
104 if (rmib_inrange(oldp
, off
)) {
105 memset(&ki
, 0, sizeof(ki
));
107 uds_get_info(&ki
, uds
);
109 if ((r
= rmib_copyout(oldp
, off
, &ki
, size
)) < 0)
114 if (max
> 0 && --max
== 0)
119 * Margin to limit the possible effects of the inherent race condition
120 * between receiving just the data size and receiving the actual data.
123 off
+= PCB_SLOP
* size
;
128 /* The CTL_NET PF_LOCAL SOCK_STREAM subtree. */
129 static struct rmib_node net_local_stream_table
[] = {
130 [0] = RMIB_FUNC(RMIB_RO
| CTLTYPE_NODE
, 0, net_local_pcblist
,
131 "pcblist", "SOCK_STREAM protocol control block list"),
134 /* The CTL_NET PF_LOCAL SOCK_DGRAM subtree. */
135 static struct rmib_node net_local_dgram_table
[] = {
136 [0] = RMIB_FUNC(RMIB_RO
| CTLTYPE_NODE
, 0, net_local_pcblist
,
137 "pcblist", "SOCK_DGRAM protocol control block list"),
140 /* The CTL_NET PF_LOCAL SOCK_SEQPACKET subtree. */
141 static struct rmib_node net_local_seqpacket_table
[] = {
142 [0] = RMIB_FUNC(RMIB_RO
| CTLTYPE_NODE
, 0, net_local_pcblist
,
143 "pcblist", "SOCK_SEQPACKET protocol control block list"),
146 /* The CTL_NET PF_LOCAL subtree. */
147 static struct rmib_node net_local_table
[] = {
148 /* 1*/ [SOCK_STREAM
] = RMIB_NODE(RMIB_RO
, net_local_stream_table
,
149 "stream", "SOCK_STREAM settings"),
150 /* 2*/ [SOCK_DGRAM
] = RMIB_NODE(RMIB_RO
, net_local_dgram_table
,
151 "dgram", "SOCK_DGRAM settings"),
152 /* 5*/ [SOCK_SEQPACKET
] = RMIB_NODE(RMIB_RO
, net_local_seqpacket_table
,
153 "seqpacket", "SOCK_SEQPACKET settings"),
156 static struct rmib_node net_local_node
=
157 RMIB_NODE(RMIB_RO
, net_local_table
, "local", "PF_LOCAL related settings");
160 * Initialize the status module.
165 const int mib
[] = { CTL_NET
, PF_LOCAL
};
169 * Register our own "net.local" subtree with the MIB service.
171 * This call only returns local failures. Remote failures (in the MIB
172 * service) are silently ignored. So, we can safely panic on failure.
174 if ((r
= rmib_register(mib
, __arraycount(mib
), &net_local_node
)) != OK
)
175 panic("UDS: unable to register remote MIB tree: %d", r
);
179 * Clean up the status module.
182 uds_stat_cleanup(void)
185 rmib_deregister(&net_local_node
);