]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/socket_info.c
2 * Copyright (c) 2005-2013 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)
70 fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
)
72 si
->soi_so
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
);
73 si
->soi_type
= so
->so_type
;
74 si
->soi_options
= (short)(so
->so_options
& 0xffff);
75 si
->soi_linger
= so
->so_linger
;
76 si
->soi_state
= so
->so_state
;
77 si
->soi_pcb
= (u_int64_t
)VM_KERNEL_ADDRPERM(so
->so_pcb
);
79 si
->soi_protocol
= SOCK_PROTO(so
);
80 if (so
->so_proto
->pr_domain
)
81 si
->soi_family
= SOCK_DOM(so
);
85 si
->soi_protocol
= si
->soi_family
= 0;
87 si
->soi_qlen
= so
->so_qlen
;
88 si
->soi_incqlen
= so
->so_incqlen
;
89 si
->soi_qlimit
= so
->so_qlimit
;
90 si
->soi_timeo
= so
->so_timeo
;
91 si
->soi_error
= so
->so_error
;
92 si
->soi_oobmark
= so
->so_oobmark
;
93 fill_sockbuf_info(&so
->so_snd
, &si
->soi_snd
);
94 fill_sockbuf_info(&so
->so_rcv
, &si
->soi_rcv
);
98 fill_socketinfo(struct socket
*so
, struct socket_info
*si
)
107 si
->soi_kind
= SOCKINFO_GENERIC
;
109 fill_common_sockinfo(so
, si
);
111 if (so
->so_pcb
== NULL
|| so
->so_proto
== 0 ||
112 so
->so_proto
->pr_domain
== NULL
)
116 * The kind of socket is determined by the triplet
117 * {domain, type, protocol}
119 domain
= SOCK_DOM(so
);
120 type
= SOCK_TYPE(so
);
121 protocol
= SOCK_PROTO(so
);
125 struct in_sockinfo
*insi
= &si
->soi_proto
.pri_in
;
126 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
128 si
->soi_kind
= SOCKINFO_IN
;
130 insi
->insi_fport
= inp
->inp_fport
;
131 insi
->insi_lport
= inp
->inp_lport
;
132 insi
->insi_gencnt
= inp
->inp_gencnt
;
133 insi
->insi_flags
= inp
->inp_flags
;
134 insi
->insi_vflag
= inp
->inp_vflag
;
135 insi
->insi_ip_ttl
= inp
->inp_ip_ttl
;
136 insi
->insi_faddr
.ina_6
= inp
->inp_dependfaddr
.inp6_foreign
;
137 insi
->insi_laddr
.ina_6
= inp
->inp_dependladdr
.inp6_local
;
138 insi
->insi_v4
.in4_tos
= inp
->inp_depend4
.inp4_ip_tos
;
139 insi
->insi_v6
.in6_hlim
= 0;
140 insi
->insi_v6
.in6_cksum
= inp
->inp_depend6
.inp6_cksum
;
141 insi
->insi_v6
.in6_ifindex
= 0;
142 insi
->insi_v6
.in6_hops
= inp
->inp_depend6
.inp6_hops
;
144 if (type
== SOCK_STREAM
&& (protocol
== 0 ||
145 protocol
== IPPROTO_TCP
) && inp
->inp_ppcb
!= NULL
) {
146 struct tcp_sockinfo
*tcpsi
= &si
->soi_proto
.pri_tcp
;
147 struct tcpcb
*tp
= (struct tcpcb
*)inp
->inp_ppcb
;
149 si
->soi_kind
= SOCKINFO_TCP
;
151 tcpsi
->tcpsi_state
= tp
->t_state
;
152 tcpsi
->tcpsi_timer
[TCPT_REXMT
] =
153 tp
->t_timer
[TCPT_REXMT
];
154 tcpsi
->tcpsi_timer
[TCPT_PERSIST
] =
155 tp
->t_timer
[TCPT_PERSIST
];
156 tcpsi
->tcpsi_timer
[TCPT_KEEP
] = tp
->t_timer
[TCPT_KEEP
];
157 tcpsi
->tcpsi_timer
[TCPT_2MSL
] = tp
->t_timer
[TCPT_2MSL
];
158 tcpsi
->tcpsi_mss
= tp
->t_maxseg
;
159 tcpsi
->tcpsi_flags
= tp
->t_flags
;
161 (u_int64_t
)VM_KERNEL_ADDRPERM(tp
);
166 struct unpcb
*unp
= (struct unpcb
*)so
->so_pcb
;
167 struct un_sockinfo
*unsi
= &si
->soi_proto
.pri_un
;
169 si
->soi_kind
= SOCKINFO_UN
;
171 unsi
->unsi_conn_pcb
=
172 (uint64_t)VM_KERNEL_ADDRPERM(unp
->unp_conn
);
174 unsi
->unsi_conn_so
= (uint64_t)
175 VM_KERNEL_ADDRPERM(unp
->unp_conn
->unp_socket
);
178 size_t addrlen
= unp
->unp_addr
->sun_len
;
180 if (addrlen
> SOCK_MAXADDRLEN
)
181 addrlen
= SOCK_MAXADDRLEN
;
182 bcopy(unp
->unp_addr
, &unsi
->unsi_addr
, addrlen
);
184 if (unp
->unp_conn
&& unp
->unp_conn
->unp_addr
) {
185 size_t addrlen
= unp
->unp_conn
->unp_addr
->sun_len
;
187 if (addrlen
> SOCK_MAXADDRLEN
)
188 addrlen
= SOCK_MAXADDRLEN
;
189 bcopy(unp
->unp_conn
->unp_addr
, &unsi
->unsi_caddr
,
195 struct ndrv_cb
*ndrv_cb
= (struct ndrv_cb
*)so
->so_pcb
;
196 struct ndrv_info
*ndrvsi
= &si
->soi_proto
.pri_ndrv
;
198 si
->soi_kind
= SOCKINFO_NDRV
;
200 /* TDB lock ifnet ???? */
201 if (ndrv_cb
->nd_if
!= 0) {
202 struct ifnet
*ifp
= ndrv_cb
->nd_if
;
204 ndrvsi
->ndrvsi_if_family
= ifp
->if_family
;
205 ndrvsi
->ndrvsi_if_unit
= ifp
->if_unit
;
206 strlcpy(ndrvsi
->ndrvsi_if_name
, ifp
->if_name
, IFNAMSIZ
);
211 if (SOCK_PROTO(so
) == SYSPROTO_EVENT
) {
212 struct kern_event_pcb
*ev_pcb
=
213 (struct kern_event_pcb
*)so
->so_pcb
;
214 struct kern_event_info
*kesi
=
215 &si
->soi_proto
.pri_kern_event
;
217 si
->soi_kind
= SOCKINFO_KERN_EVENT
;
219 kesi
->kesi_vendor_code_filter
=
220 ev_pcb
->evp_vendor_code_filter
;
221 kesi
->kesi_class_filter
= ev_pcb
->evp_class_filter
;
222 kesi
->kesi_subclass_filter
= ev_pcb
->evp_subclass_filter
;
224 } else if (SOCK_PROTO(so
) == SYSPROTO_CONTROL
) {
225 struct ctl_cb
*kcb
= (struct ctl_cb
*)so
->so_pcb
;
226 struct kern_ctl_info
*kcsi
=
227 &si
->soi_proto
.pri_kern_ctl
;
228 struct kctl
*kctl
= kcb
->kctl
;
230 si
->soi_kind
= SOCKINFO_KERN_CTL
;
234 kcsi
->kcsi_id
= kctl
->id
;
235 kcsi
->kcsi_reg_unit
= kctl
->id
;
236 kcsi
->kcsi_flags
= kctl
->flags
;
237 kcsi
->kcsi_recvbufsize
= kctl
->recvbufsize
;
238 kcsi
->kcsi_sendbufsize
= kctl
->sendbufsize
;
239 kcsi
->kcsi_unit
= kcb
->unit
;
240 strlcpy(kcsi
->kcsi_name
, kctl
->name
, MAX_KCTL_NAME
);
250 socket_unlock(so
, 0);