]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/network.c
1 /* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 int iface_check(int family
, struct all_addr
*addr
,
20 struct ifreq
*ifr
, int *indexp
)
25 /* Note: have to check all and not bail out early, so that we set the
30 #ifdef HAVE_BSD_BRIDGE
31 /* One form of bridging on BSD has the property that packets
32 can be recieved on bridge interfaces which do not have an IP address.
33 We allow these to be treated as aliases of another interface which does have
34 an IP address with --dhcp-bridge=interface,alias,alias */
35 struct dhcp_bridge
*bridge
, *alias
;
36 for (bridge
= daemon
->bridges
; bridge
; bridge
= bridge
->next
)
38 for (alias
= bridge
->alias
; alias
; alias
= alias
->next
)
39 if (strncmp(ifr
->ifr_name
, alias
->iface
, IF_NAMESIZE
) == 0)
43 if (!(newindex
= if_nametoindex(bridge
->iface
)))
45 my_syslog(LOG_WARNING
, _("unknown interface %s in bridge-interface"), ifr
->ifr_name
);
51 strncpy(ifr
->ifr_name
, bridge
->iface
, IF_NAMESIZE
);
61 if (daemon
->if_names
|| (addr
&& daemon
->if_addrs
))
65 for (tmp
= daemon
->if_names
; tmp
; tmp
= tmp
->next
)
66 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
->ifr_name
) == 0))
69 for (tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
70 if (addr
&& tmp
->addr
.sa
.sa_family
== family
)
72 if (family
== AF_INET
&&
73 tmp
->addr
.in
.sin_addr
.s_addr
== addr
->addr
.addr4
.s_addr
)
76 else if (family
== AF_INET6
&&
77 IN6_ARE_ADDR_EQUAL(&tmp
->addr
.in6
.sin6_addr
,
84 for (tmp
= daemon
->if_except
; tmp
; tmp
= tmp
->next
)
85 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
->ifr_name
) == 0))
91 static int iface_allowed(struct irec
**irecp
, int if_index
,
92 union mysockaddr
*addr
, struct in_addr netmask
)
100 /* check whether the interface IP has been added already
101 we call this routine multiple times. */
102 for (iface
= *irecp
; iface
; iface
= iface
->next
)
103 if (sockaddr_isequal(&iface
->addr
, addr
))
106 #ifdef HAVE_LINUX_NETWORK
107 ifr
.ifr_ifindex
= if_index
;
110 if ((fd
= socket(PF_INET
, SOCK_DGRAM
, 0)) == -1 ||
111 #ifdef HAVE_LINUX_NETWORK
112 ioctl(fd
, SIOCGIFNAME
, &ifr
) == -1 ||
114 !if_indextoname(if_index
, ifr
.ifr_name
) ||
116 ioctl(fd
, SIOCGIFFLAGS
, &ifr
) == -1)
129 /* If we are restricting the set of interfaces to use, make
130 sure that loopback interfaces are in that set. */
131 if (daemon
->if_names
&& (ifr
.ifr_flags
& IFF_LOOPBACK
))
134 for (lo
= daemon
->if_names
; lo
; lo
= lo
->next
)
135 if (lo
->name
&& strcmp(lo
->name
, ifr
.ifr_name
) == 0)
142 (lo
= whine_malloc(sizeof(struct iname
))) &&
143 (lo
->name
= whine_malloc(strlen(ifr
.ifr_name
)+1)))
145 strcpy(lo
->name
, ifr
.ifr_name
);
146 lo
->isloop
= lo
->used
= 1;
147 lo
->next
= daemon
->if_names
;
148 daemon
->if_names
= lo
;
152 if (addr
->sa
.sa_family
== AF_INET
&&
153 !iface_check(AF_INET
, (struct all_addr
*)&addr
->in
.sin_addr
, &ifr
, NULL
))
156 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
157 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
.ifr_name
) == 0))
161 if (addr
->sa
.sa_family
== AF_INET6
&&
162 !iface_check(AF_INET6
, (struct all_addr
*)&addr
->in6
.sin6_addr
, &ifr
, NULL
))
167 if ((iface
= whine_malloc(sizeof(struct irec
))))
170 iface
->netmask
= netmask
;
171 iface
->dhcp_ok
= dhcp_ok
;
172 iface
->next
= *irecp
;
182 static int iface_allowed_v6(struct in6_addr
*local
,
183 int scope
, int if_index
, void *vparam
)
185 union mysockaddr addr
;
186 struct in_addr netmask
; /* dummy */
190 memset(&addr
, 0, sizeof(addr
));
191 #ifdef HAVE_SOCKADDR_SA_LEN
192 addr
.in6
.sin6_len
= sizeof(addr
.in6
);
194 addr
.in6
.sin6_family
= AF_INET6
;
195 addr
.in6
.sin6_addr
= *local
;
196 addr
.in6
.sin6_port
= htons(daemon
->port
);
197 addr
.in6
.sin6_scope_id
= scope
;
199 return iface_allowed((struct irec
**)vparam
, if_index
, &addr
, netmask
);
203 static int iface_allowed_v4(struct in_addr local
, int if_index
,
204 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
206 union mysockaddr addr
;
208 memset(&addr
, 0, sizeof(addr
));
209 #ifdef HAVE_SOCKADDR_SA_LEN
210 addr
.in
.sin_len
= sizeof(addr
.in
);
212 addr
.in
.sin_family
= AF_INET
;
213 addr
.in
.sin_addr
= broadcast
; /* warning */
214 addr
.in
.sin_addr
= local
;
215 addr
.in
.sin_port
= htons(daemon
->port
);
217 return iface_allowed((struct irec
**)vparam
, if_index
, &addr
, netmask
);
221 int enumerate_interfaces(void)
224 return iface_enumerate(&daemon
->interfaces
, iface_allowed_v4
, iface_allowed_v6
);
226 return iface_enumerate(&daemon
->interfaces
, iface_allowed_v4
, NULL
);
230 /* set NONBLOCK bit on fd: See Stevens 16.6 */
235 if ((flags
= fcntl(fd
, F_GETFL
)) == -1 ||
236 fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
242 #if defined(HAVE_IPV6)
243 static int create_ipv6_listener(struct listener
**link
, int port
)
245 union mysockaddr addr
;
250 memset(&addr
, 0, sizeof(addr
));
251 addr
.in6
.sin6_family
= AF_INET6
;
252 addr
.in6
.sin6_addr
= in6addr_any
;
253 addr
.in6
.sin6_port
= htons(port
);
254 #ifdef HAVE_SOCKADDR_SA_LEN
255 addr
.in6
.sin6_len
= sizeof(addr
.in6
);
258 /* No error of the kernel doesn't support IPv6 */
259 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) == -1)
260 return (errno
== EPROTONOSUPPORT
||
261 errno
== EAFNOSUPPORT
||
264 if ((tcpfd
= socket(AF_INET6
, SOCK_STREAM
, 0)) == -1)
267 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
268 setsockopt(tcpfd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
269 setsockopt(fd
, IPV6_LEVEL
, IPV6_V6ONLY
, &opt
, sizeof(opt
)) == -1 ||
270 setsockopt(tcpfd
, IPV6_LEVEL
, IPV6_V6ONLY
, &opt
, sizeof(opt
)) == -1 ||
273 #ifdef IPV6_RECVPKTINFO
274 setsockopt(fd
, IPV6_LEVEL
, IPV6_RECVPKTINFO
, &opt
, sizeof(opt
)) == -1 ||
276 setsockopt(fd
, IPV6_LEVEL
, IPV6_PKTINFO
, &opt
, sizeof(opt
)) == -1 ||
278 bind(tcpfd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == -1 ||
279 listen(tcpfd
, 5) == -1 ||
280 bind(fd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == -1)
283 l
= safe_malloc(sizeof(struct listener
));
287 l
->family
= AF_INET6
;
295 struct listener
*create_wildcard_listeners(void)
297 union mysockaddr addr
;
299 struct listener
*l
, *l6
= NULL
;
300 int tcpfd
= -1, fd
= -1, tftpfd
= -1;
302 memset(&addr
, 0, sizeof(addr
));
303 addr
.in
.sin_family
= AF_INET
;
304 addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
305 addr
.in
.sin_port
= htons(daemon
->port
);
306 #ifdef HAVE_SOCKADDR_SA_LEN
307 addr
.in
.sin_len
= sizeof(struct sockaddr_in
);
310 if (daemon
->port
!= 0)
313 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1 ||
314 (tcpfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
317 if (setsockopt(tcpfd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
318 bind(tcpfd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == -1 ||
319 listen(tcpfd
, 5) == -1 ||
322 !create_ipv6_listener(&l6
, daemon
->port
) ||
324 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
326 #if defined(HAVE_LINUX_NETWORK)
327 setsockopt(fd
, SOL_IP
, IP_PKTINFO
, &opt
, sizeof(opt
)) == -1 ||
328 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
329 setsockopt(fd
, IPPROTO_IP
, IP_RECVDSTADDR
, &opt
, sizeof(opt
)) == -1 ||
330 setsockopt(fd
, IPPROTO_IP
, IP_RECVIF
, &opt
, sizeof(opt
)) == -1 ||
332 bind(fd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == -1)
337 if (daemon
->options
& OPT_TFTP
)
339 addr
.in
.sin_port
= htons(TFTP_PORT
);
340 if ((tftpfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1)
343 if (!fix_fd(tftpfd
) ||
344 #if defined(HAVE_LINUX_NETWORK)
345 setsockopt(tftpfd
, SOL_IP
, IP_PKTINFO
, &opt
, sizeof(opt
)) == -1 ||
346 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
347 setsockopt(tftpfd
, IPPROTO_IP
, IP_RECVDSTADDR
, &opt
, sizeof(opt
)) == -1 ||
348 setsockopt(tftpfd
, IPPROTO_IP
, IP_RECVIF
, &opt
, sizeof(opt
)) == -1 ||
350 bind(tftpfd
, (struct sockaddr
*)&addr
, sa_len(&addr
)) == -1)
355 l
= safe_malloc(sizeof(struct listener
));
365 struct listener
*create_bound_listeners(void)
367 struct listener
*listeners
= NULL
;
371 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
373 struct listener
*new = safe_malloc(sizeof(struct listener
));
374 new->family
= iface
->addr
.sa
.sa_family
;
376 new->next
= listeners
;
381 if (daemon
->port
!= 0)
383 if ((new->tcpfd
= socket(iface
->addr
.sa
.sa_family
, SOCK_STREAM
, 0)) == -1 ||
384 (new->fd
= socket(iface
->addr
.sa
.sa_family
, SOCK_DGRAM
, 0)) == -1 ||
385 setsockopt(new->fd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
386 setsockopt(new->tcpfd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
387 !fix_fd(new->tcpfd
) ||
389 die(_("failed to create listening socket: %s"), NULL
, EC_BADNET
);
392 if (iface
->addr
.sa
.sa_family
== AF_INET6
)
394 if (setsockopt(new->fd
, IPV6_LEVEL
, IPV6_V6ONLY
, &opt
, sizeof(opt
)) == -1 ||
395 setsockopt(new->tcpfd
, IPV6_LEVEL
, IPV6_V6ONLY
, &opt
, sizeof(opt
)) == -1)
396 die(_("failed to set IPV6 options on listening socket: %s"), NULL
, EC_BADNET
);
400 if (bind(new->tcpfd
, &iface
->addr
.sa
, sa_len(&iface
->addr
)) == -1 ||
401 bind(new->fd
, &iface
->addr
.sa
, sa_len(&iface
->addr
)) == -1)
404 if (iface
->addr
.sa
.sa_family
== AF_INET6
&& (errno
== ENODEV
|| errno
== EADDRNOTAVAIL
))
414 prettyprint_addr(&iface
->addr
, daemon
->namebuff
);
415 die(_("failed to bind listening socket for %s: %s"),
416 daemon
->namebuff
, EC_BADNET
);
419 else if (listen(new->tcpfd
, 5) == -1)
420 die(_("failed to listen on socket: %s"), NULL
, EC_BADNET
);
424 if ((daemon
->options
& OPT_TFTP
) && iface
->addr
.sa
.sa_family
== AF_INET
&& iface
->dhcp_ok
)
426 short save
= iface
->addr
.in
.sin_port
;
427 iface
->addr
.in
.sin_port
= htons(TFTP_PORT
);
428 if ((new->tftpfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1 ||
429 setsockopt(new->tftpfd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
)) == -1 ||
430 !fix_fd(new->tftpfd
) ||
431 bind(new->tftpfd
, &iface
->addr
.sa
, sa_len(&iface
->addr
)) == -1)
432 die(_("failed to create TFTP socket: %s"), NULL
, EC_BADNET
);
433 iface
->addr
.in
.sin_port
= save
;
444 int local_bind(int fd
, union mysockaddr
*addr
, char *intname
, int is_tcp
)
446 union mysockaddr addr_copy
= *addr
;
448 /* cannot set source _port_ for TCP connections. */
451 if (addr_copy
.sa
.sa_family
== AF_INET
)
452 addr_copy
.in
.sin_port
= 0;
455 addr_copy
.in6
.sin6_port
= 0;
459 if (bind(fd
, (struct sockaddr
*)&addr_copy
, sa_len(&addr_copy
)) == -1)
462 #if defined(SO_BINDTODEVICE)
463 if (strlen(intname
) != 0 &&
464 setsockopt(fd
, SOL_SOCKET
, SO_BINDTODEVICE
, intname
, sizeof(intname
)) == -1)
471 static struct serverfd
*allocate_sfd(union mysockaddr
*addr
, char *intname
)
473 struct serverfd
*sfd
;
476 /* may have a suitable one already */
477 for (sfd
= daemon
->sfds
; sfd
; sfd
= sfd
->next
)
478 if (sockaddr_isequal(&sfd
->source_addr
, addr
) &&
479 strcmp(intname
, sfd
->interface
) == 0)
482 /* need to make a new one. */
483 errno
= ENOMEM
; /* in case malloc fails. */
484 if (!(sfd
= whine_malloc(sizeof(struct serverfd
))))
487 if ((sfd
->fd
= socket(addr
->sa
.sa_family
, SOCK_DGRAM
, 0)) == -1)
493 if (!local_bind(sfd
->fd
, addr
, intname
, 0) || !fix_fd(sfd
->fd
))
495 errsave
= errno
; /* save error from bind. */
502 strcpy(sfd
->interface
, intname
);
503 sfd
->source_addr
= *addr
;
504 sfd
->next
= daemon
->sfds
;
509 /* create upstream sockets during startup, before root is dropped which may be needed
510 this allows query_port to be a low port and interface binding */
511 void pre_allocate_sfds(void)
515 if (daemon
->query_port
!= 0)
517 union mysockaddr addr
;
518 memset(&addr
, 0, sizeof(addr
));
519 addr
.in
.sin_family
= AF_INET
;
520 addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
521 addr
.in
.sin_port
= htons(daemon
->query_port
);
522 #ifdef HAVE_SOCKADDR_SA_LEN
523 addr
.in
.sin_len
= sizeof(struct sockaddr_in
);
525 allocate_sfd(&addr
, "");
527 memset(&addr
, 0, sizeof(addr
));
528 addr
.in6
.sin6_family
= AF_INET6
;
529 addr
.in6
.sin6_addr
= in6addr_any
;
530 addr
.in6
.sin6_port
= htons(daemon
->query_port
);
531 #ifdef HAVE_SOCKADDR_SA_LEN
532 addr
.in6
.sin6_len
= sizeof(struct sockaddr_in6
);
534 allocate_sfd(&addr
, "");
538 for (srv
= daemon
->servers
; srv
; srv
= srv
->next
)
539 if (!(srv
->flags
& (SERV_LITERAL_ADDRESS
| SERV_NO_ADDR
)) &&
540 !allocate_sfd(&srv
->source_addr
, srv
->interface
) &&
541 (daemon
->options
& OPT_NOWILD
))
543 prettyprint_addr(&srv
->addr
, daemon
->namebuff
);
544 if (strlen(srv
->interface
) != 0)
546 strcat(daemon
->namebuff
, " ");
547 strcat(daemon
->namebuff
, srv
->interface
);
549 die(_("failed to bind server socket for %s: %s"),
550 daemon
->namebuff
, EC_BADNET
);
555 void check_servers(void)
558 struct server
*new, *tmp
, *ret
= NULL
;
561 for (new = daemon
->servers
; new; new = tmp
)
565 if (!(new->flags
& (SERV_LITERAL_ADDRESS
| SERV_NO_ADDR
)))
567 port
= prettyprint_addr(&new->addr
, daemon
->namebuff
);
569 /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
570 if (new->addr
.sa
.sa_family
== AF_INET
&&
571 new->addr
.in
.sin_addr
.s_addr
== 0)
577 for (iface
= daemon
->interfaces
; iface
; iface
= iface
->next
)
578 if (sockaddr_isequal(&new->addr
, &iface
->addr
))
582 my_syslog(LOG_WARNING
, _("ignoring nameserver %s - local interface"), daemon
->namebuff
);
587 /* Do we need a socket set? */
588 if (!new->sfd
&& !(new->sfd
= allocate_sfd(&new->source_addr
, new->interface
)))
590 my_syslog(LOG_WARNING
,
591 _("ignoring nameserver %s - cannot make/bind socket: %s"),
592 daemon
->namebuff
, strerror(errno
));
598 /* reverse order - gets it right. */
602 if (new->flags
& (SERV_HAS_DOMAIN
| SERV_FOR_NODOTS
))
605 if (!(new->flags
& SERV_HAS_DOMAIN
))
606 s1
= _("unqualified"), s2
= _("names");
607 else if (strlen(new->domain
) == 0)
608 s1
= _("default"), s2
= "";
610 s1
= _("domain"), s2
= new->domain
;
612 if (new->flags
& SERV_NO_ADDR
)
613 my_syslog(LOG_INFO
, _("using local addresses only for %s %s"), s1
, s2
);
614 else if (!(new->flags
& SERV_LITERAL_ADDRESS
))
615 my_syslog(LOG_INFO
, _("using nameserver %s#%d for %s %s"), daemon
->namebuff
, port
, s1
, s2
);
617 else if (strlen(new->interface
) != 0)
618 my_syslog(LOG_INFO
, _("using nameserver %s#%d(via %s)"), daemon
->namebuff
, port
, new->interface
);
620 my_syslog(LOG_INFO
, _("using nameserver %s#%d"), daemon
->namebuff
, port
);
623 daemon
->servers
= ret
;
626 /* Return zero if no servers found, in that case we keep polling.
627 This is a protection against an update-time/write race on resolv.conf */
628 int reload_servers(char *fname
)
632 struct server
*old_servers
= NULL
;
633 struct server
*new_servers
= NULL
;
637 /* buff happens to be MAXDNAME long... */
638 if (!(f
= fopen(fname
, "r")))
640 my_syslog(LOG_ERR
, _("failed to read %s: %s"), fname
, strerror(errno
));
644 /* move old servers to free list - we can reuse the memory
645 and not risk malloc if there are the same or fewer new servers.
646 Servers which were specced on the command line go to the new list. */
647 for (serv
= daemon
->servers
; serv
;)
649 struct server
*tmp
= serv
->next
;
650 if (serv
->flags
& SERV_FROM_RESOLV
)
652 serv
->next
= old_servers
;
654 /* forward table rules reference servers, so have to blow them away */
659 serv
->next
= new_servers
;
665 while ((line
= fgets(daemon
->namebuff
, MAXDNAME
, f
)))
667 union mysockaddr addr
, source_addr
;
668 char *token
= strtok(line
, " \t\n\r");
672 if (strcmp(token
, "nameserver") != 0 && strcmp(token
, "server") != 0)
674 if (!(token
= strtok(NULL
, " \t\n\r")))
677 memset(&addr
, 0, sizeof(addr
));
678 memset(&source_addr
, 0, sizeof(source_addr
));
680 if ((addr
.in
.sin_addr
.s_addr
= inet_addr(token
)) != (in_addr_t
) -1)
682 #ifdef HAVE_SOCKADDR_SA_LEN
683 source_addr
.in
.sin_len
= addr
.in
.sin_len
= sizeof(source_addr
.in
);
685 source_addr
.in
.sin_family
= addr
.in
.sin_family
= AF_INET
;
686 addr
.in
.sin_port
= htons(NAMESERVER_PORT
);
687 source_addr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
688 source_addr
.in
.sin_port
= htons(daemon
->query_port
);
691 else if (inet_pton(AF_INET6
, token
, &addr
.in6
.sin6_addr
) > 0)
693 #ifdef HAVE_SOCKADDR_SA_LEN
694 source_addr
.in6
.sin6_len
= addr
.in6
.sin6_len
= sizeof(source_addr
.in6
);
696 source_addr
.in6
.sin6_family
= addr
.in6
.sin6_family
= AF_INET6
;
697 addr
.in6
.sin6_port
= htons(NAMESERVER_PORT
);
698 source_addr
.in6
.sin6_addr
= in6addr_any
;
699 source_addr
.in6
.sin6_port
= htons(daemon
->query_port
);
708 old_servers
= old_servers
->next
;
710 else if (!(serv
= whine_malloc(sizeof (struct server
))))
713 /* this list is reverse ordered:
714 it gets reversed again in check_servers */
715 serv
->next
= new_servers
;
718 serv
->source_addr
= source_addr
;
720 serv
->interface
[0] = 0;
722 serv
->flags
= SERV_FROM_RESOLV
;
723 serv
->queries
= serv
->failed_queries
= 0;
727 /* Free any memory not used. */
730 struct server
*tmp
= old_servers
->next
;
735 daemon
->servers
= new_servers
;
742 /* Use an IPv4 listener socket for ioctling */
743 struct in_addr
get_ifaddr(char *intr
)
748 for (l
= daemon
->listeners
; l
&& l
->family
!= AF_INET
; l
= l
->next
);
750 strncpy(ifr
.ifr_name
, intr
, IF_NAMESIZE
);
751 ifr
.ifr_addr
.sa_family
= AF_INET
;
753 if (!l
|| ioctl(l
->fd
, SIOCGIFADDR
, &ifr
) == -1)
754 ((struct sockaddr_in
*) &ifr
.ifr_addr
)->sin_addr
.s_addr
= -1;
756 return ((struct sockaddr_in
*) &ifr
.ifr_addr
)->sin_addr
;