xref: /aosp_15_r20/external/mdnsresponder/mDNSPosix/mDNSUNP.c (revision 48a54d368dc4fa860885eef7b70b6c53499e7c25)
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