]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/socket_info.c
2 * Copyright (c) 2005-2006 Apple Computer, 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 <net/ndrv_var.h>
46 #include <netinet/in_pcb.h>
47 #include <netinet/tcp_var.h>
50 static void fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
);
51 static void fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
);
54 fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
)
56 sbi
->sbi_cc
= sb
->sb_cc
;
57 sbi
->sbi_hiwat
= sb
->sb_hiwat
;
58 sbi
->sbi_mbcnt
= sb
->sb_mbcnt
;
59 sbi
->sbi_mbmax
= sb
->sb_mbmax
;
60 sbi
->sbi_lowat
= sb
->sb_lowat
;
61 sbi
->sbi_flags
= sb
->sb_flags
;
62 sbi
->sbi_timeo
= (u_long
)(sb
->sb_timeo
.tv_sec
* hz
) + sb
->sb_timeo
.tv_usec
/ tick
;
63 if (sbi
->sbi_timeo
== 0 && sb
->sb_timeo
.tv_usec
!= 0)
68 fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
)
70 si
->soi_so
= (u_int64_t
)((uintptr_t)so
);
71 si
->soi_type
= so
->so_type
;
72 si
->soi_options
= so
->so_options
;
73 si
->soi_linger
= so
->so_linger
;
74 si
->soi_state
= so
->so_state
;
75 si
->soi_pcb
= (u_int64_t
)((uintptr_t)so
->so_pcb
);
77 si
->soi_protocol
= so
->so_proto
->pr_protocol
;
78 if (so
->so_proto
->pr_domain
)
79 si
->soi_family
= so
->so_proto
->pr_domain
->dom_family
;
83 si
->soi_protocol
= si
->soi_family
= 0;
84 si
->soi_qlen
= so
->so_qlen
;
85 si
->soi_incqlen
= so
->so_incqlen
;
86 si
->soi_qlimit
= so
->so_qlimit
;
87 si
->soi_timeo
= so
->so_timeo
;
88 si
->soi_error
= so
->so_error
;
89 si
->soi_oobmark
= so
->so_oobmark
;
90 fill_sockbuf_info(&so
->so_snd
, &si
->soi_snd
);
91 fill_sockbuf_info(&so
->so_rcv
, &si
->soi_rcv
);
96 fill_socketinfo(struct socket
*so
, struct socket_info
*si
)
105 si
->soi_kind
= SOCKINFO_GENERIC
;
107 fill_common_sockinfo(so
, si
);
109 if (so
->so_pcb
== 0 || so
->so_proto
== 0 || so
->so_proto
->pr_domain
== 0)
112 /* The kind of socket is determined by the triplet {family, type, protocol} */
113 family
= so
->so_proto
->pr_domain
->dom_family
;
114 type
= so
->so_proto
->pr_type
;
115 protocol
= so
->so_proto
->pr_protocol
;
119 struct in_sockinfo
*insi
= &si
->soi_proto
.pri_in
;
120 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
122 si
->soi_kind
= SOCKINFO_IN
;
124 insi
->insi_fport
= inp
->inp_fport
;
125 insi
->insi_lport
= inp
->inp_lport
;
126 insi
->insi_gencnt
= inp
->inp_gencnt
;
127 insi
->insi_flags
= inp
->inp_flags
;
128 insi
->insi_vflag
= inp
->inp_vflag
;
129 insi
->insi_ip_ttl
= inp
->inp_ip_ttl
;
130 insi
->insi_faddr
.ina_6
= inp
->inp_dependfaddr
.inp6_foreign
;
131 insi
->insi_laddr
.ina_6
= inp
->inp_dependladdr
.inp6_local
;
132 insi
->insi_v4
.in4_tos
= inp
->inp_depend4
.inp4_ip_tos
;
133 insi
->insi_v6
.in6_hlim
= inp
->inp_depend6
.inp6_hlim
;
134 insi
->insi_v6
.in6_cksum
= inp
->inp_depend6
.inp6_cksum
;
135 insi
->insi_v6
.in6_ifindex
= inp
->inp6_ifindex
;
136 insi
->insi_v6
.in6_hops
= inp
->inp_depend6
.inp6_hops
;
138 if (type
== SOCK_STREAM
&& (protocol
== 0 || protocol
== IPPROTO_TCP
) && inp
->inp_ppcb
!= 0) {
139 struct tcp_sockinfo
*tcpsi
= &si
->soi_proto
.pri_tcp
;
140 struct tcpcb
*tp
= (struct tcpcb
*)inp
->inp_ppcb
;
142 si
->soi_kind
= SOCKINFO_TCP
;
144 tcpsi
->tcpsi_state
= tp
->t_state
;
145 tcpsi
->tcpsi_timer
[TCPT_REXMT
] = tp
->t_timer
[TCPT_REXMT
];
146 tcpsi
->tcpsi_timer
[TCPT_PERSIST
] = tp
->t_timer
[TCPT_PERSIST
];
147 tcpsi
->tcpsi_timer
[TCPT_KEEP
] = tp
->t_timer
[TCPT_KEEP
];
148 tcpsi
->tcpsi_timer
[TCPT_2MSL
] = tp
->t_timer
[TCPT_2MSL
];
149 tcpsi
->tcpsi_mss
= tp
->t_maxseg
;
150 tcpsi
->tcpsi_flags
= tp
->t_flags
;
151 tcpsi
->tcpsi_tp
= (u_int64_t
)((uintptr_t)tp
);
156 struct unpcb
*unp
= (struct unpcb
*)so
->so_pcb
;
157 struct un_sockinfo
*unsi
= &si
->soi_proto
.pri_un
;
159 si
->soi_kind
= SOCKINFO_UN
;
161 unsi
->unsi_conn_pcb
= (uint64_t)((uintptr_t)unp
->unp_conn
);
163 unsi
->unsi_conn_so
= (uint64_t)((uintptr_t)unp
->unp_conn
->unp_socket
);
167 size_t addrlen
= unp
->unp_addr
->sun_len
;
169 if (addrlen
> SOCK_MAXADDRLEN
)
170 addrlen
= SOCK_MAXADDRLEN
;
171 bcopy(unp
->unp_addr
, &unsi
->unsi_addr
, addrlen
);
173 if (unp
->unp_conn
&& unp
->unp_conn
->unp_addr
) {
174 size_t addrlen
= unp
->unp_conn
->unp_addr
->sun_len
;
176 if (addrlen
> SOCK_MAXADDRLEN
)
177 addrlen
= SOCK_MAXADDRLEN
;
178 bcopy(unp
->unp_conn
->unp_addr
, &unsi
->unsi_caddr
, addrlen
);
183 struct ndrv_cb
*ndrv_cb
= (struct ndrv_cb
*)so
->so_pcb
;
184 struct ndrv_info
*ndrvsi
= &si
->soi_proto
.pri_ndrv
;
186 si
->soi_kind
= SOCKINFO_NDRV
;
188 /* TDB lock ifnet ???? */
189 if (ndrv_cb
->nd_if
!= 0) {
190 struct ifnet
*ifp
= ndrv_cb
->nd_if
;
192 ndrvsi
->ndrvsi_if_family
= ifp
->if_family
;
193 ndrvsi
->ndrvsi_if_unit
= ifp
->if_unit
;
194 strlcpy(ndrvsi
->ndrvsi_if_name
, ifp
->if_name
, IFNAMSIZ
);
200 if (so
->so_proto
->pr_protocol
== SYSPROTO_EVENT
) {
201 struct kern_event_pcb
*ev_pcb
= (struct kern_event_pcb
*)so
->so_pcb
;
202 struct kern_event_info
*kesi
= &si
->soi_proto
.pri_kern_event
;
204 si
->soi_kind
= SOCKINFO_KERN_EVENT
;
206 kesi
->kesi_vendor_code_filter
= ev_pcb
->vendor_code_filter
;
207 kesi
->kesi_class_filter
= ev_pcb
->class_filter
;
208 kesi
->kesi_subclass_filter
= ev_pcb
->subclass_filter
;
210 } else if (so
->so_proto
->pr_protocol
== SYSPROTO_CONTROL
) {
211 struct ctl_cb
*kcb
= (struct ctl_cb
*)so
->so_pcb
;
212 struct kern_ctl_info
*kcsi
= &si
->soi_proto
.pri_kern_ctl
;
213 struct kctl
*kctl
= kcb
->kctl
;
216 si
->soi_kind
= SOCKINFO_KERN_CTL
;
220 kcsi
->kcsi_id
= kctl
->id
;
221 kcsi
->kcsi_reg_unit
= kctl
->id
;
222 kcsi
->kcsi_flags
= kctl
->flags
;
223 kcsi
->kcsi_recvbufsize
= kctl
->recvbufsize
;
224 kcsi
->kcsi_sendbufsize
= kctl
->sendbufsize
;
225 kcsi
->kcsi_unit
= kcb
->unit
;
226 strlcpy(kcsi
->kcsi_name
, kctl
->name
, MAX_KCTL_NAME
);
243 socket_unlock(so
, 0);