mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-10-26 12:24:42 +00:00
import of dnsmasq-2.39.tar.gz
This commit is contained in:
1 parent
6b01084f8e
commit
f2621c7ff0
36 files changed
+5572
-3349
No files matched your search
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large.
Load diff
+123
-66
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user