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:
16
CHANGELOG
16
CHANGELOG
@@ -843,5 +843,21 @@ release 2.4
|
||||
|
||||
Added "bind-interfaces" option correctly.
|
||||
|
||||
release 2.5
|
||||
Made "where are we allocating addresses?" code in DHCP
|
||||
server cope with requests via a relay which is on a
|
||||
directly connected network for which there is not a
|
||||
configured netmask. This strange state of affairs occurs
|
||||
with win4lin. Thanks to Alex Melt and Jim Horner for bug
|
||||
reports and testing with this.
|
||||
|
||||
Fixed trivial-but-irritating missing #include which broke
|
||||
compilation on *BSD.
|
||||
|
||||
Force --bind-interfaces if IP-aliased interface
|
||||
specifications are used, since the sockets API provides
|
||||
no other sane way to determine which alias of an
|
||||
interface a packet was sent to. Thanks to Javier Kohen
|
||||
for the bug report.
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.4
|
||||
Version: 2.5
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.4
|
||||
Version: 2.5
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.4
|
||||
Version: 2.5
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Productivity/Networking/DNS/Servers
|
||||
|
||||
13
dnsmasq.8
13
dnsmasq.8
@@ -82,7 +82,14 @@ flags are given, dnsmasq listens on all available interfaces unless overridden b
|
||||
.B \-a
|
||||
or
|
||||
.B \-I
|
||||
flags.
|
||||
flags. If IP alias interfaces (eg "eth1:0") are used with
|
||||
.B --interface
|
||||
or
|
||||
.B --except-interface
|
||||
options, then the
|
||||
.B --bind-interfaces
|
||||
option will be automatically set. This is required for deeply boring
|
||||
sockets-API reasons.
|
||||
.TP
|
||||
.B \-I, --except-interface=<interface name>
|
||||
Do not listen on the specified interface.
|
||||
@@ -108,7 +115,9 @@ requests that it shouldn't reply to. This has the advantage of
|
||||
working even when interfaces come and go and change address. This
|
||||
option forces dnsmasq to really bind only the interfaces it is
|
||||
listening on. About the only time when this is useful is when
|
||||
running another nameserver on the same machine.
|
||||
running another nameserver on the same machine or using IP
|
||||
alias. Specifying interfaces with IP alias automatically turns this
|
||||
option on.
|
||||
.TP
|
||||
.B \-b, --bogus-priv
|
||||
Bogus private reverse lookups. All reverse lookups for private IP ranges (ie 192.168.x.x, etc)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
55
src/dhcp.c
55
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)
|
||||
@@ -170,16 +172,29 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||
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;
|
||||
struct in_addr netmask = context->netmask.s_addr ? context->netmask : iface_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))
|
||||
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;
|
||||
}
|
||||
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)
|
||||
|
||||
18
src/option.c
18
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (option == '?')
|
||||
free(new);
|
||||
else
|
||||
{
|
||||
if (new->lease_time < *min_leasetime)
|
||||
*min_leasetime = new->lease_time;
|
||||
*dhcp_conf = new;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -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