]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/socket_info.c
179f951040720af3b5bb8ab0ce0ccaa35221139d
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/types.h>
24 #include <sys/kernel_types.h>
25 #include <sys/errno.h>
26 #include <sys/kernel.h>
27 #include <sys/file_internal.h>
29 #include <sys/select.h>
31 #include <sys/proc_info.h>
32 #include <sys/domain.h>
33 #include <sys/protosw.h>
34 #include <sys/domain.h>
35 #include <sys/socketvar.h>
36 #include <sys/unpcb.h>
37 #include <sys/sys_domain.h>
38 #include <sys/kern_event.h>
39 #include <net/ndrv_var.h>
40 #include <netinet/in_pcb.h>
41 #include <netinet/tcp_var.h>
44 static void fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
);
45 static void fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
);
48 fill_sockbuf_info(struct sockbuf
*sb
, struct sockbuf_info
*sbi
)
50 sbi
->sbi_cc
= sb
->sb_cc
;
51 sbi
->sbi_hiwat
= sb
->sb_hiwat
;
52 sbi
->sbi_mbcnt
= sb
->sb_mbcnt
;
53 sbi
->sbi_mbmax
= sb
->sb_mbmax
;
54 sbi
->sbi_lowat
= sb
->sb_lowat
;
55 sbi
->sbi_flags
= sb
->sb_flags
;
56 sbi
->sbi_timeo
= (u_long
)(sb
->sb_timeo
.tv_sec
* hz
) + sb
->sb_timeo
.tv_usec
/ tick
;
57 if (sbi
->sbi_timeo
== 0 && sb
->sb_timeo
.tv_usec
!= 0)
62 fill_common_sockinfo(struct socket
*so
, struct socket_info
*si
)
64 si
->soi_so
= (u_int64_t
)((uintptr_t)so
);
65 si
->soi_type
= so
->so_type
;
66 si
->soi_options
= so
->so_options
;
67 si
->soi_linger
= so
->so_linger
;
68 si
->soi_state
= so
->so_state
;
69 si
->soi_pcb
= (u_int64_t
)((uintptr_t)so
->so_pcb
);
71 si
->soi_protocol
= so
->so_proto
->pr_protocol
;
72 if (so
->so_proto
->pr_domain
)
73 si
->soi_family
= so
->so_proto
->pr_domain
->dom_family
;
77 si
->soi_protocol
= si
->soi_family
= 0;
78 si
->soi_qlen
= so
->so_qlen
;
79 si
->soi_incqlen
= so
->so_incqlen
;
80 si
->soi_qlimit
= so
->so_qlimit
;
81 si
->soi_timeo
= so
->so_timeo
;
82 si
->soi_error
= so
->so_error
;
83 si
->soi_oobmark
= so
->so_oobmark
;
84 fill_sockbuf_info(&so
->so_snd
, &si
->soi_snd
);
85 fill_sockbuf_info(&so
->so_rcv
, &si
->soi_rcv
);
90 fill_socketinfo(struct socket
*so
, struct socket_info
*si
)
99 si
->soi_kind
= SOCKINFO_GENERIC
;
101 fill_common_sockinfo(so
, si
);
103 if (so
->so_pcb
== 0 || so
->so_proto
== 0 || so
->so_proto
->pr_domain
== 0)
106 /* The kind of socket is determined by the triplet {family, type, protocol} */
107 family
= so
->so_proto
->pr_domain
->dom_family
;
108 type
= so
->so_proto
->pr_type
;
109 protocol
= so
->so_proto
->pr_protocol
;
113 struct in_sockinfo
*insi
= &si
->soi_proto
.pri_in
;
114 struct inpcb
*inp
= (struct inpcb
*)so
->so_pcb
;
116 si
->soi_kind
= SOCKINFO_IN
;
118 insi
->insi_fport
= inp
->inp_fport
;
119 insi
->insi_lport
= inp
->inp_lport
;
120 insi
->insi_gencnt
= inp
->inp_gencnt
;
121 insi
->insi_flags
= inp
->inp_flags
;
122 insi
->insi_vflag
= inp
->inp_vflag
;
123 insi
->insi_ip_ttl
= inp
->inp_ip_ttl
;
124 insi
->insi_faddr
.ina_6
= inp
->inp_dependfaddr
.inp6_foreign
;
125 insi
->insi_laddr
.ina_6
= inp
->inp_dependladdr
.inp6_local
;
126 insi
->insi_v4
.in4_tos
= inp
->inp_depend4
.inp4_ip_tos
;
127 insi
->insi_v6
.in6_hlim
= inp
->inp_depend6
.inp6_hlim
;
128 insi
->insi_v6
.in6_cksum
= inp
->inp_depend6
.inp6_cksum
;
129 insi
->insi_v6
.in6_ifindex
= inp
->inp6_ifindex
;
130 insi
->insi_v6
.in6_hops
= inp
->inp_depend6
.inp6_hops
;
132 if (type
== SOCK_STREAM
&& (protocol
== 0 || protocol
== IPPROTO_TCP
) && inp
->inp_ppcb
!= 0) {
133 struct tcp_sockinfo
*tcpsi
= &si
->soi_proto
.pri_tcp
;
134 struct tcpcb
*tp
= (struct tcpcb
*)inp
->inp_ppcb
;
136 si
->soi_kind
= SOCKINFO_TCP
;
138 tcpsi
->tcpsi_state
= tp
->t_state
;
139 tcpsi
->tcpsi_timer
[TCPT_REXMT
] = tp
->t_timer
[TCPT_REXMT
];
140 tcpsi
->tcpsi_timer
[TCPT_PERSIST
] = tp
->t_timer
[TCPT_PERSIST
];
141 tcpsi
->tcpsi_timer
[TCPT_KEEP
] = tp
->t_timer
[TCPT_KEEP
];
142 tcpsi
->tcpsi_timer
[TCPT_2MSL
] = tp
->t_timer
[TCPT_2MSL
];
143 tcpsi
->tcpsi_mss
= tp
->t_maxseg
;
144 tcpsi
->tcpsi_flags
= tp
->t_flags
;
145 tcpsi
->tcpsi_tp
= (u_int64_t
)((uintptr_t)tp
);
150 struct unpcb
*unp
= (struct unpcb
*)so
->so_pcb
;
151 struct un_sockinfo
*unsi
= &si
->soi_proto
.pri_un
;
153 si
->soi_kind
= SOCKINFO_UN
;
155 unsi
->unsi_conn_pcb
= (uint64_t)((uintptr_t)unp
->unp_conn
);
157 unsi
->unsi_conn_so
= (uint64_t)((uintptr_t)unp
->unp_conn
->unp_socket
);
161 size_t addrlen
= unp
->unp_addr
->sun_len
;
163 if (addrlen
> SOCK_MAXADDRLEN
)
164 addrlen
= SOCK_MAXADDRLEN
;
165 bcopy(unp
->unp_addr
, &unsi
->unsi_addr
, addrlen
);
167 if (unp
->unp_conn
&& unp
->unp_conn
->unp_addr
) {
168 size_t addrlen
= unp
->unp_conn
->unp_addr
->sun_len
;
170 if (addrlen
> SOCK_MAXADDRLEN
)
171 addrlen
= SOCK_MAXADDRLEN
;
172 bcopy(unp
->unp_conn
->unp_addr
, &unsi
->unsi_caddr
, addrlen
);
177 struct ndrv_cb
*ndrv_cb
= (struct ndrv_cb
*)so
->so_pcb
;
178 struct ndrv_info
*ndrvsi
= &si
->soi_proto
.pri_ndrv
;
180 si
->soi_kind
= SOCKINFO_NDRV
;
182 /* TDB lock ifnet ???? */
183 if (ndrv_cb
->nd_if
!= 0) {
184 struct ifnet
*ifp
= ndrv_cb
->nd_if
;
186 ndrvsi
->ndrvsi_if_family
= ifp
->if_family
;
187 ndrvsi
->ndrvsi_if_unit
= ifp
->if_unit
;
188 strncpy(ndrvsi
->ndrvsi_if_name
, ifp
->if_name
, IFNAMSIZ
);
194 if (so
->so_proto
->pr_protocol
== SYSPROTO_EVENT
) {
195 struct kern_event_pcb
*ev_pcb
= (struct kern_event_pcb
*)so
->so_pcb
;
196 struct kern_event_info
*kesi
= &si
->soi_proto
.pri_kern_event
;
198 si
->soi_kind
= SOCKINFO_KERN_EVENT
;
200 kesi
->kesi_vendor_code_filter
= ev_pcb
->vendor_code_filter
;
201 kesi
->kesi_class_filter
= ev_pcb
->class_filter
;
202 kesi
->kesi_subclass_filter
= ev_pcb
->subclass_filter
;
204 } else if (so
->so_proto
->pr_protocol
== SYSPROTO_CONTROL
) {
205 struct ctl_cb
*kcb
= (struct ctl_cb
*)so
->so_pcb
;
206 struct kern_ctl_info
*kcsi
= &si
->soi_proto
.pri_kern_ctl
;
207 struct kctl
*kctl
= kcb
->kctl
;
210 si
->soi_kind
= SOCKINFO_KERN_CTL
;
214 kcsi
->kcsi_id
= kctl
->id
;
215 kcsi
->kcsi_reg_unit
= kctl
->id
;
216 kcsi
->kcsi_flags
= kctl
->flags
;
217 kcsi
->kcsi_recvbufsize
= kctl
->recvbufsize
;
218 kcsi
->kcsi_sendbufsize
= kctl
->sendbufsize
;
219 kcsi
->kcsi_unit
= kcb
->unit
;
220 strncpy(kcsi
->kcsi_name
, kctl
->name
, MAX_KCTL_NAME
);
237 socket_unlock(so
, 0);