]>
git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/mDNSMacOSXPuma.c
2 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 * This file is not normally used.
24 * It can be conditionally compiled in by defining RUN_ON_PUMA_WITHOUT_IFADDRS
25 * in mDNSMacOSX.c. It is included mainly as sample code for people building
26 * for other platforms that (like Puma) lack the getifaddrs() call.
27 * NOTE: YOU CANNOT use this code to build an mDNSResponder daemon for Puma
28 * that works just like the Jaguar one, because Puma lacks other necessary
29 * functionality (like the LibInfo support to receive MIG messages from clients).
31 Change History (most recent first):
33 $Log: mDNSMacOSXPuma.c,v $
34 Revision 1.5 2004/09/20 23:52:02 cheshire
35 CFSocket{Puma}.c renamed to mDNSMacOSX{Puma}.c
37 Revision 1.4 2003/08/12 19:56:25 cheshire
40 Revision 1.3 2003/07/02 21:19:51 cheshire
41 <rdar://problem/3313413> Update copyright notices, etc., in source code comments
43 Revision 1.2 2002/09/21 20:44:51 zarzycki
46 Revision 1.1 2002/09/17 01:36:23 cheshire
47 Move Puma support to mDNSMacOSXPuma.c
51 #include <sys/ioctl.h>
52 #include <sys/sockio.h>
53 #define ifaddrs ifa_info
55 #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
57 #include <sys/cdefs.h>
59 /* Our own header for the programs that need interface configuration info.
60 Include this file, instead of "unp.h". */
62 #define IFA_NAME 16 /* same as IFNAMSIZ in <net/if.h> */
63 #define IFA_HADDR 8 /* allow for 64-bit EUI-64 in future */
66 char ifa_name
[IFA_NAME
]; /* interface name, null terminated */
67 u_char ifa_haddr
[IFA_HADDR
]; /* hardware address */
68 u_short ifa_hlen
; /* #bytes in hardware address: 0, 6, 8 */
69 short ifa_flags
; /* IFF_xxx constants from <net/if.h> */
70 short ifa_myflags
; /* our own IFI_xxx flags */
71 struct sockaddr
*ifa_addr
; /* primary address */
72 struct sockaddr
*ifa_brdaddr
;/* broadcast address */
73 struct sockaddr
*ifa_dstaddr
;/* destination address */
74 struct ifa_info
*ifa_next
; /* next of these structures */
77 #define IFI_ALIAS 1 /* ifa_addr is an alias */
79 /* function prototypes */
80 struct ifa_info
*get_ifa_info(int, int);
81 struct ifa_info
*Get_ifa_info(int, int);
82 void free_ifa_info(struct ifa_info
*);
84 #define HAVE_SOCKADDR_SA_LEN 1
87 get_ifa_info(int family
, int doaliases
)
89 struct ifa_info
*ifi
, *ifihead
, **ifipnext
;
90 int sockfd
, len
, lastlen
, flags
, myflags
;
91 char *ptr
, *buf
, lastname
[IFNAMSIZ
], *cptr
;
93 struct ifreq
*ifr
, ifrcopy
;
94 struct sockaddr_in
*sinptr
;
96 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
99 len
= 100 * sizeof(struct ifreq
); /* initial buffer size guess */
101 buf
= (char *) malloc(len
);
104 if (ioctl(sockfd
, SIOCGIFCONF
, &ifc
) < 0) {
105 if (errno
!= EINVAL
|| lastlen
!= 0)
106 debugf("ioctl error");
108 if (ifc
.ifc_len
== lastlen
)
109 break; /* success, len has not changed */
110 lastlen
= ifc
.ifc_len
;
112 len
+= 10 * sizeof(struct ifreq
); /* increment */
118 /* end get_ifa_info1 */
120 /* include get_ifa_info2 */
121 for (ptr
= buf
; ptr
< buf
+ ifc
.ifc_len
; ) {
122 ifr
= (struct ifreq
*) ptr
;
124 #ifdef HAVE_SOCKADDR_SA_LEN
125 len
= MAX(sizeof(struct sockaddr
), ifr
->ifr_addr
.sa_len
);
127 switch (ifr
->ifr_addr
.sa_family
) {
130 len
= sizeof(struct sockaddr_in6
);
135 len
= sizeof(struct sockaddr
);
138 #endif /* HAVE_SOCKADDR_SA_LEN */
139 ptr
+= sizeof(ifr
->ifr_name
) + len
; /* for next one in buffer */
141 if (ifr
->ifr_addr
.sa_family
!= family
)
142 continue; /* ignore if not desired address family */
145 if ( (cptr
= strchr(ifr
->ifr_name
, ':')) != NULL
)
146 *cptr
= 0; /* replace colon will null */
147 if (strncmp(lastname
, ifr
->ifr_name
, IFNAMSIZ
) == 0) {
149 continue; /* already processed this interface */
152 memcpy(lastname
, ifr
->ifr_name
, IFNAMSIZ
);
155 ioctl(sockfd
, SIOCGIFFLAGS
, &ifrcopy
);
156 flags
= ifrcopy
.ifr_flags
;
157 if ((flags
& IFF_UP
) == 0)
158 continue; /* ignore if interface not up */
160 ifi
= (struct ifa_info
*) calloc(1, sizeof(struct ifa_info
));
161 *ifipnext
= ifi
; /* prev points to this new one */
162 ifipnext
= &ifi
->ifa_next
; /* pointer to next one goes here */
164 ifi
->ifa_flags
= flags
; /* IFF_xxx values */
165 ifi
->ifa_myflags
= myflags
; /* IFI_xxx values */
166 memcpy(ifi
->ifa_name
, ifr
->ifr_name
, IFA_NAME
);
167 ifi
->ifa_name
[IFA_NAME
-1] = '\0';
168 /* end get_ifa_info2 */
169 /* include get_ifa_info3 */
170 switch (ifr
->ifr_addr
.sa_family
) {
172 sinptr
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
173 if (ifi
->ifa_addr
== NULL
) {
174 ifi
->ifa_addr
= (struct sockaddr
*) calloc(1, sizeof(struct sockaddr_in
));
175 memcpy(ifi
->ifa_addr
, sinptr
, sizeof(struct sockaddr_in
));
177 #ifdef SIOCGIFBRDADDR
178 if (flags
& IFF_BROADCAST
) {
179 ioctl(sockfd
, SIOCGIFBRDADDR
, &ifrcopy
);
180 sinptr
= (struct sockaddr_in
*) &ifrcopy
.ifr_broadaddr
;
181 ifi
->ifa_brdaddr
= (struct sockaddr
*) calloc(1, sizeof(struct sockaddr_in
));
182 memcpy(ifi
->ifa_brdaddr
, sinptr
, sizeof(struct sockaddr_in
));
186 #ifdef SIOCGIFDSTADDR
187 if (flags
& IFF_POINTOPOINT
) {
188 ioctl(sockfd
, SIOCGIFDSTADDR
, &ifrcopy
);
189 sinptr
= (struct sockaddr_in
*) &ifrcopy
.ifr_dstaddr
;
190 ifi
->ifa_dstaddr
= (struct sockaddr
*) calloc(1, sizeof(struct sockaddr_in
));
191 memcpy(ifi
->ifa_dstaddr
, sinptr
, sizeof(struct sockaddr_in
));
202 return(ifihead
); /* pointer to first structure in linked list */
204 /* end get_ifa_info3 */
206 /* include free_ifa_info */
207 mDNSlocal
void freeifaddrs(struct ifa_info
*ifihead
)
209 struct ifa_info
*ifi
, *ifinext
;
211 for (ifi
= ifihead
; ifi
!= NULL
; ifi
= ifinext
) {
212 if (ifi
->ifa_addr
!= NULL
)
214 if (ifi
->ifa_brdaddr
!= NULL
)
215 free(ifi
->ifa_brdaddr
);
216 if (ifi
->ifa_dstaddr
!= NULL
)
217 free(ifi
->ifa_dstaddr
);
218 ifinext
= ifi
->ifa_next
; /* can't fetch ifa_next after free() */
219 free(ifi
); /* the ifa_info{} itself */
222 /* end free_ifa_info */
225 Get_ifa_info(int family
, int doaliases
)
227 struct ifa_info
*ifi
;
229 if ( (ifi
= get_ifa_info(family
, doaliases
)) == NULL
)
230 debugf("get_ifa_info error");
234 mDNSlocal
int getifaddrs(struct ifa_info
**ifalist
)
236 *ifalist
= get_ifa_info(PF_INET
, false);