]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/socket_info.c
2 * Copyright (c) 2005-2015 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 <mach/vm_param.h>
46 #include <net/ndrv_var.h>
47 #include <netinet/in_pcb.h>
48 #include <netinet/tcp_var.h>
51 static void fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
);
52 static void fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
);
55 fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
)
57 sbi
->sbi_cc
= sb
->sb_cc
;
58 sbi
->sbi_hiwat
= sb
->sb_hiwat
;
59 sbi
->sbi_mbcnt
= sb
->sb_mbcnt
;
60 sbi
->sbi_mbmax
= sb
->sb_mbmax
;
61 sbi
->sbi_lowat
= sb
->sb_lowat
;
62 sbi
->sbi_flags
= sb
->sb_flags
;
63 sbi
->sbi_timeo
= (u_int32_t
)(sb
->sb_timeo
.tv_sec
* hz
) +
64 sb
->sb_timeo
.tv_usec
/ tick
;
65 if (sbi
->sbi_timeo
== 0 && sb
->sb_timeo
.tv_usec
!= 0) {
71 fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
)
73 si
->soi_so
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
);
74 si
->soi_type
= so
->so_type
;
75 si
->soi_options
= (short)(so
->so_options
& 0xffff);
76 si
->soi_linger
= so
->so_linger
;
77 si
->soi_state
= so
->so_state
;
78 si
->soi_pcb
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
->so_pcb
);
80 si
->soi_protocol
= SOCK_PROTO(so
);
81 if (so
->so_proto
->pr_domain
) {
82 si
->soi_family
= SOCK_DOM(so
);
87 si
->soi_protocol
= si
->soi_family
= 0;
89 si
->soi_qlen
= so
->so_qlen
;
90 si
->soi_incqlen
= so
->so_incqlen
;
91 si
->soi_qlimit
= so
->so_qlimit
;
92 si
->soi_timeo
= so
->so_timeo
;
93 si
->soi_error
= so
->so_error
;
94 si
->soi_oobmark
= so
->so_oobmark
;
95 fill_sockbuf_info(&so
->so_snd
, &si
->soi_snd
);
96 fill_sockbuf_info(&so
->so_rcv
, &si
->soi_rcv
);
100 fill_socketinfo(struct socket
*so
, struct socket_info
*si
)
109 si
->soi_kind
= SOCKINFO_GENERIC
;
111 fill_common_sockinfo(so
, si
);
113 if (so
->so_pcb
== NULL
|| so
->so_proto
== 0 ||
114 so
->so_proto
->pr_domain
== NULL
) {
119 * The kind of socket is determined by the triplet
120 * {domain, type, protocol}
122 domain
= SOCK_DOM(so
);
123 type
= SOCK_TYPE(so
);
124 protocol
= SOCK_PROTO(so
);
128 struct in_sockinfo
*insi
= &si
->soi_proto
.pri_in
;
129 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
131 si
->soi_kind
= SOCKINFO_IN
;
133 insi
->insi_fport
= inp
->inp_fport
;
134 insi
->insi_lport
= inp
->inp_lport
;
135 insi
->insi_gencnt
= inp
->inp_gencnt
;
136 insi
->insi_flags
= inp
->inp_flags
;
137 insi
->insi_vflag
= inp
->inp_vflag
;
138 insi
->insi_ip_ttl
= inp
->inp_ip_ttl
;
139 insi
->insi_faddr
.ina_6
= inp
->inp_dependfaddr
.inp6_foreign
;
140 insi
->insi_laddr
.ina_6
= inp
->inp_dependladdr
.inp6_local
;
141 insi
->insi_v4
.in4_tos
= inp
->inp_depend4
.inp4_ip_tos
;
142 insi
->insi_v6
.in6_hlim
= 0;
143 insi
->insi_v6
.in6_cksum
= inp
->inp_depend6
.inp6_cksum
;
144 insi
->insi_v6
.in6_ifindex
= 0;
145 insi
->insi_v6
.in6_hops
= inp
->inp_depend6
.inp6_hops
;
147 if (type
== SOCK_STREAM
&& (protocol
== 0 ||
148 protocol
== IPPROTO_TCP
) && inp
->inp_ppcb
!= NULL
) {
149 struct tcp_sockinfo
*tcpsi
= &si
->soi_proto
.pri_tcp
;
150 struct tcpcb
*tp
= (struct tcpcb
*)inp
->inp_ppcb
;
152 si
->soi_kind
= SOCKINFO_TCP
;
154 tcpsi
->tcpsi_state
= tp
->t_state
;
155 tcpsi
->tcpsi_timer
[TSI_T_REXMT
] =
156 tp
->t_timer
[TCPT_REXMT
];
157 tcpsi
->tcpsi_timer
[TSI_T_PERSIST
] =
158 tp
->t_timer
[TCPT_PERSIST
];
159 tcpsi
->tcpsi_timer
[TSI_T_KEEP
] =
160 tp
->t_timer
[TCPT_KEEP
];
161 tcpsi
->tcpsi_timer
[TSI_T_2MSL
] =
162 tp
->t_timer
[TCPT_2MSL
];
163 tcpsi
->tcpsi_mss
= tp
->t_maxseg
;
164 tcpsi
->tcpsi_flags
= tp
->t_flags
;
166 (u_int64_t
)VM_KERNEL_ADDRPERM(tp
);
171 struct unpcb
*unp
= (struct unpcb
*)so
->so_pcb
;
172 struct un_sockinfo
*unsi
= &si
->soi_proto
.pri_un
;
174 si
->soi_kind
= SOCKINFO_UN
;
176 unsi
->unsi_conn_pcb
=
177 (uint64_t)VM_KERNEL_ADDRPERM(unp
->unp_conn
);
179 unsi
->unsi_conn_so
= (uint64_t)
180 VM_KERNEL_ADDRPERM(unp
->unp_conn
->unp_socket
);
184 size_t addrlen
= unp
->unp_addr
->sun_len
;
186 if (addrlen
> SOCK_MAXADDRLEN
) {
187 addrlen
= SOCK_MAXADDRLEN
;
189 bcopy(unp
->unp_addr
, &unsi
->unsi_addr
, addrlen
);
191 if (unp
->unp_conn
&& unp
->unp_conn
->unp_addr
) {
192 size_t addrlen
= unp
->unp_conn
->unp_addr
->sun_len
;
194 if (addrlen
> SOCK_MAXADDRLEN
) {
195 addrlen
= SOCK_MAXADDRLEN
;
197 bcopy(unp
->unp_conn
->unp_addr
, &unsi
->unsi_caddr
,
203 struct ndrv_cb
*ndrv_cb
= (struct ndrv_cb
*)so
->so_pcb
;
204 struct ndrv_info
*ndrvsi
= &si
->soi_proto
.pri_ndrv
;
206 si
->soi_kind
= SOCKINFO_NDRV
;
208 /* TDB lock ifnet ???? */
209 if (ndrv_cb
->nd_if
!= 0) {
210 struct ifnet
*ifp
= ndrv_cb
->nd_if
;
212 ndrvsi
->ndrvsi_if_family
= ifp
->if_family
;
213 ndrvsi
->ndrvsi_if_unit
= ifp
->if_unit
;
214 strlcpy(ndrvsi
->ndrvsi_if_name
, ifp
->if_name
, IFNAMSIZ
);
219 if (SOCK_PROTO(so
) == SYSPROTO_EVENT
) {
220 struct kern_event_pcb
*ev_pcb
=
221 (struct kern_event_pcb
*)so
->so_pcb
;
222 struct kern_event_info
*kesi
=
223 &si
->soi_proto
.pri_kern_event
;
225 si
->soi_kind
= SOCKINFO_KERN_EVENT
;
227 kesi
->kesi_vendor_code_filter
=
228 ev_pcb
->evp_vendor_code_filter
;
229 kesi
->kesi_class_filter
= ev_pcb
->evp_class_filter
;
230 kesi
->kesi_subclass_filter
= ev_pcb
->evp_subclass_filter
;
231 } else if (SOCK_PROTO(so
) == SYSPROTO_CONTROL
) {
232 kctl_fill_socketinfo(so
, si
);
242 socket_unlock(so
, 0);