]>
git.saurik.com Git - apple/libinfo.git/blob - gen.subproj/getifmaddrs.c
2 * Copyright (c) 2003 Bruce M. Simpson.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bruce M. Simpson.
16 * 4. Neither the name of Bruce M. Simpson nor the names of other
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY BRUCE M. SIMPSON AND AFFILIATES
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRUCE M. SIMPSON OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 #include <sys/param.h>
35 #include <sys/sysctl.h>
36 #include <sys/ioctl.h>
37 #include <sys/socket.h>
39 #include <net/if_dl.h>
40 #include <net/route.h>
47 #define SALIGN (sizeof(uint32_t) - 1)
48 #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \
50 #define MAX_SYSCTL_TRY 5
51 #define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA)
53 /* FreeBSD uses NET_RT_IFMALIST and RTM_NEWMADDR from <sys/socket.h> */
54 /* We can use NET_RT_IFLIST2 and RTM_NEWMADDR2 on Darwin */
58 #define GIM_SYSCTL_MIB NET_RT_IFLIST2
59 #define GIM_RTM_ADDR RTM_NEWMADDR2
61 #define GIM_SYSCTL_MIB NET_RT_IFMALIST
62 #define GIM_RTM_ADDR RTM_NEWMADDR
66 getifmaddrs(struct ifmaddrs
**pif
)
79 struct ifma_msghdr2
*ifmam
;
80 struct ifmaddrs
*ifa
, *ift
;
81 struct rt_msghdr
*rtm
;
86 mib
[2] = 0; /* protocol */
87 mib
[3] = 0; /* wildcard address family */
88 mib
[4] = GIM_SYSCTL_MIB
;
89 mib
[5] = 0; /* no flags */
91 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
93 if ((buf
= malloc(needed
)) == NULL
)
95 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0) {
96 if (errno
!= ENOMEM
|| ++ntry
>= MAX_SYSCTL_TRY
) {
103 } while (buf
== NULL
);
105 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
106 rtm
= (struct rt_msghdr
*)(void *)next
;
107 if (rtm
->rtm_version
!= RTM_VERSION
)
109 switch (rtm
->rtm_type
) {
111 ifmam
= (struct ifma_msghdr2
*)(void *)rtm
;
112 if ((ifmam
->ifmam_addrs
& RTA_IFA
) == 0)
115 p
= (char *)(ifmam
+ 1);
116 for (i
= 0; i
< RTAX_MAX
; i
++) {
117 if ((RTA_MASKS
& ifmam
->ifmam_addrs
&
120 sa
= (struct sockaddr
*)(void *)p
;
129 data
= malloc(sizeof(struct ifmaddrs
) * icnt
+ dcnt
);
135 ifa
= (struct ifmaddrs
*)(void *)data
;
136 data
+= sizeof(struct ifmaddrs
) * icnt
;
138 memset(ifa
, 0, sizeof(struct ifmaddrs
) * icnt
);
141 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
142 rtm
= (struct rt_msghdr
*)(void *)next
;
143 if (rtm
->rtm_version
!= RTM_VERSION
)
146 switch (rtm
->rtm_type
) {
148 ifmam
= (struct ifma_msghdr2
*)(void *)rtm
;
149 if ((ifmam
->ifmam_addrs
& RTA_IFA
) == 0)
152 p
= (char *)(ifmam
+ 1);
153 for (i
= 0; i
< RTAX_MAX
; i
++) {
154 if ((RTA_MASKS
& ifmam
->ifmam_addrs
&
157 sa
= (struct sockaddr
*)(void *)p
;
162 (struct sockaddr
*)(void *)data
;
163 memcpy(data
, p
, len
);
169 (struct sockaddr
*)(void *)data
;
170 memcpy(data
, p
, len
);
176 (struct sockaddr
*)(void *)data
;
177 memcpy(data
, p
, len
);
187 ift
->ifma_next
= ift
+ 1;
188 ift
= ift
->ifma_next
;
197 ift
->ifma_next
= NULL
;
207 freeifmaddrs(struct ifmaddrs
*ifmp
)