mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9f8d19bf5 | ||
|
|
535be2f5d3 |
No files matched your search
@@ -126,112 +126,110 @@ int iface_enumerate(int family, void *parm, callback_t callback)
|
|||||||
|
|
||||||
for (addrs = head; addrs; addrs = addrs->ifa_next)
|
for (addrs = head; addrs; addrs = addrs->ifa_next)
|
||||||
{
|
{
|
||||||
if (addrs->ifa_addr->sa_family == family)
|
int iface_index = if_nametoindex(addrs->ifa_name);
|
||||||
|
|
||||||
|
if (iface_index == 0 || !addrs->ifa_addr ||
|
||||||
|
addrs->ifa_addr->sa_family != family ||
|
||||||
|
(!addrs->ifa_netmask && family != AF_LINK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (family == AF_INET)
|
||||||
{
|
{
|
||||||
int iface_index = if_nametoindex(addrs->ifa_name);
|
struct in_addr addr, netmask, broadcast;
|
||||||
|
addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr;
|
||||||
if (iface_index == 0 || !addrs->ifa_addr ||
|
#ifdef HAVE_BSD_NETWORK
|
||||||
(!addrs->ifa_netmask && family != AF_LINK))
|
if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (family == AF_INET)
|
|
||||||
{
|
|
||||||
struct in_addr addr, netmask, broadcast;
|
|
||||||
addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr;
|
|
||||||
#ifdef HAVE_BSD_NETWORK
|
|
||||||
if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr)
|
|
||||||
continue;
|
|
||||||
#endif
|
#endif
|
||||||
netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
|
netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
|
||||||
if (addrs->ifa_broadaddr)
|
if (addrs->ifa_broadaddr)
|
||||||
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
|
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
|
||||||
else
|
else
|
||||||
broadcast.s_addr = 0;
|
broadcast.s_addr = 0;
|
||||||
if (!callback.af_inet(addr, iface_index, NULL, netmask, broadcast, parm))
|
if (!callback.af_inet(addr, iface_index, NULL, netmask, broadcast, parm))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else if (family == AF_INET6)
|
else if (family == AF_INET6)
|
||||||
{
|
{
|
||||||
struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr;
|
struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr;
|
||||||
unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr;
|
unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr;
|
||||||
int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id;
|
int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id;
|
||||||
int i, j, prefix = 0;
|
int i, j, prefix = 0;
|
||||||
u32 valid = 0xffffffff, preferred = 0xffffffff;
|
u32 valid = 0xffffffff, preferred = 0xffffffff;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
#ifdef HAVE_BSD_NETWORK
|
#ifdef HAVE_BSD_NETWORK
|
||||||
if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr))
|
if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr))
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||||
struct in6_ifreq ifr6;
|
struct in6_ifreq ifr6;
|
||||||
|
|
||||||
memset(&ifr6, 0, sizeof(ifr6));
|
memset(&ifr6, 0, sizeof(ifr6));
|
||||||
safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
|
safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
|
||||||
|
|
||||||
|
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
||||||
|
if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
|
||||||
|
{
|
||||||
|
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
|
||||||
|
flags |= IFACE_TENTATIVE;
|
||||||
|
|
||||||
|
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
|
||||||
|
flags |= IFACE_DEPRECATED;
|
||||||
|
|
||||||
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
|
||||||
if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
|
|
||||||
{
|
|
||||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
|
|
||||||
flags |= IFACE_TENTATIVE;
|
|
||||||
|
|
||||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
|
|
||||||
flags |= IFACE_DEPRECATED;
|
|
||||||
|
|
||||||
#ifdef IN6_IFF_TEMPORARY
|
#ifdef IN6_IFF_TEMPORARY
|
||||||
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)))
|
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)))
|
||||||
flags |= IFACE_PERMANENT;
|
flags |= IFACE_PERMANENT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IN6_IFF_PRIVACY
|
#ifdef IN6_IFF_PRIVACY
|
||||||
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY)))
|
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY)))
|
||||||
flags |= IFACE_PERMANENT;
|
flags |= IFACE_PERMANENT;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
||||||
if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1)
|
if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1)
|
||||||
{
|
{
|
||||||
valid = ifr6.ifr_ifru.ifru_lifetime.ia6t_vltime;
|
valid = ifr6.ifr_ifru.ifru_lifetime.ia6t_vltime;
|
||||||
preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime;
|
preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
|
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
|
||||||
if (netmask[i] != 0xff)
|
if (netmask[i] != 0xff)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i != IN6ADDRSZ && netmask[i])
|
if (i != IN6ADDRSZ && netmask[i])
|
||||||
for (j = 7; j > 0; j--, prefix++)
|
for (j = 7; j > 0; j--, prefix++)
|
||||||
if ((netmask[i] & (1 << j)) == 0)
|
if ((netmask[i] & (1 << j)) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* voodoo to clear interface field in address */
|
/* voodoo to clear interface field in address */
|
||||||
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
||||||
{
|
{
|
||||||
addr->s6_addr[2] = 0;
|
addr->s6_addr[2] = 0;
|
||||||
addr->s6_addr[3] = 0;
|
addr->s6_addr[3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!callback.af_inet6(addr, prefix, scope_id, iface_index, flags,
|
if (!callback.af_inet6(addr, prefix, scope_id, iface_index, flags,
|
||||||
(unsigned int) preferred, (unsigned int)valid, parm))
|
(unsigned int) preferred, (unsigned int)valid, parm))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
else if (family == AF_LINK)
|
|
||||||
{
|
|
||||||
/* Assume ethernet again here */
|
|
||||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
|
|
||||||
if (sdl->sdl_alen != 0 &&
|
|
||||||
!callback.af_local(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
else if (family == AF_LINK)
|
||||||
|
{
|
||||||
|
/* Assume ethernet again here */
|
||||||
|
struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
|
||||||
|
if (sdl->sdl_alen != 0 &&
|
||||||
|
!callback.af_local(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
errsave = errno;
|
errsave = errno;
|
||||||
freeifaddrs(head);
|
freeifaddrs(head);
|
||||||
|
|||||||
+11
-13
@@ -199,10 +199,15 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
struct frec_src *src;
|
struct frec_src *src;
|
||||||
unsigned int casediff = 0;
|
unsigned int casediff = 0;
|
||||||
unsigned int *bitvector = NULL;
|
unsigned int *bitvector = NULL;
|
||||||
unsigned short id;
|
unsigned short id = ntohs(header->id); /* Retrieve the id from the new query before we overwrite it. */
|
||||||
|
|
||||||
|
/* Get the case-scambled version of the query to resend. This is important because we
|
||||||
|
may fall through below and forward the query in the packet buffer again and we
|
||||||
|
want to use the same case scrambling as the first time. */
|
||||||
|
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||||||
|
|
||||||
for (src = &forward->frec_src; src; src = src->next)
|
for (src = &forward->frec_src; src; src = src->next)
|
||||||
if (src->orig_id == ntohs(header->id) &&
|
if (src->orig_id == id &&
|
||||||
sockaddr_isequal(&src->source, udpaddr))
|
sockaddr_isequal(&src->source, udpaddr))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -255,17 +260,10 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
Note the two names are guaranteed to be the same length and differ only in the case
|
Note the two names are guaranteed to be the same length and differ only in the case
|
||||||
of letters at this point.
|
of letters at this point.
|
||||||
|
|
||||||
Get the original query into the packet buffer and extract the query name it contains
|
The original query we sent is now in packet buffer and the query name in the
|
||||||
to calculate the difference in case scrambling. This is important because we
|
new instance is on daemon->namebuff. */
|
||||||
may fall through below and forward the query in the packet buffer again and we
|
|
||||||
want to use the same case scrambling as the first time.
|
if (extract_request(header, forward->stash_len, daemon->workspacename, NULL))
|
||||||
|
|
||||||
Retrieve the id from the new query before we overwrite it. */
|
|
||||||
|
|
||||||
id = ntohs(header->id);
|
|
||||||
|
|
||||||
if (blockdata_retrieve(forward->stash, forward->stash_len, (void *)header) &&
|
|
||||||
extract_request(header, forward->stash_len, daemon->workspacename, NULL))
|
|
||||||
{
|
{
|
||||||
unsigned int i, gobig = 0;
|
unsigned int i, gobig = 0;
|
||||||
char *s1, *s2;
|
char *s1, *s2;
|
||||||
|
|||||||
Reference in new issue
Block a user