]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/socket_info.c
2 * Copyright (c) 2005-2020 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/types.h>
30 #include <sys/kernel_types.h>
31 #include <sys/errno.h>
32 #include <sys/kernel.h>
33 #include <sys/file_internal.h>
35 #include <sys/select.h>
37 #include <sys/proc_info.h>
38 #include <sys/domain.h>
39 #include <sys/protosw.h>
40 #include <sys/domain.h>
41 #include <sys/socketvar.h>
42 #include <sys/unpcb.h>
43 #include <sys/sys_domain.h>
44 #include <sys/kern_event.h>
45 #include <sys/vsock_domain.h>
46 #include <mach/vm_param.h>
47 #include <net/ndrv_var.h>
48 #include <netinet/in_pcb.h>
49 #include <netinet/tcp_var.h>
52 static void fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
);
53 static void fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
);
56 fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
)
58 sbi
->sbi_cc
= sb
->sb_cc
;
59 sbi
->sbi_hiwat
= sb
->sb_hiwat
;
60 sbi
->sbi_mbcnt
= sb
->sb_mbcnt
;
61 sbi
->sbi_mbmax
= sb
->sb_mbmax
;
62 sbi
->sbi_lowat
= sb
->sb_lowat
;
63 sbi
->sbi_flags
= (short)sb
->sb_flags
;
64 sbi
->sbi_timeo
= (short)((sb
->sb_timeo
.tv_sec
* hz
) +
65 sb
->sb_timeo
.tv_usec
/ tick
);
66 if (sbi
->sbi_timeo
== 0 && sb
->sb_timeo
.tv_usec
!= 0) {
72 fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
)
74 si
->soi_so
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
);
75 si
->soi_type
= so
->so_type
;
76 si
->soi_options
= (short)(so
->so_options
& 0xffff);
77 si
->soi_linger
= so
->so_linger
;
78 si
->soi_state
= so
->so_state
;
79 si
->soi_pcb
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
->so_pcb
);
81 si
->soi_protocol
= SOCK_PROTO(so
);
82 if (so
->so_proto
->pr_domain
) {
83 si
->soi_family
= SOCK_DOM(so
);
88 si
->soi_protocol
= si
->soi_family
= 0;
90 si
->soi_qlen
= so
->so_qlen
;
91 si
->soi_incqlen
= so
->so_incqlen
;
92 si
->soi_qlimit
= so
->so_qlimit
;
93 si
->soi_timeo
= so
->so_timeo
;
94 si
->soi_error
= so
->so_error
;
95 si
->soi_oobmark
= so
->so_oobmark
;
96 fill_sockbuf_info(&so
->so_snd
, &si
->soi_snd
);
97 fill_sockbuf_info(&so
->so_rcv
, &si
->soi_rcv
);
101 fill_socketinfo(struct socket
*so
, struct socket_info
*si
)
110 si
->soi_kind
= SOCKINFO_GENERIC
;
112 fill_common_sockinfo(so
, si
);
114 if (so
->so_pcb
== NULL
|| so
->so_proto
== 0 ||
115 so
->so_proto
->pr_domain
== NULL
) {
120 * The kind of socket is determined by the triplet
121 * {domain, type, protocol}
123 domain
= SOCK_DOM(so
);
124 type
= SOCK_TYPE(so
);
125 protocol
= SOCK_PROTO(so
);
129 struct in_sockinfo
*insi
= &si
->soi_proto
.pri_in
;
130 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
132 si
->soi_kind
= SOCKINFO_IN
;
134 insi
->insi_fport
= inp
->inp_fport
;
135 insi
->insi_lport
= inp
->inp_lport
;
136 insi
->insi_gencnt
= inp
->inp_gencnt
;
137 insi
->insi_flags
= inp
->inp_flags
;
138 insi
->insi_vflag
= inp
->inp_vflag
;
139 insi
->insi_ip_ttl
= inp
->inp_ip_ttl
;
140 insi
->insi_faddr
.ina_6
= inp
->inp_dependfaddr
.inp6_foreign
;
141 insi
->insi_laddr
.ina_6
= inp
->inp_dependladdr
.inp6_local
;
142 insi
->insi_v4
.in4_tos
= inp
->inp_depend4
.inp4_ip_tos
;
143 insi
->insi_v6
.in6_hlim
= 0;
144 insi
->insi_v6
.in6_cksum
= inp
->inp_depend6
.inp6_cksum
;
145 insi
->insi_v6
.in6_ifindex
= 0;
146 insi
->insi_v6
.in6_hops
= inp
->inp_depend6
.inp6_hops
;
148 if (type
== SOCK_STREAM
&& (protocol
== 0 ||
149 protocol
== IPPROTO_TCP
) && inp
->inp_ppcb
!= NULL
) {
150 struct tcp_sockinfo
*tcpsi
= &si
->soi_proto
.pri_tcp
;
151 struct tcpcb
*tp
= (struct tcpcb
*)inp
->inp_ppcb
;
153 si
->soi_kind
= SOCKINFO_TCP
;
155 tcpsi
->tcpsi_state
= tp
->t_state
;
156 tcpsi
->tcpsi_timer
[TSI_T_REXMT
] =
157 tp
->t_timer
[TCPT_REXMT
];
158 tcpsi
->tcpsi_timer
[TSI_T_PERSIST
] =
159 tp
->t_timer
[TCPT_PERSIST
];
160 tcpsi
->tcpsi_timer
[TSI_T_KEEP
] =
161 tp
->t_timer
[TCPT_KEEP
];
162 tcpsi
->tcpsi_timer
[TSI_T_2MSL
] =
163 tp
->t_timer
[TCPT_2MSL
];
164 tcpsi
->tcpsi_mss
= tp
->t_maxseg
;
165 tcpsi
->tcpsi_flags
= tp
->t_flags
;
167 (u_int64_t
)VM_KERNEL_ADDRPERM(tp
);
172 struct unpcb
*unp
= (struct unpcb
*)so
->so_pcb
;
173 struct un_sockinfo
*unsi
= &si
->soi_proto
.pri_un
;
175 si
->soi_kind
= SOCKINFO_UN
;
177 unsi
->unsi_conn_pcb
=
178 (uint64_t)VM_KERNEL_ADDRPERM(unp
->unp_conn
);
180 unsi
->unsi_conn_so
= (uint64_t)
181 VM_KERNEL_ADDRPERM(unp
->unp_conn
->unp_socket
);
185 size_t addrlen
= unp
->unp_addr
->sun_len
;
187 if (addrlen
> SOCK_MAXADDRLEN
) {
188 addrlen
= SOCK_MAXADDRLEN
;
190 bcopy(unp
->unp_addr
, &unsi
->unsi_addr
, addrlen
);
192 if (unp
->unp_conn
&& unp
->unp_conn
->unp_addr
) {
193 size_t addrlen
= unp
->unp_conn
->unp_addr
->sun_len
;
195 if (addrlen
> SOCK_MAXADDRLEN
) {
196 addrlen
= SOCK_MAXADDRLEN
;
198 bcopy(unp
->unp_conn
->unp_addr
, &unsi
->unsi_caddr
,
204 struct ndrv_cb
*ndrv_cb
= (struct ndrv_cb
*)so
->so_pcb
;
205 struct ndrv_info
*ndrvsi
= &si
->soi_proto
.pri_ndrv
;
207 si
->soi_kind
= SOCKINFO_NDRV
;
209 /* TDB lock ifnet ???? */
210 if (ndrv_cb
->nd_if
!= 0) {
211 struct ifnet
*ifp
= ndrv_cb
->nd_if
;
213 ndrvsi
->ndrvsi_if_family
= ifp
->if_family
;
214 ndrvsi
->ndrvsi_if_unit
= ifp
->if_unit
;
215 strlcpy(ndrvsi
->ndrvsi_if_name
, ifp
->if_name
, IFNAMSIZ
);
220 const struct vsockpcb
*pcb
= (struct vsockpcb
*)(so
)->so_pcb
;
221 struct vsock_sockinfo
*vsocksi
= &si
->soi_proto
.pri_vsock
;
223 si
->soi_kind
= SOCKINFO_VSOCK
;
225 vsocksi
->local_cid
= pcb
->local_address
.cid
;
226 vsocksi
->local_port
= pcb
->local_address
.port
;
227 vsocksi
->remote_cid
= pcb
->remote_address
.cid
;
228 vsocksi
->remote_port
= pcb
->remote_address
.port
;
233 if (SOCK_PROTO(so
) == SYSPROTO_EVENT
) {
234 struct kern_event_pcb
*ev_pcb
=
235 (struct kern_event_pcb
*)so
->so_pcb
;
236 struct kern_event_info
*kesi
=
237 &si
->soi_proto
.pri_kern_event
;
239 si
->soi_kind
= SOCKINFO_KERN_EVENT
;
241 kesi
->kesi_vendor_code_filter
=
242 ev_pcb
->evp_vendor_code_filter
;
243 kesi
->kesi_class_filter
= ev_pcb
->evp_class_filter
;
244 kesi
->kesi_subclass_filter
= ev_pcb
->evp_subclass_filter
;
245 } else if (SOCK_PROTO(so
) == SYSPROTO_CONTROL
) {
246 kctl_fill_socketinfo(so
, si
);
256 socket_unlock(so
, 0);