import of dnsmasq-2.39.tar.gz

This commit is contained in:
Simon Kelley committed 2012-01-05 17:31:13 +00:00
1 parent 6b01084f8e
commit f2621c7ff0
36 files changed
+5572 -3349

No files matched your search

+2 -2
View File
@@ -73,8 +73,8 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
/* Only know how to do ethernet on *BSD */
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
{
syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
mess->htype, ifr->ifr_name);
my_syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
mess->htype, ifr->ifr_name);
return;
}
+49 -47
View File
@@ -691,7 +691,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
if (!f)
{
syslog(LOG_ERR, _("failed to load names from %s: %m"), filename);
my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
return 0;
}
@@ -725,7 +725,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
#endif
else
{
syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
continue;
}
@@ -749,10 +749,11 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
while ((token = strtok(NULL, " \t\n\r")) && (*token != '#'))
{
struct crec *cache;
int fqdn = !!strchr(token, '.');
if (canonicalise(token))
{
/* If set, add a version of the name with a default domain appended */
if ((opts & OPT_EXPAND) && domain_suffix && !strchr(token, '.') &&
if ((opts & OPT_EXPAND) && domain_suffix && !fqdn &&
(cache = malloc(sizeof(struct crec) +
strlen(token)+2+strlen(domain_suffix)-SMALLDNAME)))
{
@@ -771,14 +772,14 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
}
}
else
syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
}
}
fclose(f);
rehash(name_count);
syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
return name_count;
}
@@ -816,7 +817,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a
if ((opts & OPT_NO_HOSTS) && !addn_hosts)
{
if (cache_size > 0)
syslog(LOG_INFO, _("cleared cache"));
my_syslog(LOG_INFO, _("cleared cache"));
return;
}
@@ -862,11 +863,11 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr)
{
strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
syslog(LOG_WARNING,
_("not giving name %s to the DHCP lease of %s because "
"the name exists in %s with address %s"),
host_name, inet_ntoa(*host_address),
record_source(daemon->addn_hosts, crec->uid), daemon->namebuff);
my_syslog(LOG_WARNING,
_("not giving name %s to the DHCP lease of %s because "
"the name exists in %s with address %s"),
host_name, inet_ntoa(*host_address),
record_source(daemon->addn_hosts, crec->uid), daemon->namebuff);
}
return;
}
@@ -903,62 +904,63 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
void dump_cache(struct daemon *daemon, time_t now)
{
syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
(unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted);
my_syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
(unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted);
if ((daemon->options & (OPT_DEBUG | OPT_LOG)) &&
(addrbuff || (addrbuff = malloc(ADDRSTRLEN))))
{
struct crec *cache ;
int i;
syslog(LOG_DEBUG, "Host Address Flags Expires");
my_syslog(LOG_DEBUG, "Host Address Flags Expires");
for (i=0; i<hash_size; i++)
for (cache = hash_table[i]; cache; cache = cache->hash_next)
{
char *a, *p = daemon->namebuff;
p += sprintf(p, "%-40.40s ", cache_get_name(cache));
if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
addrbuff[0] = 0;
a = "";
else if (cache->flags & F_CNAME)
{
addrbuff[0] = 0;
addrbuff[ADDRSTRLEN-1] = 0;
a = "";
if (!is_outdated_cname_pointer(cache))
strncpy(addrbuff, cache_get_name(cache->addr.cname.cache), ADDRSTRLEN);
a = cache_get_name(cache->addr.cname.cache);
}
#ifdef HAVE_IPV6
else if (cache->flags & F_IPV4)
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
else if (cache->flags & F_IPV6)
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
else
{
a = addrbuff;
if (cache->flags & F_IPV4)
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
else if (cache->flags & F_IPV6)
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
}
#else
else
strcpy(addrbuff, inet_ntoa(cache->addr.addr.addr.addr4));
a = inet_ntoa(cache->addr.addr.addr.addr4);
#endif
syslog(LOG_DEBUG,
p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s ", a,
cache->flags & F_IPV4 ? "4" : "",
cache->flags & F_IPV6 ? "6" : "",
cache->flags & F_CNAME ? "C" : "",
cache->flags & F_FORWARD ? "F" : " ",
cache->flags & F_REVERSE ? "R" : " ",
cache->flags & F_IMMORTAL ? "I" : " ",
cache->flags & F_DHCP ? "D" : " ",
cache->flags & F_NEG ? "N" : " ",
cache->flags & F_NXDOMAIN ? "X" : " ",
cache->flags & F_HOSTS ? "H" : " ");
#ifdef HAVE_BROKEN_RTC
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %lu",
p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
#else
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %s",
p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
/* ctime includes trailing \n - eat it */
*(p-1) = 0;
#endif
cache_get_name(cache), addrbuff,
cache->flags & F_IPV4 ? "4" : "",
cache->flags & F_IPV6 ? "6" : "",
cache->flags & F_CNAME ? "C" : "",
cache->flags & F_FORWARD ? "F" : " ",
cache->flags & F_REVERSE ? "R" : " ",
cache->flags & F_IMMORTAL ? "I" : " ",
cache->flags & F_DHCP ? "D" : " ",
cache->flags & F_NEG ? "N" : " ",
cache->flags & F_NXDOMAIN ? "X" : " ",
cache->flags & F_HOSTS ? "H" : " ",
#ifdef HAVE_BROKEN_RTC
cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now)
#else
cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd))
#endif
);
}
}
my_syslog(LOG_DEBUG, daemon->namebuff);
}
}
}
static char *record_source(struct hostsfile *addn_hosts, int index)
@@ -1063,8 +1065,8 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr,
name = ".";
if ((flags & F_FORWARD) | (flags & F_NEG))
syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
else if (flags & F_REVERSE)
syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
my_syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
}
+3 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -10,7 +10,7 @@
GNU General Public License for more details.
*/
#define VERSION "2.38"
#define VERSION "2.39"
#define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* max no children for TCP requests */
@@ -50,6 +50,7 @@
#define DHCP_CLIENT_PORT 68
#define TFTP_PORT 69
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
#define LOG_MAX 5 /* log-queue length */
/* DBUS interface specifics */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
+3 -2
View File
@@ -109,7 +109,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
}
#ifndef HAVE_IPV6
syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
#else
if (i == sizeof(struct in6_addr)-1)
{
@@ -208,6 +208,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
tmp = serv->next;
if (serv->flags & SERV_MARK)
{
server_gone(daemon, serv);
*up = serv->next;
free(serv);
}
@@ -235,7 +236,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
}
else if (strcmp(method, "SetServers") == 0)
{
syslog(LOG_INFO, _("setting upstream servers from DBus"));
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
dbus_read_servers(daemon, message);
check_servers(daemon);
}
+11 -11
View File
@@ -216,7 +216,7 @@ void dhcp_packet(struct daemon *daemon, time_t now)
{
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1)
{
syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
my_syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
return;
}
else
@@ -347,8 +347,8 @@ static int complete_context(struct daemon *daemon, struct in_addr local, int if_
{
strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
my_syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
}
context->netmask = netmask;
}
@@ -664,7 +664,7 @@ void dhcp_read_ethers(struct daemon *daemon)
if (!f)
{
syslog(LOG_ERR, _("failed to read %s:%m"), ETHERSFILE);
my_syslog(LOG_ERR, _("failed to read %s:%s"), ETHERSFILE, strerror(errno));
return;
}
@@ -699,7 +699,7 @@ void dhcp_read_ethers(struct daemon *daemon)
*ip = 0;
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
{
syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
my_syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
continue;
}
@@ -712,7 +712,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{
if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
{
syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
my_syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
continue;
}
@@ -726,7 +726,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{
if (!canonicalise(ip))
{
syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
my_syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
continue;
}
@@ -780,7 +780,7 @@ void dhcp_read_ethers(struct daemon *daemon)
fclose(f);
syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
my_syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
}
void dhcp_update_configs(struct dhcp_config *configs)
@@ -806,8 +806,8 @@ void dhcp_update_configs(struct dhcp_config *configs)
(crec->flags & F_HOSTS))
{
if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
my_syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
else
{
config->addr = crec->addr.addr.addr.addr4;
@@ -842,7 +842,7 @@ char *strip_hostname(struct daemon *daemon, char *hostname)
{
if (!daemon->domain_suffix || !hostname_isequal(dot+1, daemon->domain_suffix))
{
syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname);
my_syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname);
hostname = NULL;
}
else
+59 -46
View File
@@ -59,7 +59,7 @@ int main (int argc, char **argv)
time_t now, last = 0;
struct sigaction sigact;
struct iname *if_tmp;
int piperead, pipefd[2];
int piperead, pipefd[2], log_fd;
unsigned char sig;
#ifndef NO_GETTEXT
@@ -84,6 +84,7 @@ int main (int argc, char **argv)
sigaction(SIGPIPE, &sigact, NULL);
daemon = read_opts(argc, argv, compile_opts);
log_fd = log_start(daemon);
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
@@ -250,7 +251,7 @@ int main (int argc, char **argv)
#endif
for (i=0; i<64; i++)
{
if (i == piperead || i == pipewrite)
if (i == piperead || i == pipewrite || i == log_fd)
continue;
#ifdef HAVE_LINUX_NETWORK
@@ -279,8 +280,8 @@ int main (int argc, char **argv)
}
/* if we are to run scripts, we need to fork a helper before dropping root. */
daemon->helperfd = create_helper(daemon);
daemon->helperfd = create_helper(daemon, log_fd);
if (!(daemon->options & OPT_DEBUG))
{
/* UID changing, etc */
@@ -335,47 +336,48 @@ int main (int argc, char **argv)
}
}
log_start(daemon);
#ifdef HAVE_LINUX_NETWORK
if (daemon->options & OPT_DEBUG)
prctl(PR_SET_DUMPABLE, 1);
#endif
if (daemon->cachesize != 0)
syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
else
syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
#ifdef HAVE_DBUS
if (daemon->options & OPT_DBUS)
{
if (daemon->dbus)
syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
else
syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
}
#endif
if (bind_fallback)
syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
if (!(daemon->options & OPT_NOWILD))
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
if (if_tmp->name && !if_tmp->used)
syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
if (daemon->options & OPT_NO_RESOLV)
{
if (daemon->resolv_files && !daemon->resolv_files->is_default)
syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
daemon->resolv_files = NULL;
if (!daemon->servers)
syslog(LOG_WARNING, _("warning: no upstream servers configured"));
my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
}
if (daemon->max_logs != 0)
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
if (daemon->dhcp)
{
struct dhcp_context *dhcp_tmp;
@@ -384,11 +386,11 @@ int main (int argc, char **argv)
{
prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
syslog(LOG_INFO,
(dhcp_tmp->flags & CONTEXT_STATIC) ?
_("DHCP, static leases only on %.0s%s, lease time %s") :
_("DHCP, IP range %s -- %s, lease time %s"),
daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
my_syslog(LOG_INFO,
(dhcp_tmp->flags & CONTEXT_STATIC) ?
_("DHCP, static leases only on %.0s%s, lease time %s") :
_("DHCP, IP range %s -- %s, lease time %s"),
daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
}
}
@@ -402,13 +404,13 @@ int main (int argc, char **argv)
max_fd = FD_SETSIZE;
#endif
syslog(LOG_INFO, "TFTP %s%s %s",
daemon->tftp_prefix ? _("root is ") : _("enabled"),
daemon->tftp_prefix ? daemon->tftp_prefix: "",
daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
my_syslog(LOG_INFO, "TFTP %s%s %s",
daemon->tftp_prefix ? _("root is ") : _("enabled"),
daemon->tftp_prefix ? daemon->tftp_prefix: "",
daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
/* This is a guess, it assumes that for small limits,
disjoint files might be servered, but for large limits,
disjoint files might be served, but for large limits,
a single file will be sent to may clients (the file only needs
one fd). */
@@ -424,9 +426,9 @@ int main (int argc, char **argv)
if (daemon->tftp_max > max_fd)
{
daemon->tftp_max = max_fd;
syslog(LOG_WARNING,
_("restricting maximum simultaneous TFTP transfers to %d"),
daemon->tftp_max);
my_syslog(LOG_WARNING,
_("restricting maximum simultaneous TFTP transfers to %d"),
daemon->tftp_max);
}
}
#endif
@@ -434,11 +436,9 @@ int main (int argc, char **argv)
if (!(daemon->options & OPT_DEBUG) && (getuid() == 0 || geteuid() == 0))
{
if (bad_capabilities)
{
errno = bad_capabilities;
syslog(LOG_WARNING, _("warning: setting capabilities failed: %m"));
}
syslog(LOG_WARNING, _("running as root"));
my_syslog(LOG_WARNING, _("warning: setting capabilities failed: %s"), strerror(bad_capabilities));
my_syslog(LOG_WARNING, _("running as root"));
}
check_servers(daemon);
@@ -498,7 +498,11 @@ int main (int argc, char **argv)
FD_SET(daemon->helperfd, &wset);
bump_maxfd(daemon->helperfd, &maxfd);
}
/* must do this just before select(), when we know no
more calls to my_syslog() can occur */
set_log_writer(&wset, &maxfd);
if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
{
/* otherwise undefined after error */
@@ -507,6 +511,8 @@ int main (int argc, char **argv)
now = dnsmasq_time();
check_log_writer(&wset);
/* Check for changes to resolv files once per second max. */
/* Don't go silent for long periods if the clock goes backwards. */
if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0)
@@ -530,7 +536,7 @@ int main (int argc, char **argv)
if (stat(res->name, &statbuf) == -1)
{
if (!res->logged)
syslog(LOG_WARNING, _("failed to access %s: %m"), res->name);
my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
res->logged = 1;
}
else
@@ -552,7 +558,7 @@ int main (int argc, char **argv)
static int warned = 0;
if (reload_servers(latest->name, daemon))
{
syslog(LOG_INFO, _("reading %s"), latest->name);
my_syslog(LOG_INFO, _("reading %s"), latest->name);
warned = 0;
check_servers(daemon);
if (daemon->options & OPT_RELOAD)
@@ -563,7 +569,7 @@ int main (int argc, char **argv)
latest->mtime = 0;
if (!warned)
{
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
warned = 1;
}
}
@@ -622,7 +628,7 @@ int main (int argc, char **argv)
if (daemon->lease_stream)
fclose(daemon->lease_stream);
syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
exit(0);
}
@@ -657,9 +663,9 @@ int main (int argc, char **argv)
{
char *err;
if ((err = dbus_init(daemon)))
syslog(LOG_WARNING, _("DBus error: %s"), err);
my_syslog(LOG_WARNING, _("DBus error: %s"), err);
if (daemon->dbus)
syslog(LOG_INFO, _("connected to system DBus"));
my_syslog(LOG_INFO, _("connected to system DBus"));
}
check_dbus_listeners(daemon, &rset, &wset, &eset);
#endif
@@ -969,7 +975,7 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
difftime(now, start) < (float)PING_WAIT;)
{
struct timeval tv;
fd_set rset;
fd_set rset, wset;
struct sockaddr_in faddr;
int maxfd = fd;
socklen_t len = sizeof(faddr);
@@ -978,13 +984,20 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
tv.tv_sec = 0;
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_SET(fd, &rset);
set_dns_listeners(daemon, now, &rset, &maxfd);
if (select(maxfd+1, &rset, NULL, NULL, &tv) < 0)
FD_ZERO(&rset);
set_log_writer(&wset, &maxfd);
if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
{
FD_ZERO(&rset);
FD_ZERO(&wset);
}
now = dnsmasq_time();
check_log_writer(&wset);
check_dns_listeners(daemon, &rset, now);
#ifdef HAVE_TFTP
+29 -5
View File
@@ -43,6 +43,7 @@
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/un.h>
#include <limits.h>
#include <net/if.h>
#include <unistd.h>
@@ -115,6 +116,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data);
#define OPT_TFTP (1<<25)
#define OPT_TFTP_SECURE (1<<26)
#define OPT_TFTP_NOBLOCK (1<<27)
#define OPT_LOG_OPTS (1<<28)
struct all_addr {
union {
@@ -154,6 +156,12 @@ struct ptr_record {
struct ptr_record *next;
};
struct interface_name {
char *name; /* domain name */
char *intr; /* interface name */
struct interface_name *next;
};
union bigname {
char name[MAXDNAME];
union bigname *next; /* freelist */
@@ -377,8 +385,15 @@ struct dhcp_boot {
struct dhcp_boot *next;
};
#define MATCH_VENDOR 1
#define MATCH_USER 2
#define MATCH_CIRCUIT 3
#define MATCH_REMOTE 4
#define MATCH_SUBSCRIBER 5
/* vendorclass, userclass, remote-id or cicuit-id */
struct dhcp_vendor {
int len, is_vendor;
int len, match_type;
char *data;
struct dhcp_netid netid;
struct dhcp_vendor *next;
@@ -461,6 +476,7 @@ struct daemon {
struct mx_srv_record *mxnames;
struct txt_record *txt;
struct ptr_record *ptr;
struct interface_name *int_names;
char *mxtarget;
char *lease_file;
char *username, *groupname;
@@ -471,6 +487,8 @@ struct daemon {
struct bogus_addr *bogus_addr;
struct server *servers;
int log_fac; /* log facility */
char *log_file; /* optional log file */
int max_logs; /* queue limit */
int cachesize, ftabsize;
int port, query_port;
unsigned long local_ttl;
@@ -569,8 +587,6 @@ unsigned short rand16(void);
int legal_char(char c);
int canonicalise(char *s);
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
void die(char *message, char *arg1);
void complain(char *message, int lineno, char *file);
void *safe_malloc(size_t size);
int sa_len(union mysockaddr *addr);
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
@@ -587,11 +603,18 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(struct daemon *daemon, unsigned char *mac, int len);
void bump_maxfd(int fd, int *max);
void log_start(struct daemon *daemon);
int read_write(int fd, unsigned char *packet, int size, int rw);
/* log.c */
void die(char *message, char *arg1);
int log_start(struct daemon *daemon);
void my_syslog(int priority, const char *format, ...);
void set_log_writer(fd_set *set, int *maxfdp);
void check_log_writer(fd_set *set);
/* option.c */
struct daemon *read_opts (int argc, char **argv, char *compile_opts);
char *option_string(unsigned char opt);
/* forward.c */
void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now);
@@ -611,6 +634,7 @@ struct listener *create_bound_listeners(struct daemon *daemon);
int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
struct ifreq *ifr, int *indexp);
int fix_fd(int fd);
struct in_addr get_ifaddr(struct daemon* daemon, char *intr);
/* dhcp.c */
void dhcp_init(struct daemon *daemon);
@@ -690,7 +714,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp,
#endif
/* helper.c */
int create_helper(struct daemon *daemon);
int create_helper(struct daemon *daemon, int log_fd);
void helper_write(struct daemon *daemon);
void queue_script(struct daemon *daemon, int action,
struct dhcp_lease *lease, char *hostname);
+1 -1
View File
@@ -373,7 +373,7 @@ static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now,
server && !(server->flags & SERV_WARNED_RECURSIVE))
{
prettyprint_addr(&server->addr, daemon->namebuff);
syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
if (!(daemon->options & OPT_LOG))
server->flags |= SERV_WARNED_RECURSIVE;
}
+6 -9
View File
@@ -40,7 +40,7 @@ struct script_data
static struct script_data *buf;
static size_t bytes_in_buf, buf_size;
int create_helper(struct daemon *daemon)
int create_helper(struct daemon *daemon, int log_fd)
{
pid_t pid;
int i, pipefd[2];
@@ -72,11 +72,8 @@ int create_helper(struct daemon *daemon)
/* close all the sockets etc, we don't need them here */
for (i = 0; i < 64; i++)
if (i != STDOUT_FILENO && i != STDERR_FILENO &&
i != STDIN_FILENO && i != pipefd[0])
i != STDIN_FILENO && i != pipefd[0] && i != log_fd)
close(i);
/* we open our own log connection. */
log_start(daemon);
/* don't give our end of the pipe to our children */
if ((i = fcntl(pipefd[0], F_GETFD)) != -1)
@@ -142,9 +139,9 @@ int create_helper(struct daemon *daemon)
int status;
waitpid(pid, &status, 0);
if (WIFSIGNALED(status))
syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status));
my_syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status));
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status));
my_syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status));
continue;
}
@@ -213,8 +210,8 @@ int create_helper(struct daemon *daemon)
action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*)NULL);
/* log socket should still be open, right? */
syslog(LOG_ERR, _("failed to execute %s: %m"),
daemon->lease_change_command);
my_syslog(LOG_ERR, _("failed to execute %s: %s"),
daemon->lease_change_command, strerror(errno));
_exit(0);
}
}
+7 -7
View File
@@ -70,7 +70,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (stat(daemon->lease_file, &statbuf) == -1)
{
if (!logged_lease)
syslog(LOG_WARNING, _("failed to access %s: %m"), daemon->lease_file);
my_syslog(LOG_WARNING, _("failed to access %s: %s"), daemon->lease_file, strerror(errno));
logged_lease = 1;
return;
}
@@ -86,11 +86,11 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (!(fp = fopen (daemon->lease_file, "r")))
{
syslog (LOG_ERR, _("failed to load %s: %m"), daemon->lease_file);
my_syslog (LOG_ERR, _("failed to load %s: %s"), daemon->lease_file, strerror(errno));
return;
}
syslog (LOG_INFO, _("reading %s"), daemon->lease_file);
my_syslog (LOG_INFO, _("reading %s"), daemon->lease_file);
while ((next_token(token, MAXTOK, fp)))
{
@@ -112,7 +112,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (!canonicalise(hostname))
{
*hostname = 0;
syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
}
}
else if ((strcmp(token, "ends") == 0) ||
@@ -173,9 +173,9 @@ void load_dhcp(struct daemon *daemon, time_t now)
{
if (!daemon->domain_suffix || hostname_isequal(dot+1, daemon->domain_suffix))
{
syslog(LOG_WARNING,
_("Ignoring DHCP lease for %s because it has an illegal domain part"),
hostname);
my_syslog(LOG_WARNING,
_("Ignoring DHCP lease for %s because it has an illegal domain part"),
hostname);
continue;
}
*dot = 0;
+3 -3
View File
@@ -214,9 +214,9 @@ void lease_update_file(struct daemon *daemon, time_t now)
if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
next_event = LEASE_RETRY + now;
syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"),
daemon->lease_file, strerror(err),
(unsigned int)difftime(next_event, now));
my_syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"),
daemon->lease_file, strerror(err),
(unsigned int)difftime(next_event, now));
}
if (next_event != 0)
+342
View File
@@ -0,0 +1,342 @@
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "dnsmasq.h"
/* Implement logging to /dev/log asynchronously. If syslogd is
making DNS lookups through dnsmasq, and dnsmasq blocks awaiting
syslogd, then the two daemons can deadlock. We get around this
by not blocking when talking to syslog, instead we queue up to
MAX_LOGS messages. If more are queued, they will be dropped,
and the drop event itself logged. */
/* The "wire" protocol for logging is defined in RFC 3164 */
/* From RFC 3164 */
#define MAX_MESSAGE 1024
/* defaults in case we die() before we log_start() */
static int log_fac = LOG_DAEMON;
static int log_stderr = 0;
static int log_fd = -1;
static int log_to_file = 0;
static int entries_alloced = 0;
static int entries_lost = 0;
static int connection_good = 1;
static int max_logs = 0;
struct log_entry {
int offset, length;
struct log_entry *next;
char payload[MAX_MESSAGE];
};
static struct log_entry *entries = NULL;
static struct log_entry *free_entries = NULL;
int log_start(struct daemon *daemon)
{
int flags;
log_stderr = !!(daemon->options & OPT_DEBUG);
if (daemon->log_fac != -1)
log_fac = daemon->log_fac;
#ifdef LOG_LOCAL0
else if (daemon->options & OPT_DEBUG)
log_fac = LOG_LOCAL0;
#endif
if (daemon->log_file)
{
log_fd = open(daemon->log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
log_to_file = 1;
daemon->max_logs = 0;
}
else
log_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (log_fd == -1)
die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log");
/* if queuing is inhibited, make sure we allocate
the one required buffer now. */
if ((max_logs = daemon->max_logs) == 0)
{
free_entries = safe_malloc(sizeof(struct log_entry));
free_entries->next = NULL;
entries_alloced = 1;
}
if ((flags = fcntl(log_fd, F_GETFD)) != -1)
fcntl(log_fd, F_SETFD, flags | FD_CLOEXEC);
/* if max_log is zero, leave the socket blocking */
if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
return log_fd;
}
static void log_write(void)
{
ssize_t rc;
int tried_stream = 0;
while (entries)
{
connection_good = 1;
if ((rc = write(log_fd, entries->payload + entries->offset, entries->length)) != -1)
{
entries->length -= rc;
entries->offset += rc;
if (entries->length == 0)
{
struct log_entry *tmp = entries;
entries = tmp->next;
tmp->next = free_entries;
free_entries = tmp;
if (entries_lost != 0)
{
int e = entries_lost;
entries_lost = 0; /* avoid wild recursion */
my_syslog(LOG_WARNING, _("overflow: %d log entries lost"), e);
}
}
continue;
}
if (errno == EINTR)
continue;
if (errno == EAGAIN)
return; /* syslogd busy, go again when select() or poll() says so */
if (errno == ENOBUFS)
{
connection_good = 0;
return;
}
/* Once a stream socket hits EPIPE, we have to close and re-open */
if (errno == EPIPE)
goto reopen_stream;
if (!log_to_file &&
(errno == ECONNREFUSED ||
errno == ENOTCONN ||
errno == EDESTADDRREQ ||
errno == ECONNRESET))
{
/* socket went (syslogd down?), try and reconnect. If we fail,
stop trying until the next call to my_syslog()
ECONNREFUSED -> connection went down
ENOTCONN -> nobody listening
(ECONNRESET, EDESTADDRREQ are *BSD equivalents)
EPIPE comes from broken stream socket (we ignore SIGPIPE) */
struct sockaddr_un logaddr;
#ifdef HAVE_SOCKADDR_SA_LEN
logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1;
#endif
logaddr.sun_family = AF_LOCAL;
strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
/* Got connection back? try again. */
if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1)
continue;
/* errors from connect which mean we should keep trying */
if (errno == ENOENT ||
errno == EALREADY ||
errno == ECONNREFUSED ||
errno == EISCONN ||
errno == EINTR ||
errno == EAGAIN)
{
/* try again on next syslog() call */
connection_good = 0;
return;
}
/* we start with a SOCK_DGRAM socket, but syslog may want SOCK_STREAM */
if (!tried_stream && errno == EPROTOTYPE)
{
reopen_stream:
tried_stream = 1;
close(log_fd);
if ((log_fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1)
{
int flags;
if ((flags = fcntl(log_fd, F_GETFD)) != -1)
fcntl(log_fd, F_SETFD, flags | FD_CLOEXEC);
/* if max_log is zero, leave the socket blocking */
if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
continue;
}
}
}
/* give up - fall back to syslog() - this handles out-of-space
when logging to a file, for instance. */
log_fd = -1;
my_syslog(LOG_CRIT, _("log failed: %s"), strerror(errno));
return;
}
}
void my_syslog(int priority, const char *format, ...)
{
va_list ap;
struct log_entry *entry;
time_t time_now;
char *p;
size_t len;
va_start(ap, format);
if (log_stderr)
{
fprintf(stderr, "dnsmasq: ");
vfprintf(stderr, format, ap);
fputc('\n', stderr);
}
if (log_fd == -1)
{
/* fall-back to syslog if we die during startup or fail during running. */
static int isopen = 0;
if (!isopen)
{
openlog("dnsmasq", LOG_PID, log_fac);
isopen = 1;
}
vsyslog(priority, format, ap);
va_end(ap);
return;
}
if ((entry = free_entries))
free_entries = entry->next;
else if (entries_alloced < max_logs && (entry = malloc(sizeof(struct log_entry))))
entries_alloced++;
if (!entry)
entries_lost++;
else
{
/* add to end of list, consumed from the start */
entry->next = NULL;
if (!entries)
entries = entry;
else
{
struct log_entry *tmp;
for (tmp = entries; tmp->next; tmp = tmp->next);
tmp->next = entry;
}
time(&time_now);
p = entry->payload;
if (!log_to_file)
p += sprintf(p, "<%d>", priority | log_fac);
p += sprintf(p, "%.15s dnsmasq[%d]: ", ctime(&time_now) + 4, getpid());
len = p - entry->payload;
len += vsnprintf(p, MAX_MESSAGE - len, format, ap) + 1; /* include zero-terminator */
entry->length = len > MAX_MESSAGE ? MAX_MESSAGE : len;
entry->offset = 0;
/* replace terminator with \n */
if (log_to_file)
entry->payload[entry->length - 1] = '\n';
}
/* almost always, logging won't block, so try and write this now,
to save collecting too many log messages during a select loop. */
log_write();
/* Since we're doing things asynchronously, a cache-dump, for instance,
can now generate log lines very fast. With a small buffer (desirable),
that means it can overflow the log-buffer very quickly,
so that the cache dump becomes mainly a count of how many lines
overflowed. To avoid this, we delay here, the delay is controlled
by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
The scaling stuff ensures that when the queue is bigger than 8, the delay
only occurs for the last 8 entries. Once the queue is full, we stop delaying
to preserve performance.
*/
if (entries && max_logs != 0)
{
int d;
for (d = 0,entry = entries; entry; entry = entry->next, d++);
if (d == max_logs)
d = 0;
else if (max_logs > 8)
d -= max_logs - 8;
if (d > 0)
{
struct timespec waiter;
waiter.tv_sec = 0;
waiter.tv_nsec = 1000000 << (d - 1); /* 1 ms */
nanosleep(&waiter, NULL);
/* Have another go now */
log_write();
}
}
va_end(ap);
}
void set_log_writer(fd_set *set, int *maxfdp)
{
if (entries && log_fd != -1 && connection_good)
{
FD_SET(log_fd, set);
bump_maxfd(log_fd, maxfdp);
}
}
void check_log_writer(fd_set *set)
{
if (log_fd != -1 && FD_ISSET(log_fd, set))
log_write();
}
void die(char *message, char *arg1)
{
char *errmess = strerror(errno);
if (!arg1)
arg1 = errmess;
log_stderr = 1; /* print as well as log when we die.... */
my_syslog(LOG_CRIT, message, arg1, errmess);
log_stderr = 0;
my_syslog(LOG_CRIT, _("FAILED to start up"));
exit(1);
}
+1 -1
View File
@@ -229,7 +229,7 @@ static void nl_err(struct nlmsghdr *h)
{
struct nlmsgerr *err = NLMSG_DATA(h);
if (err->error != 0)
syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
}
/* We arrange to receive netlink multicast messages whenever the network route is added.
+24 -9
View File
@@ -38,7 +38,7 @@ int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
if (!(newindex = if_nametoindex(bridge->iface)))
{
syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
return 0;
}
else
@@ -492,7 +492,7 @@ void check_servers(struct daemon *daemon)
break;
if (iface)
{
syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
free(new);
continue;
}
@@ -500,8 +500,9 @@ void check_servers(struct daemon *daemon)
/* Do we need a socket set? */
if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds)))
{
syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %m"), daemon->namebuff);
my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %s"),
daemon->namebuff, strerror(errno));
free(new);
continue;
}
@@ -520,12 +521,12 @@ void check_servers(struct daemon *daemon)
s1 = _("unqualified"), s2 = _("domains");
if (new->flags & SERV_NO_ADDR)
syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
else if (!(new->flags & SERV_LITERAL_ADDRESS))
syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
}
else
syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
}
daemon->servers = ret;
@@ -545,7 +546,7 @@ int reload_servers(char *fname, struct daemon *daemon)
/* buff happens to be MAXDNAME long... */
if (!(f = fopen(fname, "r")))
{
syslog(LOG_ERR, _("failed to read %s: %m"), fname);
my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
return 0;
}
@@ -644,8 +645,22 @@ int reload_servers(char *fname, struct daemon *daemon)
}
/* Use an IPv4 listener socket for ioctling */
struct in_addr get_ifaddr(struct daemon* daemon, char *intr)
{
struct listener *l;
struct ifreq ifr;
for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
ifr.ifr_addr.sa_family = AF_INET;
if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
}
+434 -284
View File
File diff suppressed because it is too large. Load diff
+123 -66
View File
@@ -485,15 +485,16 @@ unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsi
/* is addr in the non-globally-routed IP space? */
static int private_net(struct all_addr *addrp)
static int private_net(struct in_addr addr)
{
struct in_addr addr = *(struct in_addr *)addrp;
if (inet_netof(addr) == 0xA ||
(inet_netof(addr) >= 0xAC10 && inet_netof(addr) < 0xAC20) ||
(inet_netof(addr) >> 8) == 0xC0A8)
return 1;
else
return 0;
in_addr_t ip_addr = ntohl(addr.s_addr);
return
((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8 (loopback) */ ||
((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
}
static void dns_doctor(HEADER *header, struct doctor *doctor, struct in_addr *addr)
@@ -864,7 +865,9 @@ int check_for_local_domain(char *name, time_t now, struct daemon *daemon)
struct crec *crecp;
struct mx_srv_record *mx;
struct txt_record *txt;
struct interface_name *intr;
struct ptr_record *ptr;
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
(crecp->flags & (F_HOSTS | F_DHCP)))
return 1;
@@ -876,7 +879,15 @@ int check_for_local_domain(char *name, time_t now, struct daemon *daemon)
for (txt = daemon->txt; txt; txt = txt->next)
if (hostname_isequal(name, txt->name))
return 1;
for (intr = daemon->int_names; intr; intr = intr->next)
if (hostname_isequal(name, intr->name))
return 1;
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
if (hostname_isequal(name, ptr->name))
return 1;
return 0;
}
@@ -1108,21 +1119,27 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
/* see if it's w.z.y.z.in-addr.arpa format */
int is_arpa = in_arpa_name_2_addr(name, &addr);
struct ptr_record *ptr;
struct interface_name* intr = NULL;
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
if (hostname_isequal(name, ptr->name))
break;
if (!ptr &&
!(crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
{
if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) && private_net(&addr))
if (is_arpa == F_IPV4)
for (intr = daemon->int_names; intr; intr = intr->next)
if (addr.addr.addr4.s_addr == get_ifaddr(daemon, intr->intr).s_addr)
break;
if (intr)
{
ans = 1;
if (!dryrun)
{
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
ans = 1;
nxdomain = 1;
if (!dryrun)
log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, name, &addr, 0, NULL, 0);
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, 0, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
anscount++;
}
}
else if (ptr)
@@ -1132,59 +1149,71 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
{
log_query(F_CNAME | F_FORWARD | F_CONFIG | F_BIGNAME, name, NULL, 0, NULL, 0);
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
if (hostname_isequal(name, ptr->name))
{
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
T_PTR, C_IN, "d", ptr->ptr))
anscount++;
}
if (hostname_isequal(name, ptr->name) &&
add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
T_PTR, C_IN, "d", ptr->ptr))
anscount++;
}
}
else do
{
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
continue;
if (crecp->flags & F_NEG)
{
ans = 1;
auth = 0;
if (crecp->flags & F_NXDOMAIN)
nxdomain = 1;
if (!dryrun)
log_query(crecp->flags & ~F_FORWARD, name, &addr, 0, NULL, 0);
}
else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
{
ans = 1;
if (!(crecp->flags & (F_HOSTS | F_DHCP)))
else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
do
{
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
continue;
if (crecp->flags & F_NEG)
{
ans = 1;
auth = 0;
if (!dryrun)
{
unsigned long ttl;
/* Return 0 ttl for DHCP entries, which might change
before the lease expires. */
if (crecp->flags & (F_IMMORTAL | F_DHCP))
ttl = daemon->local_ttl;
else
ttl = crecp->ttd - now;
log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
0, daemon->addn_hosts, crecp->uid);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL,
T_PTR, C_IN, "d", cache_get_name(crecp)))
anscount++;
}
}
} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
if (crecp->flags & F_NXDOMAIN)
nxdomain = 1;
if (!dryrun)
log_query(crecp->flags & ~F_FORWARD, name, &addr, 0, NULL, 0);
}
else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
{
ans = 1;
if (!(crecp->flags & (F_HOSTS | F_DHCP)))
auth = 0;
if (!dryrun)
{
unsigned long ttl;
/* Return 0 ttl for DHCP entries, which might change
before the lease expires. */
if (crecp->flags & (F_IMMORTAL | F_DHCP))
ttl = daemon->local_ttl;
else
ttl = crecp->ttd - now;
log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
0, daemon->addn_hosts, crecp->uid);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL,
T_PTR, C_IN, "d", cache_get_name(crecp)))
anscount++;
}
}
} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
else if (is_arpa == F_IPV4 &&
(daemon->options & OPT_BOGUSPRIV) &&
private_net(addr.addr.addr4))
{
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
ans = 1;
nxdomain = 1;
if (!dryrun)
log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
name, &addr, 0, NULL, 0);
}
}
for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
{
unsigned short type = T_A;
if (flag == F_IPV6)
#ifdef HAVE_IPV6
type = T_AAAA;
@@ -1195,7 +1224,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
if (qtype != type && qtype != T_ANY)
continue;
/* Check for "A for A" queries. */
/* Check for "A for A" queries */
if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
{
ans = 1;
@@ -1209,6 +1238,34 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
continue;
}
/* interface name stuff */
if (qtype == T_A)
{
struct interface_name *intr;
for (intr = daemon->int_names; intr; intr = intr->next)
if (hostname_isequal(name, intr->name))
break;
if (intr)
{
ans = 1;
if (!dryrun)
{
if ((addr.addr.addr4 = get_ifaddr(daemon, intr->intr)).s_addr == (in_addr_t) -1)
log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, 0, NULL, 0);
else
{
log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, 0, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL, type, C_IN, "4", &addr))
anscount++;
}
}
continue;
}
}
cname_restart:
if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
{
+210 -61
View File
@@ -48,7 +48,10 @@
#define OPTION_SUBNET_SELECT 118
#define OPTION_END 255
#define SUBOPT_CIRCUIT_ID 1
#define SUBOPT_REMOTE_ID 2
#define SUBOPT_SUBNET_SELECT 5 /* RFC 3527 */
#define SUBOPT_SUBSCR_ID 6 /* RFC 3393 */
#define DHCPDISCOVER 1
#define DHCPOFFER 2
@@ -63,6 +66,7 @@
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
#define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2]))
static int sanitise(unsigned char *opt, char *buf);
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config,
struct dhcp_lease *lease, unsigned char *opt, time_t now);
static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val);
@@ -74,7 +78,7 @@ static void log_packet(struct daemon *daemon, char *type, void *addr,
unsigned char *ext_mac, int mac_len, char *interface, char *string);
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
static size_t dhcp_packet_size(struct dhcp_packet *mess);
static size_t dhcp_packet_size(struct daemon *daemon, struct dhcp_packet *mess, struct dhcp_netid *netid);
static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess,
@@ -166,6 +170,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
get overwritten, then it will be shuffled back at the end of processing.
Note that the incoming options must not be overwritten here, so there has to
be enough free space at the end of the packet to copy the option. */
unsigned char *sopt;
unsigned int total = option_len(opt) + 2;
unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
if (last_opt && last_opt < end - total)
@@ -175,10 +180,34 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
}
/* look for RFC3527 Link selection sub-option */
if ((opt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), SUBOPT_SUBNET_SELECT, INADDRSZ)))
subnet_addr = option_addr(opt);
if ((sopt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), SUBOPT_SUBNET_SELECT, INADDRSZ)))
subnet_addr = option_addr(sopt);
/* if a circuit-id or remote-is option is provided, exact-match to options. */
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
{
int search;
if (vendor->match_type == MATCH_CIRCUIT)
search = SUBOPT_CIRCUIT_ID;
else if (vendor->match_type == MATCH_REMOTE)
search = SUBOPT_REMOTE_ID;
else if (vendor->match_type == MATCH_SUBSCRIBER)
search = SUBOPT_SUBSCR_ID;
else
continue;
if ((sopt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), search, 1)) &&
vendor->len == option_len(sopt) &&
memcmp(option_ptr(sopt), vendor->data, vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
}
}
}
/* Check for RFC3011 subnet selector - only if RFC3527 one not present */
if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
subnet_addr = option_addr(opt);
@@ -268,15 +297,29 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
if (!context)
{
syslog(LOG_WARNING, _("no address range available for DHCP request %s %s"),
subnet_addr.s_addr ? _("with subnet selector") : _("via"),
subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
my_syslog(LOG_WARNING, _("no address range available for DHCP request %s %s"),
subnet_addr.s_addr ? _("with subnet selector") : _("via"),
subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
return 0;
}
/* keep _a_ local address available. */
fallback = context->local;
if (daemon->options & OPT_LOG_OPTS)
{
struct dhcp_context *context_tmp;
my_syslog(LOG_INFO, _("DHCP packet: transaction-id is %u"), mess->xid);
for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
{
strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
if (context_tmp->flags & CONTEXT_STATIC)
my_syslog(LOG_INFO, _("Available DHCP subnet: %s/%s"), daemon->namebuff, inet_ntoa(context_tmp->netmask));
else
my_syslog(LOG_INFO, _("Available DHCP range: %s -- %s"), daemon->namebuff, inet_ntoa(context_tmp->end));
}
}
mess->op = BOOTREPLY;
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
@@ -361,7 +404,10 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
if (!message &&
!lease &&
(!(lease = lease_allocate(mess->yiaddr))))
message = _("no leases left");
{
my_syslog(LOG_WARNING, _("Limit of %d leases exceeded."), daemon->dhcp_max);
message = _("no leases left");
}
if (!message && !(context = narrow_context(context, mess->yiaddr)))
message = _("wrong network");
@@ -389,7 +435,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
log_packet(daemon, NULL, logaddr, mess->chaddr, mess->hlen, iface_name, message);
return message ? 0 : dhcp_packet_size(mess);
return message ? 0 : dhcp_packet_size(daemon, mess, netid);
}
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
@@ -501,21 +547,40 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
}
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
if ((opt = option_find(mess, sz, vendor->is_vendor ? OPTION_VENDOR_ID : OPTION_USER_CLASS, 1)))
{
int i;
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt)+i, vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
}
}
{
int mopt;
if (vendor->match_type == MATCH_VENDOR)
mopt = OPTION_VENDOR_ID;
else if (vendor->match_type == MATCH_USER)
mopt = OPTION_USER_CLASS;
else
continue;
if ((opt = option_find(mess, sz, mopt, 1)))
{
int i;
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt)+i, vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
}
}
}
/* mark vendor-encapsulated options which match the client-supplied vendor class */
match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
if (daemon->options & OPT_LOG_OPTS)
{
if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
my_syslog(LOG_INFO, _("Vendor class: %s"), daemon->namebuff);
if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
my_syslog(LOG_INFO, _("User class: %s"), daemon->namebuff);
}
/* if all the netids in the ignore list are present, ignore this client */
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
if (match_netid(id_list->list, netid, 0))
@@ -540,19 +605,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
return 0;
/* sanitise any message. Paranoid? Moi? */
if ((opt = option_find(mess, sz, OPTION_MESSAGE, 1)))
{
char *p = option_ptr(opt), *q = daemon->dhcp_buff;
int i;
for (i = option_len(opt); i > 0; i--)
{
char c = *p++;
if (isprint(c))
*q++ = c;
}
*q++ = 0; /* add terminator */
}
sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
return 0;
@@ -566,8 +619,8 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
config->addr.s_addr == option_addr(opt).s_addr)
{
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
syslog(LOG_WARNING, _("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
my_syslog(LOG_WARNING, _("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
}
@@ -616,8 +669,8 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
int len;
unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
syslog(LOG_WARNING, _("not using configured address %s because it is leased to %s"),
addrs, print_mac(daemon, mac, len));
my_syslog(LOG_WARNING, _("not using configured address %s because it is leased to %s"),
addrs, print_mac(daemon, mac, len));
}
else
{
@@ -626,10 +679,10 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
if (context->router.s_addr == config->addr.s_addr)
break;
if (tmp)
syslog(LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
my_syslog(LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
else if (have_config(config, CONFIG_DECLINED) &&
difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
syslog(LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
my_syslog(LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
else
conf = config->addr;
}
@@ -673,7 +726,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
do_options(context, mess, end, req_options, daemon, offer_hostname,
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
return dhcp_packet_size(mess);
return dhcp_packet_size(daemon, mess, netid);
case DHCPREQUEST:
if (ignore || have_config(config, CONFIG_DISABLE))
@@ -891,7 +944,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
}
return dhcp_packet_size(mess);
return dhcp_packet_size(daemon, mess, netid);
case DHCPINFORM:
if (ignore || have_config(config, CONFIG_DISABLE))
@@ -919,7 +972,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
do_options(context, mess, end, req_options, daemon, hostname,
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
return dhcp_packet_size(mess);
return dhcp_packet_size(daemon, mess, netid);
}
return 0;
@@ -988,6 +1041,29 @@ static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *
return time;
}
static int sanitise(unsigned char *opt, char *buf)
{
char *p;
int i;
*buf = 0;
if (!opt)
return 0;
p = option_ptr(opt);
for (i = option_len(opt); i > 0; i--)
{
char c = *p++;
if (isprint(c))
*buf++ = c;
}
*buf = 0; /* add terminator */
return 1;
}
static void log_packet(struct daemon *daemon, char *type, void *addr,
unsigned char *ext_mac, int mac_len, char *interface, char *string)
{
@@ -997,14 +1073,30 @@ static void log_packet(struct daemon *daemon, char *type, void *addr,
if (addr)
memcpy(&a, addr, sizeof(a));
syslog(LOG_INFO, "%s%s(%s) %s%s%s %s",
type ? "DHCP" : "BOOTP",
type ? type : "",
interface,
addr ? inet_ntoa(a) : "",
addr ? " " : "",
print_mac(daemon, ext_mac, mac_len),
string ? string : "");
my_syslog(LOG_INFO, "%s%s(%s) %s%s%s %s",
type ? "DHCP" : "BOOTP",
type ? type : "",
interface,
addr ? inet_ntoa(a) : "",
addr ? " " : "",
print_mac(daemon, ext_mac, mac_len),
string ? string : "");
}
static void log_options(struct daemon *daemon, unsigned char *start)
{
while (*start != OPTION_END)
{
char *text = option_string(start[0]);
unsigned char trunc = start[1] < 13 ? start[1] : 13;
my_syslog(LOG_INFO, "sent size:%3d option:%3d%s%s%s%s%s",
start[1], start[0],
text ? ":" : "", text ? text : "",
start[1] == 0 ? "" : " ",
start[1] == 0 ? "" : print_mac(daemon, &start[2], trunc),
trunc == start[1] ? "" : "...");
start += start[1] + 2;
}
}
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
@@ -1102,28 +1194,53 @@ static unsigned char *find_overload(struct dhcp_packet *mess)
return NULL;
}
static size_t dhcp_packet_size(struct dhcp_packet *mess)
static size_t dhcp_packet_size(struct daemon *daemon, struct dhcp_packet *mess, struct dhcp_netid *netid)
{
unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
unsigned char *overload;
size_t ret;
/* We do logging too */
if (netid && (daemon->options & OPT_LOG_OPTS))
{
char *p = daemon->namebuff;
*p = 0;
for (; netid; netid = netid->next)
{
strncat (p, netid->net, MAXDNAME);
if (netid->next)
strncat (p, ", ", MAXDNAME);
}
p[MAXDNAME - 1] = 0;
my_syslog(LOG_INFO, _("tags: %s"), p);
}
/* add END options to the regions. */
if ((overload = find_overload(mess)))
{
if (option_uint(overload, 1) & 1)
*dhcp_skip_opts(mess->file) = OPTION_END;
{
*dhcp_skip_opts(mess->file) = OPTION_END;
if (daemon->options & OPT_LOG_OPTS)
log_options(daemon, mess->file);
}
if (option_uint(overload, 1) & 2)
*dhcp_skip_opts(mess->sname) = OPTION_END;
{
*dhcp_skip_opts(mess->sname) = OPTION_END;
if (daemon->options & OPT_LOG_OPTS)
log_options(daemon, mess->sname);
}
}
*p++ = OPTION_END;
if (daemon->options & OPT_LOG_OPTS)
log_options(daemon, &mess->options[0] + sizeof(u32));
ret = (size_t)(p - (unsigned char *)mess);
if (ret < MIN_PACKETSZ)
ret = MIN_PACKETSZ;
return ret;
}
@@ -1177,7 +1294,7 @@ static unsigned char *free_space(struct dhcp_packet *mess, unsigned char *end, i
}
if (!p)
syslog(LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
my_syslog(LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
}
if (p)
@@ -1313,9 +1430,30 @@ static void do_options(struct dhcp_context *context,
struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
struct dhcp_boot *boot;
unsigned char *p, *end = agent_id ? agent_id : real_end;
int len, force_encap = 0;
int i, len, force_encap = 0;
unsigned char f0 = 0, s0 = 0;
/* logging */
if ((daemon->options & OPT_LOG_OPTS) && req_options)
{
char *q = daemon->namebuff;
for (i = 0; req_options[i] != OPTION_END; i++)
{
char *s = option_string(req_options[i]);
q +=snprintf(q, MAXDNAME - (q - daemon->namebuff),
"%d%s%s%s",
req_options[i],
s ? ":" : "",
s ? s : "",
req_options[i+1] == OPTION_END ? "" : ", ");
if (req_options[i+1] == OPTION_END || (q - daemon->namebuff) > 40)
{
q = daemon->namebuff;
my_syslog(LOG_INFO, _("requested options: %s"), daemon->namebuff);
}
}
}
/* decide which dhcp-boot option we're using */
for (boot = daemon->boot_config; boot; boot = boot->next)
if (match_netid(boot->netid, netid, 0))
@@ -1340,7 +1478,11 @@ static void do_options(struct dhcp_context *context,
if (req_options && in_list(req_options, OPTION_SNAME))
option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
else
strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
{
if (daemon->options & OPT_LOG_OPTS)
my_syslog(LOG_INFO, _("server name: %s"), boot->sname);
strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
}
}
if (boot->file)
@@ -1348,13 +1490,20 @@ static void do_options(struct dhcp_context *context,
if (req_options && in_list(req_options, OPTION_FILENAME))
option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
else
strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
{
if (daemon->options & OPT_LOG_OPTS)
my_syslog(LOG_INFO, _("bootfile name: %s"), boot->file);
strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
}
}
if (boot->next_server.s_addr)
mess->siaddr = boot->next_server;
if (daemon->options & OPT_LOG_OPTS)
my_syslog(LOG_INFO, _("next server: %s"), inet_ntoa(mess->siaddr));
}
/* We don't want to do option-overload for BOOTP, so make the file and sname
fields look like they are in use, even when they aren't. This gets restored
at the end of this function. */
+24 -15
View File
@@ -106,7 +106,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
if (addr.sin_addr.s_addr == 0)
return;
if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr, &ifr, &if_index))
if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr.sin_addr,
&ifr, &if_index))
return;
/* allowed interfaces are the same as for DHCP */
@@ -179,18 +180,26 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
}
}
strcpy(daemon->namebuff, "/");
if (daemon->tftp_prefix)
{
strncpy(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/' &&
filename[0] != '/')
if (daemon->tftp_prefix[0] == '/')
daemon->namebuff[0] = 0;
strncat(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
strncat(daemon->namebuff, "/", MAXDNAME);
/* Absolute pathnames OK if they match prefix */
if (filename[0] == '/')
{
if (strstr(filename, daemon->namebuff) == filename)
daemon->namebuff[0] = 0;
else
filename++;
}
}
else if (filename[0] != '/')
strncpy(daemon->namebuff, "/", MAXDNAME);
else
else if (filename[0] == '/')
daemon->namebuff[0] = 0;
strncat(daemon->namebuff, filename, MAXDNAME);
daemon->namebuff[MAXDNAME-1] = 0;
@@ -227,7 +236,7 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
free_transfer(transfer);
else
{
syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
my_syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
transfer->next = daemon->tftp_trans;
daemon->tftp_trans = transfer;
}
@@ -350,9 +359,9 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
*(q++) = *r;
*q = 0;
}
syslog(LOG_ERR, _("TFTP error %d %s received from %s"),
(int)ntohs(mess->block), err,
inet_ntoa(transfer->peer.sin_addr));
my_syslog(LOG_ERR, _("TFTP error %d %s received from %s"),
(int)ntohs(mess->block), err,
inet_ntoa(transfer->peer.sin_addr));
/* Got err, ensure we take abort */
transfer->timeout = now;
@@ -381,8 +390,8 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
/* don't complain about timeout when we're awaiting the last
ACK, some clients never send it */
if (len != 0)
syslog(LOG_ERR, _("TFTP failed sending %s to %s"),
transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
my_syslog(LOG_ERR, _("TFTP failed sending %s to %s"),
transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
len = 0;
}
@@ -441,7 +450,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
mess->err = htons(err);
ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
if (err != ERR_FNF)
syslog(LOG_ERR, "TFTP %s", mess->message);
my_syslog(LOG_ERR, "TFTP %s", mess->message);
return ret;
}
-43
View File
@@ -156,35 +156,6 @@ void *safe_malloc(size_t size)
return ret;
}
static void log_err(char *message, char *arg1)
{
char *errmess = strerror(errno);
if (!arg1)
arg1 = errmess;
fprintf(stderr, "dnsmasq: ");
fprintf(stderr, message, arg1, errmess);
fprintf(stderr, "\n");
syslog(LOG_CRIT, message, arg1, errmess);
}
void complain(char *message, int lineno, char *file)
{
char buff[256];
sprintf(buff, _("%s at line %d of %%s"), message, lineno);
log_err(buff, file);
}
void die(char *message, char *arg1)
{
log_err(message, arg1);
syslog(LOG_CRIT, _("FAILED to start up"));
exit(1);
}
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
{
if (s1->sa.sa_family == s2->sa.sa_family)
@@ -418,20 +389,6 @@ void bump_maxfd(int fd, int *max)
*max = fd;
}
void log_start(struct daemon *daemon)
{
if (daemon->options & OPT_DEBUG)
{
#ifdef LOG_PERROR
openlog("dnsmasq", LOG_PERROR, daemon->log_fac);
#else
openlog("dnsmasq", 0, daemon->log_fac);
#endif
}
else
openlog("dnsmasq", LOG_PID, daemon->log_fac);
}
int read_write(int fd, unsigned char *packet, int size, int rw)
{
ssize_t n, done;