1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker *
3*48a54d36SAndroid Build Coastguard Worker * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker *
5*48a54d36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker *
9*48a54d36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker *
11*48a54d36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker */
17*48a54d36SAndroid Build Coastguard Worker
18*48a54d36SAndroid Build Coastguard Worker #include "mDNSUNP.h"
19*48a54d36SAndroid Build Coastguard Worker
20*48a54d36SAndroid Build Coastguard Worker #include <errno.h>
21*48a54d36SAndroid Build Coastguard Worker #include <assert.h>
22*48a54d36SAndroid Build Coastguard Worker #include <string.h>
23*48a54d36SAndroid Build Coastguard Worker #include <stdlib.h>
24*48a54d36SAndroid Build Coastguard Worker #include <sys/uio.h>
25*48a54d36SAndroid Build Coastguard Worker #include <sys/ioctl.h>
26*48a54d36SAndroid Build Coastguard Worker #include <signal.h>
27*48a54d36SAndroid Build Coastguard Worker #include <unistd.h>
28*48a54d36SAndroid Build Coastguard Worker #include <stdio.h>
29*48a54d36SAndroid Build Coastguard Worker
30*48a54d36SAndroid Build Coastguard Worker /* Some weird platforms derived from 4.4BSD Lite (e.g. EFI) need the ALIGN(P)
31*48a54d36SAndroid Build Coastguard Worker macro, usually defined in <sys/param.h> or someplace like that, to make sure the
32*48a54d36SAndroid Build Coastguard Worker CMSG_NXTHDR macro is well-formed. On such platforms, the symbol NEED_ALIGN_MACRO
33*48a54d36SAndroid Build Coastguard Worker should be set to the name of the header to include to get the ALIGN(P) macro.
34*48a54d36SAndroid Build Coastguard Worker */
35*48a54d36SAndroid Build Coastguard Worker #ifdef NEED_ALIGN_MACRO
36*48a54d36SAndroid Build Coastguard Worker #include NEED_ALIGN_MACRO
37*48a54d36SAndroid Build Coastguard Worker #endif
38*48a54d36SAndroid Build Coastguard Worker
39*48a54d36SAndroid Build Coastguard Worker /* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
40*48a54d36SAndroid Build Coastguard Worker other platforms don't even have that include file. So,
41*48a54d36SAndroid Build Coastguard Worker if we haven't yet got a definition, let's try to find
42*48a54d36SAndroid Build Coastguard Worker <sys/sockio.h>.
43*48a54d36SAndroid Build Coastguard Worker */
44*48a54d36SAndroid Build Coastguard Worker
45*48a54d36SAndroid Build Coastguard Worker #ifndef SIOCGIFCONF
46*48a54d36SAndroid Build Coastguard Worker #include <sys/sockio.h>
47*48a54d36SAndroid Build Coastguard Worker #endif
48*48a54d36SAndroid Build Coastguard Worker
49*48a54d36SAndroid Build Coastguard Worker /* sockaddr_dl is only referenced if we're using IP_RECVIF,
50*48a54d36SAndroid Build Coastguard Worker so only include the header in that case.
51*48a54d36SAndroid Build Coastguard Worker */
52*48a54d36SAndroid Build Coastguard Worker
53*48a54d36SAndroid Build Coastguard Worker #ifdef IP_RECVIF
54*48a54d36SAndroid Build Coastguard Worker #include <net/if_dl.h>
55*48a54d36SAndroid Build Coastguard Worker #endif
56*48a54d36SAndroid Build Coastguard Worker
57*48a54d36SAndroid Build Coastguard Worker #if defined(AF_INET6) && HAVE_IPV6 && !HAVE_LINUX
58*48a54d36SAndroid Build Coastguard Worker #include <net/if_var.h>
59*48a54d36SAndroid Build Coastguard Worker #include <netinet/in_var.h>
60*48a54d36SAndroid Build Coastguard Worker // Note: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
61*48a54d36SAndroid Build Coastguard Worker #endif
62*48a54d36SAndroid Build Coastguard Worker
63*48a54d36SAndroid Build Coastguard Worker #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
64*48a54d36SAndroid Build Coastguard Worker #include <netdb.h>
65*48a54d36SAndroid Build Coastguard Worker #include <arpa/inet.h>
66*48a54d36SAndroid Build Coastguard Worker
67*48a54d36SAndroid Build Coastguard Worker /* Converts a prefix length to IPv6 network mask */
plen_to_mask(int plen,char * addr)68*48a54d36SAndroid Build Coastguard Worker void plen_to_mask(int plen, char *addr) {
69*48a54d36SAndroid Build Coastguard Worker int i;
70*48a54d36SAndroid Build Coastguard Worker int colons=7; /* Number of colons in IPv6 address */
71*48a54d36SAndroid Build Coastguard Worker int bits_in_block=16; /* Bits per IPv6 block */
72*48a54d36SAndroid Build Coastguard Worker for(i=0;i<=colons;i++) {
73*48a54d36SAndroid Build Coastguard Worker int block, ones=0xffff, ones_in_block;
74*48a54d36SAndroid Build Coastguard Worker if (plen>bits_in_block) ones_in_block=bits_in_block;
75*48a54d36SAndroid Build Coastguard Worker else ones_in_block=plen;
76*48a54d36SAndroid Build Coastguard Worker block = ones & (ones << (bits_in_block-ones_in_block));
77*48a54d36SAndroid Build Coastguard Worker i==0 ? sprintf(addr, "%x", block) : sprintf(addr, "%s:%x", addr, block);
78*48a54d36SAndroid Build Coastguard Worker plen -= ones_in_block;
79*48a54d36SAndroid Build Coastguard Worker }
80*48a54d36SAndroid Build Coastguard Worker }
81*48a54d36SAndroid Build Coastguard Worker
82*48a54d36SAndroid Build Coastguard Worker /* Gets IPv6 interface information from the /proc filesystem in linux*/
get_ifi_info_linuxv6(int family,int doaliases)83*48a54d36SAndroid Build Coastguard Worker struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
84*48a54d36SAndroid Build Coastguard Worker {
85*48a54d36SAndroid Build Coastguard Worker struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
86*48a54d36SAndroid Build Coastguard Worker FILE *fp = NULL;
87*48a54d36SAndroid Build Coastguard Worker char addr[8][5];
88*48a54d36SAndroid Build Coastguard Worker int flags, myflags, index, plen, scope;
89*48a54d36SAndroid Build Coastguard Worker char ifname[IFNAMSIZ], lastname[IFNAMSIZ];
90*48a54d36SAndroid Build Coastguard Worker char addr6[32+7+1]; /* don't forget the seven ':' */
91*48a54d36SAndroid Build Coastguard Worker struct addrinfo hints, *res0;
92*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in6 *sin6;
93*48a54d36SAndroid Build Coastguard Worker struct in6_addr *addrptr;
94*48a54d36SAndroid Build Coastguard Worker int err;
95*48a54d36SAndroid Build Coastguard Worker int sockfd = -1;
96*48a54d36SAndroid Build Coastguard Worker struct ifreq ifr;
97*48a54d36SAndroid Build Coastguard Worker
98*48a54d36SAndroid Build Coastguard Worker res0=NULL;
99*48a54d36SAndroid Build Coastguard Worker ifihead = NULL;
100*48a54d36SAndroid Build Coastguard Worker ifipnext = &ifihead;
101*48a54d36SAndroid Build Coastguard Worker lastname[0] = 0;
102*48a54d36SAndroid Build Coastguard Worker
103*48a54d36SAndroid Build Coastguard Worker if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
104*48a54d36SAndroid Build Coastguard Worker sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
105*48a54d36SAndroid Build Coastguard Worker if (sockfd < 0) {
106*48a54d36SAndroid Build Coastguard Worker goto gotError;
107*48a54d36SAndroid Build Coastguard Worker }
108*48a54d36SAndroid Build Coastguard Worker while (fscanf(fp,
109*48a54d36SAndroid Build Coastguard Worker "%4s%4s%4s%4s%4s%4s%4s%4s %x %x %x %x %15s\n",
110*48a54d36SAndroid Build Coastguard Worker addr[0],addr[1],addr[2],addr[3],
111*48a54d36SAndroid Build Coastguard Worker addr[4],addr[5],addr[6],addr[7],
112*48a54d36SAndroid Build Coastguard Worker &index, &plen, &scope, &flags, ifname) != EOF) {
113*48a54d36SAndroid Build Coastguard Worker
114*48a54d36SAndroid Build Coastguard Worker myflags = 0;
115*48a54d36SAndroid Build Coastguard Worker if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
116*48a54d36SAndroid Build Coastguard Worker if (doaliases == 0)
117*48a54d36SAndroid Build Coastguard Worker continue; /* already processed this interface */
118*48a54d36SAndroid Build Coastguard Worker myflags = IFI_ALIAS;
119*48a54d36SAndroid Build Coastguard Worker }
120*48a54d36SAndroid Build Coastguard Worker strncpy(lastname, ifname, IFNAMSIZ);
121*48a54d36SAndroid Build Coastguard Worker ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
122*48a54d36SAndroid Build Coastguard Worker if (ifi == NULL) {
123*48a54d36SAndroid Build Coastguard Worker goto gotError;
124*48a54d36SAndroid Build Coastguard Worker }
125*48a54d36SAndroid Build Coastguard Worker
126*48a54d36SAndroid Build Coastguard Worker ifipold = *ifipnext; /* need this later */
127*48a54d36SAndroid Build Coastguard Worker ifiptr = ifipnext;
128*48a54d36SAndroid Build Coastguard Worker *ifipnext = ifi; /* prev points to this new one */
129*48a54d36SAndroid Build Coastguard Worker ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
130*48a54d36SAndroid Build Coastguard Worker
131*48a54d36SAndroid Build Coastguard Worker sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
132*48a54d36SAndroid Build Coastguard Worker addr[0],addr[1],addr[2],addr[3],
133*48a54d36SAndroid Build Coastguard Worker addr[4],addr[5],addr[6],addr[7]);
134*48a54d36SAndroid Build Coastguard Worker
135*48a54d36SAndroid Build Coastguard Worker /* Add address of the interface */
136*48a54d36SAndroid Build Coastguard Worker memset(&hints, 0, sizeof(hints));
137*48a54d36SAndroid Build Coastguard Worker hints.ai_family = AF_INET6;
138*48a54d36SAndroid Build Coastguard Worker hints.ai_flags = AI_NUMERICHOST;
139*48a54d36SAndroid Build Coastguard Worker err = getaddrinfo(addr6, NULL, &hints, &res0);
140*48a54d36SAndroid Build Coastguard Worker if (err) {
141*48a54d36SAndroid Build Coastguard Worker goto gotError;
142*48a54d36SAndroid Build Coastguard Worker }
143*48a54d36SAndroid Build Coastguard Worker ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
144*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
145*48a54d36SAndroid Build Coastguard Worker goto gotError;
146*48a54d36SAndroid Build Coastguard Worker }
147*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
148*48a54d36SAndroid Build Coastguard Worker
149*48a54d36SAndroid Build Coastguard Worker /* Add netmask of the interface */
150*48a54d36SAndroid Build Coastguard Worker char ipv6addr[INET6_ADDRSTRLEN];
151*48a54d36SAndroid Build Coastguard Worker plen_to_mask(plen, ipv6addr);
152*48a54d36SAndroid Build Coastguard Worker ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
153*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
154*48a54d36SAndroid Build Coastguard Worker goto gotError;
155*48a54d36SAndroid Build Coastguard Worker }
156*48a54d36SAndroid Build Coastguard Worker sin6=calloc(1, sizeof(struct sockaddr_in6));
157*48a54d36SAndroid Build Coastguard Worker addrptr=calloc(1, sizeof(struct in6_addr));
158*48a54d36SAndroid Build Coastguard Worker inet_pton(family, ipv6addr, addrptr);
159*48a54d36SAndroid Build Coastguard Worker sin6->sin6_family=family;
160*48a54d36SAndroid Build Coastguard Worker sin6->sin6_addr=*addrptr;
161*48a54d36SAndroid Build Coastguard Worker sin6->sin6_scope_id=scope;
162*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
163*48a54d36SAndroid Build Coastguard Worker free(sin6);
164*48a54d36SAndroid Build Coastguard Worker
165*48a54d36SAndroid Build Coastguard Worker
166*48a54d36SAndroid Build Coastguard Worker /* Add interface name */
167*48a54d36SAndroid Build Coastguard Worker strncpy(ifi->ifi_name, ifname, IFI_NAME);
168*48a54d36SAndroid Build Coastguard Worker
169*48a54d36SAndroid Build Coastguard Worker /* Add interface index */
170*48a54d36SAndroid Build Coastguard Worker ifi->ifi_index = index;
171*48a54d36SAndroid Build Coastguard Worker
172*48a54d36SAndroid Build Coastguard Worker /* Add interface flags*/
173*48a54d36SAndroid Build Coastguard Worker strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
174*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
175*48a54d36SAndroid Build Coastguard Worker if (errno == EADDRNOTAVAIL) {
176*48a54d36SAndroid Build Coastguard Worker /*
177*48a54d36SAndroid Build Coastguard Worker * If the main interface is configured with no IP address but
178*48a54d36SAndroid Build Coastguard Worker * an alias interface exists with an IP address, you get
179*48a54d36SAndroid Build Coastguard Worker * EADDRNOTAVAIL for the main interface
180*48a54d36SAndroid Build Coastguard Worker */
181*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_addr);
182*48a54d36SAndroid Build Coastguard Worker free(ifi);
183*48a54d36SAndroid Build Coastguard Worker ifipnext = ifiptr;
184*48a54d36SAndroid Build Coastguard Worker *ifipnext = ifipold;
185*48a54d36SAndroid Build Coastguard Worker continue;
186*48a54d36SAndroid Build Coastguard Worker } else {
187*48a54d36SAndroid Build Coastguard Worker goto gotError;
188*48a54d36SAndroid Build Coastguard Worker }
189*48a54d36SAndroid Build Coastguard Worker }
190*48a54d36SAndroid Build Coastguard Worker ifi->ifi_flags = ifr.ifr_flags;
191*48a54d36SAndroid Build Coastguard Worker freeaddrinfo(res0);
192*48a54d36SAndroid Build Coastguard Worker res0=NULL;
193*48a54d36SAndroid Build Coastguard Worker }
194*48a54d36SAndroid Build Coastguard Worker }
195*48a54d36SAndroid Build Coastguard Worker goto done;
196*48a54d36SAndroid Build Coastguard Worker
197*48a54d36SAndroid Build Coastguard Worker gotError:
198*48a54d36SAndroid Build Coastguard Worker if (ifihead != NULL) {
199*48a54d36SAndroid Build Coastguard Worker free_ifi_info(ifihead);
200*48a54d36SAndroid Build Coastguard Worker ifihead = NULL;
201*48a54d36SAndroid Build Coastguard Worker }
202*48a54d36SAndroid Build Coastguard Worker if (res0 != NULL) {
203*48a54d36SAndroid Build Coastguard Worker freeaddrinfo(res0);
204*48a54d36SAndroid Build Coastguard Worker res0=NULL;
205*48a54d36SAndroid Build Coastguard Worker }
206*48a54d36SAndroid Build Coastguard Worker done:
207*48a54d36SAndroid Build Coastguard Worker if (sockfd != -1) {
208*48a54d36SAndroid Build Coastguard Worker // __ANDROID__ : replaced assert(close(..))
209*48a54d36SAndroid Build Coastguard Worker int sockfd_closed = close(sockfd);
210*48a54d36SAndroid Build Coastguard Worker assert(sockfd_closed == 0);
211*48a54d36SAndroid Build Coastguard Worker }
212*48a54d36SAndroid Build Coastguard Worker // __ANDROID__ : if fp was opened, it needs to be closed
213*48a54d36SAndroid Build Coastguard Worker if (fp != NULL) {
214*48a54d36SAndroid Build Coastguard Worker int fd_closed = fclose(fp);
215*48a54d36SAndroid Build Coastguard Worker assert(fd_closed == 0);
216*48a54d36SAndroid Build Coastguard Worker }
217*48a54d36SAndroid Build Coastguard Worker return(ifihead); /* pointer to first structure in linked list */
218*48a54d36SAndroid Build Coastguard Worker }
219*48a54d36SAndroid Build Coastguard Worker #endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
220*48a54d36SAndroid Build Coastguard Worker
get_ifi_info(int family,int doaliases)221*48a54d36SAndroid Build Coastguard Worker struct ifi_info *get_ifi_info(int family, int doaliases)
222*48a54d36SAndroid Build Coastguard Worker {
223*48a54d36SAndroid Build Coastguard Worker int junk;
224*48a54d36SAndroid Build Coastguard Worker struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
225*48a54d36SAndroid Build Coastguard Worker int sockfd, sockf6, len, lastlen, flags, myflags;
226*48a54d36SAndroid Build Coastguard Worker #ifdef NOT_HAVE_IF_NAMETOINDEX
227*48a54d36SAndroid Build Coastguard Worker int index = 200;
228*48a54d36SAndroid Build Coastguard Worker #endif
229*48a54d36SAndroid Build Coastguard Worker char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
230*48a54d36SAndroid Build Coastguard Worker struct ifconf ifc;
231*48a54d36SAndroid Build Coastguard Worker struct ifreq *ifr, ifrcopy;
232*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in *sinptr;
233*48a54d36SAndroid Build Coastguard Worker
234*48a54d36SAndroid Build Coastguard Worker #if defined(AF_INET6) && HAVE_IPV6
235*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in6 *sinptr6;
236*48a54d36SAndroid Build Coastguard Worker #endif
237*48a54d36SAndroid Build Coastguard Worker
238*48a54d36SAndroid Build Coastguard Worker #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
239*48a54d36SAndroid Build Coastguard Worker if (family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
240*48a54d36SAndroid Build Coastguard Worker #endif
241*48a54d36SAndroid Build Coastguard Worker
242*48a54d36SAndroid Build Coastguard Worker sockfd = -1;
243*48a54d36SAndroid Build Coastguard Worker sockf6 = -1;
244*48a54d36SAndroid Build Coastguard Worker buf = NULL;
245*48a54d36SAndroid Build Coastguard Worker ifihead = NULL;
246*48a54d36SAndroid Build Coastguard Worker
247*48a54d36SAndroid Build Coastguard Worker sockfd = socket(AF_INET, SOCK_DGRAM, 0);
248*48a54d36SAndroid Build Coastguard Worker if (sockfd < 0) {
249*48a54d36SAndroid Build Coastguard Worker goto gotError;
250*48a54d36SAndroid Build Coastguard Worker }
251*48a54d36SAndroid Build Coastguard Worker
252*48a54d36SAndroid Build Coastguard Worker lastlen = 0;
253*48a54d36SAndroid Build Coastguard Worker len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
254*48a54d36SAndroid Build Coastguard Worker for ( ; ; ) {
255*48a54d36SAndroid Build Coastguard Worker buf = (char*)malloc(len);
256*48a54d36SAndroid Build Coastguard Worker if (buf == NULL) {
257*48a54d36SAndroid Build Coastguard Worker goto gotError;
258*48a54d36SAndroid Build Coastguard Worker }
259*48a54d36SAndroid Build Coastguard Worker ifc.ifc_len = len;
260*48a54d36SAndroid Build Coastguard Worker ifc.ifc_buf = buf;
261*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
262*48a54d36SAndroid Build Coastguard Worker if (errno != EINVAL || lastlen != 0) {
263*48a54d36SAndroid Build Coastguard Worker goto gotError;
264*48a54d36SAndroid Build Coastguard Worker }
265*48a54d36SAndroid Build Coastguard Worker } else {
266*48a54d36SAndroid Build Coastguard Worker if (ifc.ifc_len == lastlen)
267*48a54d36SAndroid Build Coastguard Worker break; /* success, len has not changed */
268*48a54d36SAndroid Build Coastguard Worker lastlen = ifc.ifc_len;
269*48a54d36SAndroid Build Coastguard Worker }
270*48a54d36SAndroid Build Coastguard Worker len += 10 * sizeof(struct ifreq); /* increment */
271*48a54d36SAndroid Build Coastguard Worker free(buf);
272*48a54d36SAndroid Build Coastguard Worker }
273*48a54d36SAndroid Build Coastguard Worker ifihead = NULL;
274*48a54d36SAndroid Build Coastguard Worker ifipnext = &ifihead;
275*48a54d36SAndroid Build Coastguard Worker lastname[0] = 0;
276*48a54d36SAndroid Build Coastguard Worker /* end get_ifi_info1 */
277*48a54d36SAndroid Build Coastguard Worker
278*48a54d36SAndroid Build Coastguard Worker /* include get_ifi_info2 */
279*48a54d36SAndroid Build Coastguard Worker for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
280*48a54d36SAndroid Build Coastguard Worker ifr = (struct ifreq *) ptr;
281*48a54d36SAndroid Build Coastguard Worker
282*48a54d36SAndroid Build Coastguard Worker /* Advance to next one in buffer */
283*48a54d36SAndroid Build Coastguard Worker if (sizeof(struct ifreq) > sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr))
284*48a54d36SAndroid Build Coastguard Worker ptr += sizeof(struct ifreq);
285*48a54d36SAndroid Build Coastguard Worker else
286*48a54d36SAndroid Build Coastguard Worker ptr += sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr);
287*48a54d36SAndroid Build Coastguard Worker
288*48a54d36SAndroid Build Coastguard Worker // fprintf(stderr, "intf %p name=%s AF=%d\n", index, ifr->ifr_name, ifr->ifr_addr.sa_family);
289*48a54d36SAndroid Build Coastguard Worker
290*48a54d36SAndroid Build Coastguard Worker if (ifr->ifr_addr.sa_family != family)
291*48a54d36SAndroid Build Coastguard Worker continue; /* ignore if not desired address family */
292*48a54d36SAndroid Build Coastguard Worker
293*48a54d36SAndroid Build Coastguard Worker myflags = 0;
294*48a54d36SAndroid Build Coastguard Worker if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)
295*48a54d36SAndroid Build Coastguard Worker *cptr = 0; /* replace colon will null */
296*48a54d36SAndroid Build Coastguard Worker if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
297*48a54d36SAndroid Build Coastguard Worker if (doaliases == 0)
298*48a54d36SAndroid Build Coastguard Worker continue; /* already processed this interface */
299*48a54d36SAndroid Build Coastguard Worker myflags = IFI_ALIAS;
300*48a54d36SAndroid Build Coastguard Worker }
301*48a54d36SAndroid Build Coastguard Worker memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
302*48a54d36SAndroid Build Coastguard Worker
303*48a54d36SAndroid Build Coastguard Worker ifrcopy = *ifr;
304*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
305*48a54d36SAndroid Build Coastguard Worker goto gotError;
306*48a54d36SAndroid Build Coastguard Worker }
307*48a54d36SAndroid Build Coastguard Worker
308*48a54d36SAndroid Build Coastguard Worker flags = ifrcopy.ifr_flags;
309*48a54d36SAndroid Build Coastguard Worker if ((flags & IFF_UP) == 0)
310*48a54d36SAndroid Build Coastguard Worker continue; /* ignore if interface not up */
311*48a54d36SAndroid Build Coastguard Worker
312*48a54d36SAndroid Build Coastguard Worker ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
313*48a54d36SAndroid Build Coastguard Worker if (ifi == NULL) {
314*48a54d36SAndroid Build Coastguard Worker goto gotError;
315*48a54d36SAndroid Build Coastguard Worker }
316*48a54d36SAndroid Build Coastguard Worker ifipold = *ifipnext; /* need this later */
317*48a54d36SAndroid Build Coastguard Worker ifiptr = ifipnext;
318*48a54d36SAndroid Build Coastguard Worker *ifipnext = ifi; /* prev points to this new one */
319*48a54d36SAndroid Build Coastguard Worker ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
320*48a54d36SAndroid Build Coastguard Worker
321*48a54d36SAndroid Build Coastguard Worker ifi->ifi_flags = flags; /* IFF_xxx values */
322*48a54d36SAndroid Build Coastguard Worker ifi->ifi_myflags = myflags; /* IFI_xxx values */
323*48a54d36SAndroid Build Coastguard Worker #ifndef NOT_HAVE_IF_NAMETOINDEX
324*48a54d36SAndroid Build Coastguard Worker ifi->ifi_index = if_nametoindex(ifr->ifr_name);
325*48a54d36SAndroid Build Coastguard Worker #else
326*48a54d36SAndroid Build Coastguard Worker ifrcopy = *ifr;
327*48a54d36SAndroid Build Coastguard Worker #ifdef SIOCGIFINDEX
328*48a54d36SAndroid Build Coastguard Worker if ( 0 >= ioctl(sockfd, SIOCGIFINDEX, &ifrcopy))
329*48a54d36SAndroid Build Coastguard Worker ifi->ifi_index = ifrcopy.ifr_index;
330*48a54d36SAndroid Build Coastguard Worker else
331*48a54d36SAndroid Build Coastguard Worker #endif
332*48a54d36SAndroid Build Coastguard Worker ifi->ifi_index = index++; /* SIOCGIFINDEX is broken on Solaris 2.5ish, so fake it */
333*48a54d36SAndroid Build Coastguard Worker #endif
334*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
335*48a54d36SAndroid Build Coastguard Worker ifi->ifi_name[IFI_NAME-1] = '\0';
336*48a54d36SAndroid Build Coastguard Worker /* end get_ifi_info2 */
337*48a54d36SAndroid Build Coastguard Worker /* include get_ifi_info3 */
338*48a54d36SAndroid Build Coastguard Worker switch (ifr->ifr_addr.sa_family) {
339*48a54d36SAndroid Build Coastguard Worker case AF_INET:
340*48a54d36SAndroid Build Coastguard Worker sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
341*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
342*48a54d36SAndroid Build Coastguard Worker ifi->ifi_addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
343*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
344*48a54d36SAndroid Build Coastguard Worker goto gotError;
345*48a54d36SAndroid Build Coastguard Worker }
346*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
347*48a54d36SAndroid Build Coastguard Worker
348*48a54d36SAndroid Build Coastguard Worker #ifdef SIOCGIFNETMASK
349*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) {
350*48a54d36SAndroid Build Coastguard Worker if (errno == EADDRNOTAVAIL) {
351*48a54d36SAndroid Build Coastguard Worker /*
352*48a54d36SAndroid Build Coastguard Worker * If the main interface is configured with no IP address but
353*48a54d36SAndroid Build Coastguard Worker * an alias interface exists with an IP address, you get
354*48a54d36SAndroid Build Coastguard Worker * EADDRNOTAVAIL for the main interface
355*48a54d36SAndroid Build Coastguard Worker */
356*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_addr);
357*48a54d36SAndroid Build Coastguard Worker free(ifi);
358*48a54d36SAndroid Build Coastguard Worker ifipnext = ifiptr;
359*48a54d36SAndroid Build Coastguard Worker *ifipnext = ifipold;
360*48a54d36SAndroid Build Coastguard Worker continue;
361*48a54d36SAndroid Build Coastguard Worker } else {
362*48a54d36SAndroid Build Coastguard Worker goto gotError;
363*48a54d36SAndroid Build Coastguard Worker }
364*48a54d36SAndroid Build Coastguard Worker }
365*48a54d36SAndroid Build Coastguard Worker
366*48a54d36SAndroid Build Coastguard Worker ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
367*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_netmask == NULL) goto gotError;
368*48a54d36SAndroid Build Coastguard Worker sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
369*48a54d36SAndroid Build Coastguard Worker /* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
370*48a54d36SAndroid Build Coastguard Worker #ifndef NOT_HAVE_SA_LEN
371*48a54d36SAndroid Build Coastguard Worker sinptr->sin_len = sizeof(struct sockaddr_in);
372*48a54d36SAndroid Build Coastguard Worker #endif
373*48a54d36SAndroid Build Coastguard Worker sinptr->sin_family = AF_INET;
374*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_netmask, sinptr, sizeof(struct sockaddr_in));
375*48a54d36SAndroid Build Coastguard Worker #endif
376*48a54d36SAndroid Build Coastguard Worker
377*48a54d36SAndroid Build Coastguard Worker #ifdef SIOCGIFBRDADDR
378*48a54d36SAndroid Build Coastguard Worker if (flags & IFF_BROADCAST) {
379*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy) < 0) {
380*48a54d36SAndroid Build Coastguard Worker goto gotError;
381*48a54d36SAndroid Build Coastguard Worker }
382*48a54d36SAndroid Build Coastguard Worker sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
383*48a54d36SAndroid Build Coastguard Worker /* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
384*48a54d36SAndroid Build Coastguard Worker #ifndef NOT_HAVE_SA_LEN
385*48a54d36SAndroid Build Coastguard Worker sinptr->sin_len = sizeof( struct sockaddr_in );
386*48a54d36SAndroid Build Coastguard Worker #endif
387*48a54d36SAndroid Build Coastguard Worker sinptr->sin_family = AF_INET;
388*48a54d36SAndroid Build Coastguard Worker ifi->ifi_brdaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
389*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_brdaddr == NULL) {
390*48a54d36SAndroid Build Coastguard Worker goto gotError;
391*48a54d36SAndroid Build Coastguard Worker }
392*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));
393*48a54d36SAndroid Build Coastguard Worker }
394*48a54d36SAndroid Build Coastguard Worker #endif
395*48a54d36SAndroid Build Coastguard Worker
396*48a54d36SAndroid Build Coastguard Worker #ifdef SIOCGIFDSTADDR
397*48a54d36SAndroid Build Coastguard Worker if (flags & IFF_POINTOPOINT) {
398*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy) < 0) {
399*48a54d36SAndroid Build Coastguard Worker goto gotError;
400*48a54d36SAndroid Build Coastguard Worker }
401*48a54d36SAndroid Build Coastguard Worker sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
402*48a54d36SAndroid Build Coastguard Worker /* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
403*48a54d36SAndroid Build Coastguard Worker #ifndef NOT_HAVE_SA_LEN
404*48a54d36SAndroid Build Coastguard Worker sinptr->sin_len = sizeof( struct sockaddr_in );
405*48a54d36SAndroid Build Coastguard Worker #endif
406*48a54d36SAndroid Build Coastguard Worker sinptr->sin_family = AF_INET;
407*48a54d36SAndroid Build Coastguard Worker ifi->ifi_dstaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
408*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_dstaddr == NULL) {
409*48a54d36SAndroid Build Coastguard Worker goto gotError;
410*48a54d36SAndroid Build Coastguard Worker }
411*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));
412*48a54d36SAndroid Build Coastguard Worker }
413*48a54d36SAndroid Build Coastguard Worker #endif
414*48a54d36SAndroid Build Coastguard Worker }
415*48a54d36SAndroid Build Coastguard Worker break;
416*48a54d36SAndroid Build Coastguard Worker
417*48a54d36SAndroid Build Coastguard Worker #if defined(AF_INET6) && HAVE_IPV6
418*48a54d36SAndroid Build Coastguard Worker case AF_INET6:
419*48a54d36SAndroid Build Coastguard Worker sinptr6 = (struct sockaddr_in6 *) &ifr->ifr_addr;
420*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
421*48a54d36SAndroid Build Coastguard Worker ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
422*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr == NULL) {
423*48a54d36SAndroid Build Coastguard Worker goto gotError;
424*48a54d36SAndroid Build Coastguard Worker }
425*48a54d36SAndroid Build Coastguard Worker
426*48a54d36SAndroid Build Coastguard Worker /* Some platforms (*BSD) inject the prefix in IPv6LL addresses */
427*48a54d36SAndroid Build Coastguard Worker /* We need to strip that out */
428*48a54d36SAndroid Build Coastguard Worker if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
429*48a54d36SAndroid Build Coastguard Worker sinptr6->sin6_addr.s6_addr[2] = sinptr6->sin6_addr.s6_addr[3] = 0;
430*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_addr, sinptr6, sizeof(struct sockaddr_in6));
431*48a54d36SAndroid Build Coastguard Worker
432*48a54d36SAndroid Build Coastguard Worker #ifdef SIOCGIFNETMASK_IN6
433*48a54d36SAndroid Build Coastguard Worker {
434*48a54d36SAndroid Build Coastguard Worker struct in6_ifreq ifr6;
435*48a54d36SAndroid Build Coastguard Worker if (sockf6 == -1)
436*48a54d36SAndroid Build Coastguard Worker sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
437*48a54d36SAndroid Build Coastguard Worker memset(&ifr6, 0, sizeof(ifr6));
438*48a54d36SAndroid Build Coastguard Worker memcpy(&ifr6.ifr_name, &ifr->ifr_name, sizeof(ifr6.ifr_name ));
439*48a54d36SAndroid Build Coastguard Worker memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
440*48a54d36SAndroid Build Coastguard Worker if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
441*48a54d36SAndroid Build Coastguard Worker if (errno == EADDRNOTAVAIL) {
442*48a54d36SAndroid Build Coastguard Worker /*
443*48a54d36SAndroid Build Coastguard Worker * If the main interface is configured with no IP address but
444*48a54d36SAndroid Build Coastguard Worker * an alias interface exists with an IP address, you get
445*48a54d36SAndroid Build Coastguard Worker * EADDRNOTAVAIL for the main interface
446*48a54d36SAndroid Build Coastguard Worker */
447*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_addr);
448*48a54d36SAndroid Build Coastguard Worker free(ifi);
449*48a54d36SAndroid Build Coastguard Worker ifipnext = ifiptr;
450*48a54d36SAndroid Build Coastguard Worker *ifipnext = ifipold;
451*48a54d36SAndroid Build Coastguard Worker continue;
452*48a54d36SAndroid Build Coastguard Worker } else {
453*48a54d36SAndroid Build Coastguard Worker goto gotError;
454*48a54d36SAndroid Build Coastguard Worker }
455*48a54d36SAndroid Build Coastguard Worker }
456*48a54d36SAndroid Build Coastguard Worker ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
457*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_netmask == NULL) goto gotError;
458*48a54d36SAndroid Build Coastguard Worker sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
459*48a54d36SAndroid Build Coastguard Worker memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct sockaddr_in6));
460*48a54d36SAndroid Build Coastguard Worker }
461*48a54d36SAndroid Build Coastguard Worker #endif
462*48a54d36SAndroid Build Coastguard Worker }
463*48a54d36SAndroid Build Coastguard Worker break;
464*48a54d36SAndroid Build Coastguard Worker #endif
465*48a54d36SAndroid Build Coastguard Worker
466*48a54d36SAndroid Build Coastguard Worker default:
467*48a54d36SAndroid Build Coastguard Worker break;
468*48a54d36SAndroid Build Coastguard Worker }
469*48a54d36SAndroid Build Coastguard Worker }
470*48a54d36SAndroid Build Coastguard Worker goto done;
471*48a54d36SAndroid Build Coastguard Worker
472*48a54d36SAndroid Build Coastguard Worker gotError:
473*48a54d36SAndroid Build Coastguard Worker if (ifihead != NULL) {
474*48a54d36SAndroid Build Coastguard Worker free_ifi_info(ifihead);
475*48a54d36SAndroid Build Coastguard Worker ifihead = NULL;
476*48a54d36SAndroid Build Coastguard Worker }
477*48a54d36SAndroid Build Coastguard Worker
478*48a54d36SAndroid Build Coastguard Worker done:
479*48a54d36SAndroid Build Coastguard Worker if (buf != NULL) {
480*48a54d36SAndroid Build Coastguard Worker free(buf);
481*48a54d36SAndroid Build Coastguard Worker }
482*48a54d36SAndroid Build Coastguard Worker if (sockfd != -1) {
483*48a54d36SAndroid Build Coastguard Worker junk = close(sockfd);
484*48a54d36SAndroid Build Coastguard Worker assert(junk == 0);
485*48a54d36SAndroid Build Coastguard Worker }
486*48a54d36SAndroid Build Coastguard Worker if (sockf6 != -1) {
487*48a54d36SAndroid Build Coastguard Worker junk = close(sockf6);
488*48a54d36SAndroid Build Coastguard Worker assert(junk == 0);
489*48a54d36SAndroid Build Coastguard Worker }
490*48a54d36SAndroid Build Coastguard Worker return(ifihead); /* pointer to first structure in linked list */
491*48a54d36SAndroid Build Coastguard Worker }
492*48a54d36SAndroid Build Coastguard Worker /* end get_ifi_info3 */
493*48a54d36SAndroid Build Coastguard Worker
494*48a54d36SAndroid Build Coastguard Worker /* include free_ifi_info */
495*48a54d36SAndroid Build Coastguard Worker void
free_ifi_info(struct ifi_info * ifihead)496*48a54d36SAndroid Build Coastguard Worker free_ifi_info(struct ifi_info *ifihead)
497*48a54d36SAndroid Build Coastguard Worker {
498*48a54d36SAndroid Build Coastguard Worker struct ifi_info *ifi, *ifinext;
499*48a54d36SAndroid Build Coastguard Worker
500*48a54d36SAndroid Build Coastguard Worker for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
501*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_addr != NULL)
502*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_addr);
503*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_netmask != NULL)
504*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_netmask);
505*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_brdaddr != NULL)
506*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_brdaddr);
507*48a54d36SAndroid Build Coastguard Worker if (ifi->ifi_dstaddr != NULL)
508*48a54d36SAndroid Build Coastguard Worker free(ifi->ifi_dstaddr);
509*48a54d36SAndroid Build Coastguard Worker ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */
510*48a54d36SAndroid Build Coastguard Worker free(ifi); /* the ifi_info{} itself */
511*48a54d36SAndroid Build Coastguard Worker }
512*48a54d36SAndroid Build Coastguard Worker }
513*48a54d36SAndroid Build Coastguard Worker /* end free_ifi_info */
514*48a54d36SAndroid Build Coastguard Worker
515*48a54d36SAndroid Build Coastguard Worker ssize_t
recvfrom_flags(int fd,void * ptr,size_t nbytes,int * flagsp,struct sockaddr * sa,socklen_t * salenptr,struct my_in_pktinfo * pktp,u_char * ttl)516*48a54d36SAndroid Build Coastguard Worker recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
517*48a54d36SAndroid Build Coastguard Worker struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl)
518*48a54d36SAndroid Build Coastguard Worker {
519*48a54d36SAndroid Build Coastguard Worker struct msghdr msg;
520*48a54d36SAndroid Build Coastguard Worker struct iovec iov[1];
521*48a54d36SAndroid Build Coastguard Worker ssize_t n;
522*48a54d36SAndroid Build Coastguard Worker
523*48a54d36SAndroid Build Coastguard Worker #ifdef CMSG_FIRSTHDR
524*48a54d36SAndroid Build Coastguard Worker struct cmsghdr *cmptr;
525*48a54d36SAndroid Build Coastguard Worker union {
526*48a54d36SAndroid Build Coastguard Worker struct cmsghdr cm;
527*48a54d36SAndroid Build Coastguard Worker char control[1024];
528*48a54d36SAndroid Build Coastguard Worker } control_un;
529*48a54d36SAndroid Build Coastguard Worker
530*48a54d36SAndroid Build Coastguard Worker *ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
531*48a54d36SAndroid Build Coastguard Worker
532*48a54d36SAndroid Build Coastguard Worker msg.msg_control = control_un.control;
533*48a54d36SAndroid Build Coastguard Worker msg.msg_controllen = sizeof(control_un.control);
534*48a54d36SAndroid Build Coastguard Worker msg.msg_flags = 0;
535*48a54d36SAndroid Build Coastguard Worker #else
536*48a54d36SAndroid Build Coastguard Worker memset(&msg, 0, sizeof(msg)); /* make certain msg_accrightslen = 0 */
537*48a54d36SAndroid Build Coastguard Worker #endif /* CMSG_FIRSTHDR */
538*48a54d36SAndroid Build Coastguard Worker
539*48a54d36SAndroid Build Coastguard Worker msg.msg_name = (char *) sa;
540*48a54d36SAndroid Build Coastguard Worker msg.msg_namelen = *salenptr;
541*48a54d36SAndroid Build Coastguard Worker iov[0].iov_base = (char *)ptr;
542*48a54d36SAndroid Build Coastguard Worker iov[0].iov_len = nbytes;
543*48a54d36SAndroid Build Coastguard Worker msg.msg_iov = iov;
544*48a54d36SAndroid Build Coastguard Worker msg.msg_iovlen = 1;
545*48a54d36SAndroid Build Coastguard Worker
546*48a54d36SAndroid Build Coastguard Worker if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
547*48a54d36SAndroid Build Coastguard Worker return(n);
548*48a54d36SAndroid Build Coastguard Worker
549*48a54d36SAndroid Build Coastguard Worker *salenptr = msg.msg_namelen; /* pass back results */
550*48a54d36SAndroid Build Coastguard Worker if (pktp) {
551*48a54d36SAndroid Build Coastguard Worker /* 0.0.0.0, i/f = -1 */
552*48a54d36SAndroid Build Coastguard Worker /* We set the interface to -1 so that the caller can
553*48a54d36SAndroid Build Coastguard Worker tell whether we returned a meaningful value or
554*48a54d36SAndroid Build Coastguard Worker just some default. Previously this code just
555*48a54d36SAndroid Build Coastguard Worker set the value to 0, but I'm concerned that 0
556*48a54d36SAndroid Build Coastguard Worker might be a valid interface value.
557*48a54d36SAndroid Build Coastguard Worker */
558*48a54d36SAndroid Build Coastguard Worker memset(pktp, 0, sizeof(struct my_in_pktinfo));
559*48a54d36SAndroid Build Coastguard Worker pktp->ipi_ifindex = -1;
560*48a54d36SAndroid Build Coastguard Worker }
561*48a54d36SAndroid Build Coastguard Worker /* end recvfrom_flags1 */
562*48a54d36SAndroid Build Coastguard Worker
563*48a54d36SAndroid Build Coastguard Worker /* include recvfrom_flags2 */
564*48a54d36SAndroid Build Coastguard Worker #ifndef CMSG_FIRSTHDR
565*48a54d36SAndroid Build Coastguard Worker #warning CMSG_FIRSTHDR not defined. Will not be able to determine destination address, received interface, etc.
566*48a54d36SAndroid Build Coastguard Worker *flagsp = 0; /* pass back results */
567*48a54d36SAndroid Build Coastguard Worker return(n);
568*48a54d36SAndroid Build Coastguard Worker #else
569*48a54d36SAndroid Build Coastguard Worker
570*48a54d36SAndroid Build Coastguard Worker *flagsp = msg.msg_flags; /* pass back results */
571*48a54d36SAndroid Build Coastguard Worker if (msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr) ||
572*48a54d36SAndroid Build Coastguard Worker (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)
573*48a54d36SAndroid Build Coastguard Worker return(n);
574*48a54d36SAndroid Build Coastguard Worker
575*48a54d36SAndroid Build Coastguard Worker for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
576*48a54d36SAndroid Build Coastguard Worker cmptr = CMSG_NXTHDR(&msg, cmptr)) {
577*48a54d36SAndroid Build Coastguard Worker
578*48a54d36SAndroid Build Coastguard Worker #ifdef IP_PKTINFO
579*48a54d36SAndroid Build Coastguard Worker #if in_pktinfo_definition_is_missing
580*48a54d36SAndroid Build Coastguard Worker struct in_pktinfo
581*48a54d36SAndroid Build Coastguard Worker {
582*48a54d36SAndroid Build Coastguard Worker int ipi_ifindex;
583*48a54d36SAndroid Build Coastguard Worker struct in_addr ipi_spec_dst;
584*48a54d36SAndroid Build Coastguard Worker struct in_addr ipi_addr;
585*48a54d36SAndroid Build Coastguard Worker };
586*48a54d36SAndroid Build Coastguard Worker #endif
587*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IP &&
588*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IP_PKTINFO) {
589*48a54d36SAndroid Build Coastguard Worker struct in_pktinfo *tmp;
590*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
591*48a54d36SAndroid Build Coastguard Worker
592*48a54d36SAndroid Build Coastguard Worker tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
593*48a54d36SAndroid Build Coastguard Worker sin->sin_family = AF_INET;
594*48a54d36SAndroid Build Coastguard Worker sin->sin_addr = tmp->ipi_addr;
595*48a54d36SAndroid Build Coastguard Worker sin->sin_port = 0;
596*48a54d36SAndroid Build Coastguard Worker pktp->ipi_ifindex = tmp->ipi_ifindex;
597*48a54d36SAndroid Build Coastguard Worker continue;
598*48a54d36SAndroid Build Coastguard Worker }
599*48a54d36SAndroid Build Coastguard Worker #endif
600*48a54d36SAndroid Build Coastguard Worker
601*48a54d36SAndroid Build Coastguard Worker #ifdef IP_RECVDSTADDR
602*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IP &&
603*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IP_RECVDSTADDR) {
604*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
605*48a54d36SAndroid Build Coastguard Worker
606*48a54d36SAndroid Build Coastguard Worker sin->sin_family = AF_INET;
607*48a54d36SAndroid Build Coastguard Worker sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
608*48a54d36SAndroid Build Coastguard Worker sin->sin_port = 0;
609*48a54d36SAndroid Build Coastguard Worker continue;
610*48a54d36SAndroid Build Coastguard Worker }
611*48a54d36SAndroid Build Coastguard Worker #endif
612*48a54d36SAndroid Build Coastguard Worker
613*48a54d36SAndroid Build Coastguard Worker #ifdef IP_RECVIF
614*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IP &&
615*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IP_RECVIF) {
616*48a54d36SAndroid Build Coastguard Worker struct sockaddr_dl *sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
617*48a54d36SAndroid Build Coastguard Worker #ifndef HAVE_BROKEN_RECVIF_NAME
618*48a54d36SAndroid Build Coastguard Worker int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
619*48a54d36SAndroid Build Coastguard Worker strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
620*48a54d36SAndroid Build Coastguard Worker #endif
621*48a54d36SAndroid Build Coastguard Worker pktp->ipi_ifindex = sdl->sdl_index;
622*48a54d36SAndroid Build Coastguard Worker #ifdef HAVE_BROKEN_RECVIF_NAME
623*48a54d36SAndroid Build Coastguard Worker if (sdl->sdl_index == 0) {
624*48a54d36SAndroid Build Coastguard Worker pktp->ipi_ifindex = *(uint_t*)sdl;
625*48a54d36SAndroid Build Coastguard Worker }
626*48a54d36SAndroid Build Coastguard Worker #endif
627*48a54d36SAndroid Build Coastguard Worker assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
628*48a54d36SAndroid Build Coastguard Worker // null terminated because of memset above
629*48a54d36SAndroid Build Coastguard Worker continue;
630*48a54d36SAndroid Build Coastguard Worker }
631*48a54d36SAndroid Build Coastguard Worker #endif
632*48a54d36SAndroid Build Coastguard Worker
633*48a54d36SAndroid Build Coastguard Worker #ifdef IP_RECVTTL
634*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IP &&
635*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IP_RECVTTL) {
636*48a54d36SAndroid Build Coastguard Worker *ttl = *(u_char*)CMSG_DATA(cmptr);
637*48a54d36SAndroid Build Coastguard Worker continue;
638*48a54d36SAndroid Build Coastguard Worker }
639*48a54d36SAndroid Build Coastguard Worker else if (cmptr->cmsg_level == IPPROTO_IP &&
640*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IP_TTL) { // some implementations seem to send IP_TTL instead of IP_RECVTTL
641*48a54d36SAndroid Build Coastguard Worker *ttl = *(int*)CMSG_DATA(cmptr);
642*48a54d36SAndroid Build Coastguard Worker continue;
643*48a54d36SAndroid Build Coastguard Worker }
644*48a54d36SAndroid Build Coastguard Worker #endif
645*48a54d36SAndroid Build Coastguard Worker
646*48a54d36SAndroid Build Coastguard Worker #if defined(IPV6_PKTINFO) && HAVE_IPV6
647*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IPV6 &&
648*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IPV6_2292_PKTINFO) {
649*48a54d36SAndroid Build Coastguard Worker struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
650*48a54d36SAndroid Build Coastguard Worker struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
651*48a54d36SAndroid Build Coastguard Worker
652*48a54d36SAndroid Build Coastguard Worker sin6->sin6_family = AF_INET6;
653*48a54d36SAndroid Build Coastguard Worker #ifndef NOT_HAVE_SA_LEN
654*48a54d36SAndroid Build Coastguard Worker sin6->sin6_len = sizeof(*sin6);
655*48a54d36SAndroid Build Coastguard Worker #endif
656*48a54d36SAndroid Build Coastguard Worker sin6->sin6_addr = ip6_info->ipi6_addr;
657*48a54d36SAndroid Build Coastguard Worker sin6->sin6_flowinfo = 0;
658*48a54d36SAndroid Build Coastguard Worker sin6->sin6_scope_id = 0;
659*48a54d36SAndroid Build Coastguard Worker sin6->sin6_port = 0;
660*48a54d36SAndroid Build Coastguard Worker pktp->ipi_ifindex = ip6_info->ipi6_ifindex;
661*48a54d36SAndroid Build Coastguard Worker continue;
662*48a54d36SAndroid Build Coastguard Worker }
663*48a54d36SAndroid Build Coastguard Worker #endif
664*48a54d36SAndroid Build Coastguard Worker
665*48a54d36SAndroid Build Coastguard Worker #if defined(IPV6_HOPLIMIT) && HAVE_IPV6
666*48a54d36SAndroid Build Coastguard Worker if (cmptr->cmsg_level == IPPROTO_IPV6 &&
667*48a54d36SAndroid Build Coastguard Worker cmptr->cmsg_type == IPV6_2292_HOPLIMIT) {
668*48a54d36SAndroid Build Coastguard Worker *ttl = *(int*)CMSG_DATA(cmptr);
669*48a54d36SAndroid Build Coastguard Worker continue;
670*48a54d36SAndroid Build Coastguard Worker }
671*48a54d36SAndroid Build Coastguard Worker #endif
672*48a54d36SAndroid Build Coastguard Worker assert(0); // unknown ancillary data
673*48a54d36SAndroid Build Coastguard Worker }
674*48a54d36SAndroid Build Coastguard Worker return(n);
675*48a54d36SAndroid Build Coastguard Worker #endif /* CMSG_FIRSTHDR */
676*48a54d36SAndroid Build Coastguard Worker }
677*48a54d36SAndroid Build Coastguard Worker
678*48a54d36SAndroid Build Coastguard Worker // **********************************************************************************************
679*48a54d36SAndroid Build Coastguard Worker
680*48a54d36SAndroid Build Coastguard Worker // daemonize the process. Adapted from "Unix Network Programming" vol 1 by Stevens, section 12.4.
681*48a54d36SAndroid Build Coastguard Worker // Returns 0 on success, -1 on failure.
682*48a54d36SAndroid Build Coastguard Worker
683*48a54d36SAndroid Build Coastguard Worker #ifdef NOT_HAVE_DAEMON
684*48a54d36SAndroid Build Coastguard Worker #include <fcntl.h>
685*48a54d36SAndroid Build Coastguard Worker #include <sys/stat.h>
686*48a54d36SAndroid Build Coastguard Worker #include <sys/signal.h>
687*48a54d36SAndroid Build Coastguard Worker
daemon(int nochdir,int noclose)688*48a54d36SAndroid Build Coastguard Worker int daemon(int nochdir, int noclose)
689*48a54d36SAndroid Build Coastguard Worker {
690*48a54d36SAndroid Build Coastguard Worker switch (fork())
691*48a54d36SAndroid Build Coastguard Worker {
692*48a54d36SAndroid Build Coastguard Worker case -1: return (-1); // Fork failed
693*48a54d36SAndroid Build Coastguard Worker case 0: break; // Child -- continue
694*48a54d36SAndroid Build Coastguard Worker default: _exit(0); // Parent -- exit
695*48a54d36SAndroid Build Coastguard Worker }
696*48a54d36SAndroid Build Coastguard Worker
697*48a54d36SAndroid Build Coastguard Worker if (setsid() == -1) return(-1);
698*48a54d36SAndroid Build Coastguard Worker
699*48a54d36SAndroid Build Coastguard Worker signal(SIGHUP, SIG_IGN);
700*48a54d36SAndroid Build Coastguard Worker
701*48a54d36SAndroid Build Coastguard Worker switch (fork()) // Fork again, primarily for reasons of Unix trivia
702*48a54d36SAndroid Build Coastguard Worker {
703*48a54d36SAndroid Build Coastguard Worker case -1: return (-1); // Fork failed
704*48a54d36SAndroid Build Coastguard Worker case 0: break; // Child -- continue
705*48a54d36SAndroid Build Coastguard Worker default: _exit(0); // Parent -- exit
706*48a54d36SAndroid Build Coastguard Worker }
707*48a54d36SAndroid Build Coastguard Worker
708*48a54d36SAndroid Build Coastguard Worker if (!nochdir) (void)chdir("/");
709*48a54d36SAndroid Build Coastguard Worker umask(0);
710*48a54d36SAndroid Build Coastguard Worker
711*48a54d36SAndroid Build Coastguard Worker if (!noclose)
712*48a54d36SAndroid Build Coastguard Worker {
713*48a54d36SAndroid Build Coastguard Worker int fd = open("/dev/null", O_RDWR, 0);
714*48a54d36SAndroid Build Coastguard Worker if (fd != -1)
715*48a54d36SAndroid Build Coastguard Worker {
716*48a54d36SAndroid Build Coastguard Worker // Avoid unnecessarily duplicating a file descriptor to itself
717*48a54d36SAndroid Build Coastguard Worker if (fd != STDIN_FILENO) (void)dup2(fd, STDIN_FILENO);
718*48a54d36SAndroid Build Coastguard Worker if (fd != STDOUT_FILENO) (void)dup2(fd, STDOUT_FILENO);
719*48a54d36SAndroid Build Coastguard Worker if (fd != STDERR_FILENO) (void)dup2(fd, STDERR_FILENO);
720*48a54d36SAndroid Build Coastguard Worker if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
721*48a54d36SAndroid Build Coastguard Worker (void)close (fd);
722*48a54d36SAndroid Build Coastguard Worker }
723*48a54d36SAndroid Build Coastguard Worker }
724*48a54d36SAndroid Build Coastguard Worker return (0);
725*48a54d36SAndroid Build Coastguard Worker }
726*48a54d36SAndroid Build Coastguard Worker #endif /* NOT_HAVE_DAEMON */
727