mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
import of dnsmasq-2.5.tar.gz
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
/* Author's email: simon@thekelleys.org.uk */
|
||||
|
||||
#define VERSION "2.4"
|
||||
#define VERSION "2.5"
|
||||
|
||||
#define FTABSIZ 150 /* max number of outstanding requests */
|
||||
#define TIMEOUT 20 /* drop queries after TIMEOUT seconds */
|
||||
|
||||
57
src/dhcp.c
57
src/dhcp.c
@@ -75,7 +75,8 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||
struct iovec iov[2];
|
||||
struct cmsghdr *cmptr;
|
||||
int sz, newlen, iface_index = 0;
|
||||
struct in_addr source, real_netmask, iface_addr, netmask_save, broadcast_save;
|
||||
struct in_addr source, iface_netmask, iface_addr, iface_broadcast;
|
||||
struct in_addr netmask_save, broadcast_save, router;
|
||||
#ifdef HAVE_BPF
|
||||
unsigned char iface_hwaddr[ETHER_ADDR_LEN];
|
||||
#endif
|
||||
@@ -112,7 +113,8 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||
if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
iface_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
|
||||
|
||||
if (!iface_index || !if_indextoname(iface_index, ifr.ifr_name))
|
||||
if (!(ifr.ifr_ifindex = iface_index) ||
|
||||
ioctl(dhcp_fd, SIOCGIFNAME, &ifr) == -1)
|
||||
return;
|
||||
|
||||
#elif defined(IP_RECVIF)
|
||||
@@ -169,17 +171,30 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||
/* If the packet came via a relay, use that address to look up the context,
|
||||
else use the address of the interface is arrived on. */
|
||||
source = mess->giaddr.s_addr ? mess->giaddr : iface_addr;
|
||||
|
||||
iface_netmask.s_addr = 0;
|
||||
iface_broadcast.s_addr = 0;
|
||||
|
||||
if (ioctl(dhcp_fd, SIOCGIFNETMASK, &ifr) != -1)
|
||||
{
|
||||
iface_netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
/* we can use the interface netmask if either the packet came direct,
|
||||
or it came via a relay listening on the same network. This sounds unlikely,
|
||||
but it happens with win4lin. */
|
||||
if ((source.s_addr & iface_netmask.s_addr) != (iface_addr.s_addr & iface_netmask.s_addr))
|
||||
iface_netmask.s_addr = 0;
|
||||
else if (ioctl(dhcp_fd, SIOCGIFBRDADDR, &ifr) != -1)
|
||||
iface_broadcast = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
|
||||
}
|
||||
|
||||
for (context = contexts; context; context = context->next)
|
||||
{
|
||||
if (!context->netmask.s_addr && !mess->giaddr.s_addr && ioctl(dhcp_fd, SIOCGIFNETMASK, &ifr) != -1)
|
||||
real_netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
else
|
||||
real_netmask = context->netmask;
|
||||
|
||||
if (real_netmask.s_addr &&
|
||||
(source.s_addr & real_netmask.s_addr) == (context->start.s_addr & real_netmask.s_addr) &&
|
||||
(source.s_addr & real_netmask.s_addr) == (context->end.s_addr & real_netmask.s_addr))
|
||||
struct in_addr netmask = context->netmask.s_addr ? context->netmask : iface_netmask;
|
||||
|
||||
if (netmask.s_addr &&
|
||||
(source.s_addr & netmask.s_addr) == (context->start.s_addr & netmask.s_addr) &&
|
||||
(source.s_addr & netmask.s_addr) == (context->end.s_addr & netmask.s_addr))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -192,26 +207,34 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||
netmask_save = context->netmask;
|
||||
broadcast_save = context->broadcast;
|
||||
|
||||
context->netmask = real_netmask;
|
||||
if (!context->netmask.s_addr)
|
||||
context->netmask = iface_netmask;
|
||||
|
||||
if (!context->broadcast.s_addr)
|
||||
{
|
||||
if (mess->giaddr.s_addr)
|
||||
context->broadcast.s_addr = (mess->giaddr.s_addr & real_netmask.s_addr) | ~real_netmask.s_addr;
|
||||
else if (ioctl(dhcp_fd, SIOCGIFBRDADDR, &ifr) != -1)
|
||||
context->broadcast = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
if (iface_broadcast.s_addr)
|
||||
context->broadcast = iface_broadcast;
|
||||
else
|
||||
context->broadcast.s_addr = (iface_addr.s_addr & real_netmask.s_addr) | ~real_netmask.s_addr;
|
||||
context->broadcast.s_addr = (source.s_addr & context->netmask.s_addr) | ~context->netmask.s_addr;
|
||||
}
|
||||
|
||||
if (ioctl(dhcp_fd, SIOCGIFMTU, &ifr) == -1)
|
||||
ifr.ifr_mtu = ETHERMTU;
|
||||
|
||||
/* Normally, we set the default route to point to the machine which is getting the
|
||||
DHCP broadcast, either this machine or a relay. In the special case that the relay
|
||||
is on the same network as us, we set the default route to us, not the relay.
|
||||
This is the win4lin scenario again. */
|
||||
if ((source.s_addr & context->netmask.s_addr) == (iface_addr.s_addr & context->netmask.s_addr))
|
||||
router = iface_addr;
|
||||
else
|
||||
router = source;
|
||||
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
newlen = dhcp_reply(context, iface_addr, ifr.ifr_name, ifr.ifr_mtu,
|
||||
rawpacket, sz, now, namebuff,
|
||||
dhcp_opts, dhcp_configs, domain_suffix, dhcp_file,
|
||||
dhcp_sname, dhcp_next_server);
|
||||
dhcp_sname, dhcp_next_server, router);
|
||||
lease_update_file(0, now);
|
||||
lease_update_dns();
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <limits.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -403,5 +404,5 @@ int dhcp_reply(struct dhcp_context *context,
|
||||
unsigned int sz, time_t now, char *namebuff,
|
||||
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
|
||||
char *domain_suffix, char *dhcp_file, char *dhcp_sname,
|
||||
struct in_addr dhcp_next_server);
|
||||
struct in_addr dhcp_next_server, struct in_addr router);
|
||||
|
||||
|
||||
@@ -104,7 +104,6 @@ static void send_from(int fd, int nowild, char *packet, int len,
|
||||
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
cmptr->cmsg_type = IPV6_PKTINFO;
|
||||
cmptr->cmsg_level = IPV6_LEVEL;
|
||||
cmptr->cmsg_level = IPPROTO_IPV6;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -368,11 +367,10 @@ struct server *receive_query(struct listener *listen, char *packet, char *mxname
|
||||
union mysockaddr source_addr;
|
||||
struct iname *tmp;
|
||||
struct all_addr dst_addr;
|
||||
int m, n, gotit = 0;
|
||||
int m, n, if_index = 0;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmptr;
|
||||
char if_name[IF_NAMESIZE];
|
||||
union {
|
||||
struct cmsghdr align; /* this ensures alignment */
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -414,20 +412,16 @@ struct server *receive_query(struct listener *listen, char *packet, char *mxname
|
||||
if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
dst_addr.addr.addr4 = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_spec_dst;
|
||||
if_indextoname(((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex, if_name);
|
||||
gotit = 1;
|
||||
if_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
|
||||
}
|
||||
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
|
||||
if (!(options & OPT_NOWILD) && listen->family == AF_INET)
|
||||
{
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
|
||||
{
|
||||
dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr));
|
||||
gotit = 1;
|
||||
}
|
||||
dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr));
|
||||
else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
|
||||
if_indextoname(((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index, if_name);
|
||||
if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -438,8 +432,7 @@ struct server *receive_query(struct listener *listen, char *packet, char *mxname
|
||||
if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == IPV6_PKTINFO)
|
||||
{
|
||||
dst_addr.addr.addr6 = ((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_addr;
|
||||
if_indextoname(((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_ifindex, if_name);
|
||||
gotit = 1;
|
||||
if_index =((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_ifindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -450,17 +443,31 @@ struct server *receive_query(struct listener *listen, char *packet, char *mxname
|
||||
/* enforce available interface configuration */
|
||||
if (!(options & OPT_NOWILD))
|
||||
{
|
||||
if (!gotit)
|
||||
struct ifreq ifr;
|
||||
|
||||
if (if_index == 0)
|
||||
return last_server;
|
||||
|
||||
if (except || names)
|
||||
{
|
||||
#ifdef SIOCGIFNAME
|
||||
ifr.ifr_ifindex = if_index;
|
||||
if (ioctl(listen->fd, SIOCGIFNAME, &ifr) == -1)
|
||||
return last_server;
|
||||
#else
|
||||
if (!if_indextoname(if_index, ifr.ifr_name))
|
||||
return last_server;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (tmp = except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, if_name) == 0))
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
return last_server;
|
||||
|
||||
if (names || addrs)
|
||||
{
|
||||
for (tmp = names; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, if_name) == 0))
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
break;
|
||||
if (!tmp)
|
||||
for (tmp = addrs; tmp; tmp = tmp->next)
|
||||
|
||||
@@ -145,7 +145,7 @@ struct irec *enumerate_interfaces(struct iname *names,
|
||||
lo->next = names->next;
|
||||
names->next = lo;
|
||||
}
|
||||
|
||||
|
||||
if ((new = add_iface(iface, ifr->ifr_name,
|
||||
&addr, names, addrs, except)))
|
||||
{
|
||||
|
||||
24
src/option.c
24
src/option.c
@@ -165,7 +165,6 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
char *conffile = CONFFILE;
|
||||
int conffile_set = 0;
|
||||
int lineno = 0;
|
||||
|
||||
opterr = 0;
|
||||
|
||||
*min_leasetime = UINT_MAX;
|
||||
@@ -359,6 +358,8 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
/* new->name may be NULL if someone does
|
||||
"interface=" to disable all interfaces except loop. */
|
||||
new->name = safe_string_alloc(optarg);
|
||||
if (strchr(optarg, ':'))
|
||||
flags |= OPT_NOWILD;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -368,6 +369,8 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
new->next = *if_except;
|
||||
*if_except = new;
|
||||
new->name = safe_string_alloc(optarg);
|
||||
if (strchr(optarg, ':'))
|
||||
flags |= OPT_NOWILD;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -684,14 +687,13 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
}
|
||||
|
||||
new->lease_time = atoi(a[leasepos]) * fac;
|
||||
if (new->lease_time < *min_leasetime)
|
||||
*min_leasetime = new->lease_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new->last = new->start;
|
||||
|
||||
if (new->lease_time < *min_leasetime)
|
||||
*min_leasetime = new->lease_time;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -803,17 +805,17 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
new->hostname = safe_string_alloc(a[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
new->lease_time = atoi(a[j]) * fac;
|
||||
if (new->lease_time < *min_leasetime)
|
||||
*min_leasetime = new->lease_time;
|
||||
}
|
||||
new->lease_time = atoi(a[j]) * fac;
|
||||
}
|
||||
|
||||
if (option == '?')
|
||||
free(new);
|
||||
else
|
||||
*dhcp_conf = new;
|
||||
{
|
||||
if (new->lease_time < *min_leasetime)
|
||||
*min_leasetime = new->lease_time;
|
||||
*dhcp_conf = new;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1023,7 +1025,7 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
|
||||
*resolv_files = 0;
|
||||
else if (*resolv_files && (*resolv_files)->next && (flags & OPT_NO_POLL))
|
||||
die("only one resolv.conf file allowed in no-poll mode.", NULL);
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
|
||||
unsigned char *req_options,
|
||||
struct dhcp_opt *config_opts,
|
||||
char *domainname, char *hostname,
|
||||
struct in_addr relay,
|
||||
struct in_addr router,
|
||||
struct in_addr iface_addr,
|
||||
int iface_mtu);
|
||||
|
||||
@@ -74,7 +74,7 @@ int dhcp_reply(struct dhcp_context *context,
|
||||
unsigned int sz, time_t now, char *namebuff,
|
||||
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
|
||||
char *domain_suffix, char *dhcp_file, char *dhcp_sname,
|
||||
struct in_addr dhcp_next_server)
|
||||
struct in_addr dhcp_next_server, struct in_addr router)
|
||||
{
|
||||
unsigned char *opt, *clid;
|
||||
struct dhcp_lease *lease;
|
||||
@@ -265,7 +265,7 @@ int dhcp_reply(struct dhcp_context *context,
|
||||
p = option_put(p, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(iface_addr.s_addr));
|
||||
p = option_put(p, end, OPTION_LEASE_TIME, 4, expires_time);
|
||||
p = do_req_options(context, p, end, req_options, dhcp_opts, domain_suffix,
|
||||
NULL, mess->giaddr, iface_addr, iface_mtu);
|
||||
NULL, router, iface_addr, iface_mtu);
|
||||
p = option_put(p, end, OPTION_END, 0, 0);
|
||||
|
||||
log_packet("OFFER" , &mess->yiaddr, mess->chaddr, iface_name, NULL);
|
||||
@@ -354,7 +354,7 @@ int dhcp_reply(struct dhcp_context *context,
|
||||
p = option_put(p, end, OPTION_T2, 4, ((renewal_time * 7)/8) - fuzz);
|
||||
}
|
||||
p = do_req_options(context, p, end, req_options, dhcp_opts, domain_suffix,
|
||||
hostname, mess->giaddr, iface_addr, iface_mtu);
|
||||
hostname, router, iface_addr, iface_mtu);
|
||||
p = option_put(p, end, OPTION_END, 0, 0);
|
||||
return p - (unsigned char *)mess;
|
||||
|
||||
@@ -364,7 +364,7 @@ int dhcp_reply(struct dhcp_context *context,
|
||||
p = option_put(p, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
|
||||
p = option_put(p, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(iface_addr.s_addr));
|
||||
p = do_req_options(context, p, end, req_options, dhcp_opts, domain_suffix,
|
||||
hostname, mess->giaddr, iface_addr, iface_mtu);
|
||||
hostname, router, iface_addr, iface_mtu);
|
||||
p = option_put(p, end, OPTION_END, 0, 0);
|
||||
|
||||
log_packet("ACK", &mess->ciaddr, mess->chaddr, iface_name, hostname);
|
||||
@@ -538,7 +538,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
|
||||
unsigned char *req_options,
|
||||
struct dhcp_opt *config_opts,
|
||||
char *domainname, char *hostname,
|
||||
struct in_addr relay,
|
||||
struct in_addr router,
|
||||
struct in_addr iface_addr,
|
||||
int iface_mtu)
|
||||
{
|
||||
@@ -563,7 +563,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
|
||||
if (in_list(req_options, OPTION_ROUTER) &&
|
||||
!option_find2(context, config_opts, OPTION_ROUTER))
|
||||
p = option_put(p, end, OPTION_ROUTER, INADDRSZ,
|
||||
ntohl(relay.s_addr ? relay.s_addr : iface_addr.s_addr ));
|
||||
ntohl(router.s_addr));
|
||||
|
||||
if (in_list(req_options, OPTION_DNSSERVER) &&
|
||||
!option_find2(context, config_opts, OPTION_DNSSERVER))
|
||||
|
||||
Reference in New Issue
Block a user