]>
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
)