summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kline <ek@google.com>2017-05-24 09:46:37 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-05-24 09:46:37 +0000
commita21366fc0529c748068fdd4bfcab48723e2a5f99 (patch)
tree393316bed9b71d2cf78d8b69cc68021cc2a82d20
parent337e7e3a369dd09e37ddf2df37d4fb03f92db49f (diff)
parentd37f567618c3f5266d82b971a505f5a214a03f34 (diff)
downloaddnsmasq-oreo-dr1-dev.tar.gz
Merge "Remove some unused TFTP and DBUS support" am: 00d11a4477 am: c660bc5375 am: 71fa6b0bfboreo-dr1-dev
am: d37f567618 Change-Id: I960366fcca40f86e05929cffa853294dec18a1e7
-rwxr-xr-xdbus/DBus-interface131
-rwxr-xr-xdbus/dnsmasq.conf14
-rw-r--r--src/Android.mk6
-rwxr-xr-xsrc/config.h21
-rwxr-xr-xsrc/dbus.c436
-rwxr-xr-xsrc/dnsmasq.c147
-rwxr-xr-xsrc/dnsmasq.h50
-rwxr-xr-xsrc/lease.c14
-rwxr-xr-xsrc/network.c60
-rwxr-xr-xsrc/option.c34
-rwxr-xr-xsrc/tftp.c600
11 files changed, 15 insertions, 1498 deletions
diff --git a/dbus/DBus-interface b/dbus/DBus-interface
deleted file mode 100755
index 8d578ca..0000000
--- a/dbus/DBus-interface
+++ /dev/null
@@ -1,131 +0,0 @@
-DBus support must be enabled at compile-time and run-time. Ensure
-that src/config.h contains the line
-
-#define HAVE_DBUS.
-
-and that /etc/dnsmasq.conf contains the line
-
-enable-dbus
-
-Because dnsmasq can operate stand-alone from the DBus, and may need to provide
-service before the dbus daemon is available, it will continue to run
-if the DBus connection is not available at startup. The DBus will be polled
-every 250ms until a connection is established. Start of polling and final
-connection establishment are both logged. When dnsmasq establishes a
-connection to the dbus, it sends the signal "Up". Anything controlling
-the server settings in dnsmasq should re-invoke the SetServers method
-(q.v.) when it sees this signal. This allows dnsmasq to be restarted
-and avoids startup races with the provider of nameserver information.
-
-
-Dnsmasq provides one service on the DBus: uk.org.thekelleys.dnsmasq
-and a single object: /uk/org/thekelleys/dnsmasq
-
-1. METHODS
-----------
-
-Methods are of the form
-
-uk.org.thekelleys.<method>
-
-Available methods are:
-
-GetVersion
-----------
-Returns a string containing the version of dnsmasq running.
-
-ClearCache
-----------
-Returns nothing. Clears the domain name cache and re-reads
-/etc/hosts. The same as sending dnsmasq a HUP signal.
-
-SetServers
-----------
-Returns nothing. Takes a set of arguments representing the new
-upstream DNS servers to be used by dnsmasq. IPv4 addresses are
-represented as a UINT32 (in network byte order) and IPv6 addresses
-are represented as sixteen BYTEs (since there is no UINT128 type).
-Each server address may be followed by one or more STRINGS, which are
-the domains for which the preceding server should be used.
-
-Examples.
-
-UINT32: <address1>
-UNIT32: <address2>
-
-is equivalent to
-
---server=<address1> --server=<address2>
-
-
-UINT32 <address1>
-UINT32 <address2>
-STRING "somedomain.com"
-
-is equivalent to
-
---server=<address1> --server=/somedomain.com/<address2>
-
-UINT32 <address1>
-UINT32 <address2>
-STRING "somedomain.com"
-UINT32 <address3>
-STRING "anotherdomain.com"
-STRING "thirddomain.com"
-
-is equivalent to
-
---server=<address1>
---server=/somedomain.com/<address2>
---server=/anotherdomain.com/thirddomain.com/<address3>
-
-Am IPv4 address of 0.0.0.0 is interpreted as "no address, local only",
-so
-
-UINT32: <0.0.0.0>
-STRING "local.domain"
-
-is equivalent to
-
---local=/local.domain/
-
-
-Each call to SetServers completely replaces the set of servers
-specified by via the DBus, but it leaves any servers specified via the
-command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
-
-2. SIGNALS
-----------
-
-If dnsmasq's DHCP server is active, it will send signals over DBUS whenever
-the DHCP lease database changes. Think of these signals as transactions on
-a database with the IP address acting as the primary key.
-
-Signals are of the form:
-
-uk.org.thekelleys.<signal>
-
-and their parameters are:
-
-STRING "192.168.1.115"
-STRING "01:23:45:67:89:ab"
-STRING "hostname.or.fqdn"
-
-
-Available signals are:
-
-DhcpLeaseAdded
----------------
-
-This signal is emitted when a DHCP lease for a given IP address is created.
-
-DhcpLeaseDeleted
-----------------
-
-This signal is emitted when a DHCP lease for a given IP address is deleted.
-
-DhcpLeaseUpdated
-----------------
-
-This signal is emitted when a DHCP lease for a given IP address is updated.
-
diff --git a/dbus/dnsmasq.conf b/dbus/dnsmasq.conf
deleted file mode 100755
index 82b1c76..0000000
--- a/dbus/dnsmasq.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
- <policy user="root">
- <allow own="uk.org.thekelleys.dnsmasq"/>
- <allow send_destination="uk.org.thekelleys.dnsmasq"/>
- </policy>
- <policy context="default">
- <deny own="uk.org.thekelleys.dnsmasq"/>
- <deny send_destination="uk.org.thekelleys.dnsmasq"/>
- </policy>
-</busconfig>
-
diff --git a/src/Android.mk b/src/Android.mk
index 8edf9d6..7c729ef 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -3,14 +3,14 @@ LOCAL_PATH := $(call my-dir)
#########################
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c forward.c helper.c lease.c log.c \
- netlink.c network.c option.c rfc1035.c rfc2131.c tftp.c util.c
+LOCAL_SRC_FILES := bpf.c cache.c dhcp.c dnsmasq.c forward.c helper.c lease.c log.c \
+ netlink.c network.c option.c rfc1035.c rfc2131.c util.c
LOCAL_MODULE := dnsmasq
LOCAL_C_INCLUDES := external/dnsmasq/src
-LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DIPV6 -DNO_TFTP -DNO_SCRIPT -D_BSD_SOURCE \
+LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DIPV6 -DNO_SCRIPT -D_BSD_SOURCE \
-Wno-unused-variable -Wno-unused-parameter -Werror
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
LOCAL_SHARED_LIBRARIES := libcutils liblog
diff --git a/src/config.h b/src/config.h
index e63cbae..9e43696 100755
--- a/src/config.h
+++ b/src/config.h
@@ -68,16 +68,10 @@
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_ALTPORT 1067
#define DHCP_CLIENT_ALTPORT 1068
-#define TFTP_PORT 69
-#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
#define LOG_MAX 5 /* log-queue length */
#define RANDFILE "/dev/urandom"
#define DAD_WAIT 20 /* retry binding IPv6 sockets for this long */
-/* DBUS interface specifics */
-#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
-#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
-
/* A small collection of RR-types which are missing on some platforms */
#ifndef T_SIG
@@ -124,9 +118,6 @@ HAVE_BROKEN_RTC
NOTE: when enabling or disabling this, be sure to delete any old
leases file, otherwise dnsmasq may get very confused.
-HAVE_TFTP
- define this to get dnsmasq's built-in TFTP server.
-
HAVE_DHCP
define this to get dnsmasq's DHCP server.
@@ -143,11 +134,6 @@ HAVE_ARC4RANDOM
HAVE_SOCKADDR_SA_LEN
define this if struct sockaddr has sa_len field (*BSD)
-HAVE_DBUS
- Define this if you want to link against libdbus, and have dnsmasq
- define some methods to allow (re)configuration of the upstream DNS
- servers via DBus.
-
NOTES:
For Linux you should define
HAVE_LINUX_NETWORK
@@ -168,15 +154,8 @@ NOTES:
/* platform independent options- uncomment to enable */
#define HAVE_DHCP
-#define HAVE_TFTP
#define HAVE_SCRIPT
/* #define HAVE_BROKEN_RTC */
-/* #define HAVE_DBUS */
-
-/* Allow TFTP to be disabled with COPTS=-DNO_TFTP */
-#ifdef NO_TFTP
-#undef HAVE_TFTP
-#endif
/* Allow DHCP to be disabled with COPTS=-DNO_DHCP */
#ifdef NO_DHCP
diff --git a/src/dbus.c b/src/dbus.c
deleted file mode 100755
index 841f924..0000000
--- a/src/dbus.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* dnsmasq is Copyright (c) 2000-2009 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, or
- (at your option) version 3 dated 29 June, 2007.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "dnsmasq.h"
-
-#ifdef HAVE_DBUS
-
-#include <dbus/dbus.h>
-
-const char* introspection_xml =
-"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
-"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
-"<node name=\"" DNSMASQ_PATH "\">\n"
-" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
-" <method name=\"Introspect\">\n"
-" <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
-" </method>\n"
-" </interface>\n"
-" <interface name=\"" DNSMASQ_SERVICE "\">\n"
-" <method name=\"ClearCache\">\n"
-" </method>\n"
-" <method name=\"GetVersion\">\n"
-" <arg name=\"version\" direction=\"out\" type=\"s\"/>\n"
-" </method>\n"
-" <method name=\"SetServers\">\n"
-" <arg name=\"servers\" direction=\"in\" type=\"av\"/>\n"
-" </method>\n"
-" <signal name=\"DhcpLeaseAdded\">\n"
-" <arg name=\"ipaddr\" type=\"s\"/>\n"
-" <arg name=\"hwaddr\" type=\"s\"/>\n"
-" <arg name=\"hostname\" type=\"s\"/>\n"
-" </signal>\n"
-" <signal name=\"DhcpLeaseDeleted\">\n"
-" <arg name=\"ipaddr\" type=\"s\"/>\n"
-" <arg name=\"hwaddr\" type=\"s\"/>\n"
-" <arg name=\"hostname\" type=\"s\"/>\n"
-" </signal>\n"
-" <signal name=\"DhcpLeaseUpdated\">\n"
-" <arg name=\"ipaddr\" type=\"s\"/>\n"
-" <arg name=\"hwaddr\" type=\"s\"/>\n"
-" <arg name=\"hostname\" type=\"s\"/>\n"
-" </signal>\n"
-" </interface>\n"
-"</node>\n";
-
-struct watch {
- DBusWatch *watch;
- struct watch *next;
-};
-
-
-static dbus_bool_t add_watch(DBusWatch *watch, void *data)
-{
- struct watch *w;
-
- for (w = daemon->watches; w; w = w->next)
- if (w->watch == watch)
- return TRUE;
-
- if (!(w = whine_malloc(sizeof(struct watch))))
- return FALSE;
-
- w->watch = watch;
- w->next = daemon->watches;
- daemon->watches = w;
-
- w = data; /* no warning */
- return TRUE;
-}
-
-static void remove_watch(DBusWatch *watch, void *data)
-{
- struct watch **up, *w;
-
- for (up = &(daemon->watches), w = daemon->watches; w; w = w->next)
- if (w->watch == watch)
- {
- *up = w->next;
- free(w);
- }
- else
- up = &(w->next);
-
- w = data; /* no warning */
-}
-
-static void dbus_read_servers(DBusMessage *message)
-{
- struct server *serv, *tmp, **up;
- DBusMessageIter iter;
- union mysockaddr addr, source_addr;
- char *domain;
-
- dbus_message_iter_init(message, &iter);
-
- /* mark everything from DBUS */
- for (serv = daemon->servers; serv; serv = serv->next)
- if (serv->flags & SERV_FROM_DBUS)
- serv->flags |= SERV_MARK;
-
- while (1)
- {
- int skip = 0;
-
- if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32)
- {
- u32 a;
-
- dbus_message_iter_get_basic(&iter, &a);
- dbus_message_iter_next (&iter);
-
-#ifdef HAVE_SOCKADDR_SA_LEN
- source_addr.in.sin_len = addr.in.sin_len = sizeof(struct sockaddr_in);
-#endif
- addr.in.sin_addr.s_addr = ntohl(a);
- source_addr.in.sin_family = addr.in.sin_family = AF_INET;
- addr.in.sin_port = htons(NAMESERVER_PORT);
- source_addr.in.sin_addr.s_addr = INADDR_ANY;
- source_addr.in.sin_port = htons(daemon->query_port);
- }
- else if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_BYTE)
- {
- unsigned char p[sizeof(struct in6_addr)];
- unsigned int i;
-
- skip = 1;
-
- for(i = 0; i < sizeof(struct in6_addr); i++)
- {
- dbus_message_iter_get_basic(&iter, &p[i]);
- dbus_message_iter_next (&iter);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BYTE)
- break;
- }
-
-#ifndef HAVE_IPV6
- my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
-#else
- if (i == sizeof(struct in6_addr)-1)
- {
- memcpy(&addr.in6.sin6_addr, p, sizeof(struct in6_addr));
-#ifdef HAVE_SOCKADDR_SA_LEN
- source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(struct sockaddr_in6);
-#endif
- source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
- addr.in6.sin6_port = htons(NAMESERVER_PORT);
- source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
- source_addr.in6.sin6_scope_id = addr.in6.sin6_scope_id = 0;
- source_addr.in6.sin6_addr = in6addr_any;
- source_addr.in6.sin6_port = htons(daemon->query_port);
- skip = 0;
- }
-#endif
- }
- else
- /* At the end */
- break;
-
- do {
- if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING)
- {
- dbus_message_iter_get_basic(&iter, &domain);
- dbus_message_iter_next (&iter);
- }
- else
- domain = NULL;
-
- if (!skip)
- {
- /* See if this is already there, and unmark */
- for (serv = daemon->servers; serv; serv = serv->next)
- if ((serv->flags & SERV_FROM_DBUS) &&
- (serv->flags & SERV_MARK))
- {
- if (!(serv->flags & SERV_HAS_DOMAIN) && !domain)
- {
- serv->flags &= ~SERV_MARK;
- break;
- }
- if ((serv->flags & SERV_HAS_DOMAIN) &&
- domain &&
- hostname_isequal(domain, serv->domain))
- {
- serv->flags &= ~SERV_MARK;
- break;
- }
- }
-
- if (!serv && (serv = whine_malloc(sizeof (struct server))))
- {
- /* Not found, create a new one. */
- memset(serv, 0, sizeof(struct server));
-
- if (domain)
- serv->domain = whine_malloc(strlen(domain)+1);
-
- if (domain && !serv->domain)
- {
- free(serv);
- serv = NULL;
- }
- else
- {
- serv->next = daemon->servers;
- daemon->servers = serv;
- serv->flags = SERV_FROM_DBUS;
- if (domain)
- {
- strcpy(serv->domain, domain);
- serv->flags |= SERV_HAS_DOMAIN;
- }
- }
- }
-
- if (serv)
- {
- if (source_addr.in.sin_family == AF_INET &&
- addr.in.sin_addr.s_addr == 0 &&
- serv->domain)
- serv->flags |= SERV_NO_ADDR;
- else
- {
- serv->flags &= ~SERV_NO_ADDR;
- serv->addr = addr;
- serv->source_addr = source_addr;
- }
- }
- }
- } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING);
- }
-
- /* unlink and free anything still marked. */
- for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
- {
- tmp = serv->next;
- if (serv->flags & SERV_MARK)
- {
- server_gone(serv);
- *up = serv->next;
- free(serv);
- }
- else
- up = &serv->next;
- }
-
-}
-
-DBusHandlerResult message_handler(DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- char *method = (char *)dbus_message_get_member(message);
-
- if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
- {
- DBusMessage *reply = dbus_message_new_method_return(message);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_xml, DBUS_TYPE_INVALID);
- dbus_connection_send (connection, reply, NULL);
- dbus_message_unref (reply);
- }
- else if (strcmp(method, "GetVersion") == 0)
- {
- char *v = VERSION;
- DBusMessage *reply = dbus_message_new_method_return(message);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &v, DBUS_TYPE_INVALID);
- dbus_connection_send (connection, reply, NULL);
- dbus_message_unref (reply);
- }
- else if (strcmp(method, "SetServers") == 0)
- {
- my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
- dbus_read_servers(message);
- check_servers();
- }
- else if (strcmp(method, "ClearCache") == 0)
- clear_cache_and_reload(dnsmasq_time());
- else
- return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-
- method = user_data; /* no warning */
-
- return (DBUS_HANDLER_RESULT_HANDLED);
-
-}
-
-
-/* returns NULL or error message, may fail silently if dbus daemon not yet up. */
-char *dbus_init(void)
-{
- DBusConnection *connection = NULL;
- DBusObjectPathVTable dnsmasq_vtable = {NULL, &message_handler, NULL, NULL, NULL, NULL };
- DBusError dbus_error;
- DBusMessage *message;
-
- dbus_error_init (&dbus_error);
- if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
- return NULL;
-
- dbus_connection_set_exit_on_disconnect(connection, FALSE);
- dbus_connection_set_watch_functions(connection, add_watch, remove_watch,
- NULL, NULL, NULL);
- dbus_error_init (&dbus_error);
- dbus_bus_request_name (connection, DNSMASQ_SERVICE, 0, &dbus_error);
- if (dbus_error_is_set (&dbus_error))
- return (char *)dbus_error.message;
-
- if (!dbus_connection_register_object_path(connection, DNSMASQ_PATH,
- &dnsmasq_vtable, NULL))
- return _("could not register a DBus message handler");
-
- daemon->dbus = connection;
-
- if ((message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, "Up")))
- {
- dbus_connection_send(connection, message, NULL);
- dbus_message_unref(message);
- }
-
- return NULL;
-}
-
-
-void set_dbus_listeners(int *maxfdp,
- fd_set *rset, fd_set *wset, fd_set *eset)
-{
- struct watch *w;
-
- for (w = daemon->watches; w; w = w->next)
- if (dbus_watch_get_enabled(w->watch))
- {
- unsigned int flags = dbus_watch_get_flags(w->watch);
- int fd = dbus_watch_get_unix_fd(w->watch);
-
- bump_maxfd(fd, maxfdp);
-
- if (flags & DBUS_WATCH_READABLE)
- FD_SET(fd, rset);
-
- if (flags & DBUS_WATCH_WRITABLE)
- FD_SET(fd, wset);
-
- FD_SET(fd, eset);
- }
-}
-
-void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
-{
- DBusConnection *connection = (DBusConnection *)daemon->dbus;
- struct watch *w;
-
- for (w = daemon->watches; w; w = w->next)
- if (dbus_watch_get_enabled(w->watch))
- {
- unsigned int flags = 0;
- int fd = dbus_watch_get_unix_fd(w->watch);
-
- if (FD_ISSET(fd, rset))
- flags |= DBUS_WATCH_READABLE;
-
- if (FD_ISSET(fd, wset))
- flags |= DBUS_WATCH_WRITABLE;
-
- if (FD_ISSET(fd, eset))
- flags |= DBUS_WATCH_ERROR;
-
- if (flags != 0)
- dbus_watch_handle(w->watch, flags);
- }
-
- if (connection)
- {
- dbus_connection_ref (connection);
- while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS);
- dbus_connection_unref (connection);
- }
-}
-
-void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
-{
- DBusConnection *connection = (DBusConnection *)daemon->dbus;
- DBusMessage* message = NULL;
- DBusMessageIter args;
- char *action_str, *addr, *mac = daemon->namebuff;
- unsigned char *p;
- int i;
-
- if (!connection)
- return;
-
- if (!hostname)
- hostname = "";
-
- p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
- lease->hwaddr, lease->clid_len, lease->clid, &i);
- print_mac(mac, p, i);
-
- if (action == ACTION_DEL)
- action_str = "DhcpLeaseDeleted";
- else if (action == ACTION_ADD)
- action_str = "DhcpLeaseAdded";
- else if (action == ACTION_OLD)
- action_str = "DhcpLeaseUpdated";
- else
- return;
-
- addr = inet_ntoa(lease->addr);
-
- if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
- return;
-
- dbus_message_iter_init_append(message, &args);
-
- if (dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &addr) &&
- dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &mac) &&
- dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &hostname))
- dbus_connection_send(connection, message, NULL);
-
- dbus_message_unref(message);
-}
-
-#endif
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 24e7055..27f8bce 100755
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -33,10 +33,6 @@ static char *compile_opts =
#ifdef NO_FORK
"no-MMU "
#endif
-#ifndef HAVE_DBUS
-"no-"
-#endif
-"DBus "
#ifndef LOCALEDIR
"no-"
#endif
@@ -46,12 +42,9 @@ static char *compile_opts =
#endif
"DHCP "
#if defined(HAVE_DHCP) && !defined(HAVE_SCRIPT)
-"no-scripts "
-#endif
-#ifndef HAVE_TFTP
-"no-"
+"no-scripts"
#endif
-"TFTP";
+"";
@@ -145,11 +138,6 @@ int main (int argc, char **argv)
}
#endif
-#ifndef HAVE_TFTP
- if (daemon->options & OPT_TFTP)
- die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
-#endif
-
#ifdef HAVE_SOLARIS_NETWORK
if (daemon->max_logs != 0)
die(_("asychronous logging is not available under Solaris"), NULL, EC_BADCONF);
@@ -194,20 +182,7 @@ int main (int argc, char **argv)
if (daemon->port != 0)
cache_init();
-
- if (daemon->options & OPT_DBUS)
-#ifdef HAVE_DBUS
- {
- char *err;
- daemon->dbus = NULL;
- daemon->watches = NULL;
- if ((err = dbus_init()))
- die(_("DBus error: %s"), err, EC_MISC);
- }
-#else
- die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
-#endif
-
+
if (daemon->port != 0)
pre_allocate_sfds();
@@ -466,16 +441,6 @@ int main (int argc, char **argv)
my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
-
-#ifdef HAVE_DBUS
- if (daemon->options & OPT_DBUS)
- {
- if (daemon->dbus)
- my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
- else
- my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
- }
-#endif
if (log_err != 0)
my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
@@ -521,49 +486,6 @@ int main (int argc, char **argv)
}
#endif
-#ifdef HAVE_TFTP
- if (daemon->options & OPT_TFTP)
- {
-#ifdef FD_SETSIZE
- if (FD_SETSIZE < (unsigned)max_fd)
- max_fd = FD_SETSIZE;
-#endif
-
- my_syslog(MS_TFTP | 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 served, but for large limits,
- a single file will be sent to may clients (the file only needs
- one fd). */
-
- max_fd -= 30; /* use other than TFTP */
-
- if (max_fd < 0)
- max_fd = 5;
- else if (max_fd < 100)
- max_fd = max_fd/2;
- else
- max_fd = max_fd - 20;
-
- /* if we have to use a limited range of ports,
- that will limit the number of transfers */
- if (daemon->start_tftp_port != 0 &&
- daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
- max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
-
- if (daemon->tftp_max > max_fd)
- {
- daemon->tftp_max = max_fd;
- my_syslog(MS_TFTP | LOG_WARNING,
- _("restricting maximum simultaneous TFTP transfers to %d"),
- daemon->tftp_max);
- }
- }
-#endif
-
/* finished start-up - release original process */
if (err_pipe[1] != -1)
close(err_pipe[1]);
@@ -595,19 +517,6 @@ int main (int argc, char **argv)
set_android_listeners(&rset, &maxfd);
#endif
- /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
- if (daemon->tftp_trans ||
- ((daemon->options & OPT_DBUS) && !daemon->dbus))
- {
- t.tv_sec = 0;
- t.tv_usec = 250000;
- tp = &t;
- }
-
-#ifdef HAVE_DBUS
- set_dbus_listeners(&maxfd, &rset, &wset, &eset);
-#endif
-
#ifdef HAVE_DHCP
if (daemon->dhcp)
{
@@ -672,19 +581,6 @@ int main (int argc, char **argv)
if (FD_ISSET(daemon->netlinkfd, &rset))
netlink_multicast();
#endif
-
-#ifdef HAVE_DBUS
- /* if we didn't create a DBus connection, retry now. */
- if ((daemon->options & OPT_DBUS) && !daemon->dbus)
- {
- char *err;
- if ((err = dbus_init()))
- my_syslog(LOG_WARNING, _("DBus error: %s"), err);
- if (daemon->dbus)
- my_syslog(LOG_INFO, _("connected to system DBus"));
- }
- check_dbus_listeners(&rset, &wset, &eset);
-#endif
#if defined(__ANDROID__) && !defined(__BRILLO__)
check_android_listeners(&rset);
@@ -692,10 +588,6 @@ int main (int argc, char **argv)
check_dns_listeners(&rset, now);
-#ifdef HAVE_TFTP
- check_tftp_listeners(&rset, now);
-#endif
-
#ifdef HAVE_DHCP
if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
dhcp_packet(now);
@@ -1039,18 +931,7 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
struct serverfd *serverfdp;
struct listener *listener;
int wait = 0, i;
-
-#ifdef HAVE_TFTP
- int tftp = 0;
- struct tftp_transfer *transfer;
- for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
- {
- tftp++;
- FD_SET(transfer->sockfd, set);
- bump_maxfd(transfer->sockfd, maxfdp);
- }
-#endif
-
+
/* will we be able to get memory? */
if (daemon->port != 0)
get_new_frec(now, &wait);
@@ -1088,15 +969,6 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
bump_maxfd(listener->tcpfd, maxfdp);
break;
}
-
-#ifdef HAVE_TFTP
- if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
- {
- FD_SET(listener->tftpfd, set);
- bump_maxfd(listener->tftpfd, maxfdp);
- }
-#endif
-
}
return wait;
@@ -1122,11 +994,6 @@ static void check_dns_listeners(fd_set *set, time_t now)
{
if (listener->fd != -1 && FD_ISSET(listener->fd, set))
receive_query(listener, now);
-
-#ifdef HAVE_TFTP
- if (listener->tftpfd != -1 && FD_ISSET(listener->tftpfd, set))
- tftp_request(listener, now);
-#endif
if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
{
@@ -1257,7 +1124,7 @@ int icmp_ping(struct in_addr addr)
/* Try and get an ICMP echo from a machine. */
/* Note that whilst in the three second wait, we check for
- (and service) events on the DNS and TFTP sockets, (so doing that
+ (and service) events on the DNS sockets, (so doing that
better not use any resources our caller has in use...)
but we remain deaf to signals or further DHCP packets. */
@@ -1330,10 +1197,6 @@ int icmp_ping(struct in_addr addr)
check_log_writer(&wset);
check_dns_listeners(&rset, now);
-#ifdef HAVE_TFTP
- check_tftp_listeners(&rset, now);
-#endif
-
if (FD_ISSET(fd, &rset) &&
recvfrom(fd, &packet, sizeof(packet), 0,
(struct sockaddr *)&faddr, &len) == sizeof(packet) &&
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 10b8521..2a78497 100755
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -348,7 +348,7 @@ struct irec {
};
struct listener {
- int fd, tcpfd, tftpfd, family;
+ int fd, tcpfd, family;
struct irec *iface; /* only valid for non-wildcard */
struct listener *next;
};
@@ -575,26 +575,6 @@ struct ping_result {
struct ping_result *next;
};
-struct tftp_file {
- int refcount, fd;
- off_t size;
- dev_t dev;
- ino_t inode;
- char filename[];
-};
-
-struct tftp_transfer {
- int sockfd;
- time_t timeout;
- int backoff;
- unsigned int block, blocksize, expansion;
- off_t offset;
- struct sockaddr_in peer;
- char opt_blocksize, opt_transize, netascii, carrylf;
- struct tftp_file *file;
- struct tftp_transfer *next;
-};
-
extern struct daemon {
/* datastuctures representing the command-line and
config file arguments. All set (including defaults)
@@ -637,13 +617,11 @@ extern struct daemon {
int enable_pxe;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *force_broadcast, *bootp_dynamic;
char *dhcp_hosts_file, *dhcp_opts_file;
- int dhcp_max, tftp_max;
+ int dhcp_max;
int dhcp_server_port, dhcp_client_port;
- int start_tftp_port, end_tftp_port;
unsigned int min_leasetime;
struct doctor *doctors;
unsigned short edns_pktsz;
- char *tftp_prefix;
uint32_t listen_mark;
/* globally used stuff for DNS */
@@ -677,16 +655,6 @@ extern struct daemon {
FILE *lease_stream;
struct dhcp_bridge *bridges;
- /* DBus stuff */
- /* void * here to avoid depending on dbus headers outside dbus.c */
- void *dbus;
-#ifdef HAVE_DBUS
- struct watch *watches;
-#endif
-
- /* TFTP stuff */
- struct tftp_transfer *tftp_trans;
-
} *daemon;
/* cache.c */
@@ -875,14 +843,6 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
/* bpf.c or netlink.c */
int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)());
-/* dbus.c */
-#ifdef HAVE_DBUS
-char *dbus_init(void);
-void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
-void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
-void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
-#endif
-
/* helper.c */
#if defined(HAVE_DHCP) && !defined(NO_FORK)
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
@@ -891,9 +851,3 @@ void queue_script(int action, struct dhcp_lease *lease,
char *hostname, time_t now);
int helper_buf_empty(void);
#endif
-
-/* tftp.c */
-#ifdef HAVE_TFTP
-void tftp_request(struct listener *listen, time_t now);
-void check_tftp_listeners(fd_set *rset, time_t now);
-#endif
diff --git a/src/lease.c b/src/lease.c
index c021d15..985bd73 100755
--- a/src/lease.c
+++ b/src/lease.c
@@ -530,13 +530,6 @@ int do_script_run(time_t now)
{
struct dhcp_lease *lease;
-#ifdef HAVE_DBUS
- /* If we're going to be sending DBus signals, but the connection is not yet up,
- delay everything until it is. */
- if ((daemon->options & OPT_DBUS) && !daemon->dbus)
- return 0;
-#endif
-
if (old_leases)
{
lease = old_leases;
@@ -557,9 +550,6 @@ int do_script_run(time_t now)
#ifdef HAVE_SCRIPT
queue_script(ACTION_DEL, lease, lease->old_hostname, now);
#endif
-#ifdef HAVE_DBUS
- emit_dbus_signal(ACTION_DEL, lease, lease->old_hostname);
-#endif
old_leases = lease->next;
free(lease->old_hostname);
@@ -593,10 +583,6 @@ int do_script_run(time_t now)
queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease,
lease->fqdn ? lease->fqdn : lease->hostname, now);
#endif
-#ifdef HAVE_DBUS
- emit_dbus_signal(lease->new ? ACTION_ADD : ACTION_OLD, lease,
- lease->fqdn ? lease->fqdn : lease->hostname);
-#endif
lease->new = lease->changed = lease->aux_changed = 0;
/* these are used for the "add" call, then junked, since they're not in the database */
diff --git a/src/network.c b/src/network.c
index 1588288..b1a06e4 100755
--- a/src/network.c
+++ b/src/network.c
@@ -320,7 +320,6 @@ static int create_ipv6_listener(struct listener **link, int port)
l = safe_malloc(sizeof(struct listener));
l->fd = fd;
l->tcpfd = tcpfd;
- l->tftpfd = -1;
l->family = AF_INET6;
l->iface = NULL;
l->next = NULL;
@@ -335,7 +334,7 @@ struct listener *create_wildcard_listeners(void)
union mysockaddr addr;
int opt = 1;
struct listener *l, *l6 = NULL;
- int tcpfd = -1, fd = -1, tftpfd = -1;
+ int tcpfd = -1, fd = -1;
memset(&addr, 0, sizeof(addr));
addr.in.sin_family = AF_INET;
@@ -387,31 +386,11 @@ struct listener *create_wildcard_listeners(void)
}
}
#endif /* __ANDROID__ */
-
-#ifdef HAVE_TFTP
- if (daemon->options & OPT_TFTP)
- {
- addr.in.sin_port = htons(TFTP_PORT);
- if ((tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- return NULL;
-
- if (!fix_fd(tftpfd) ||
-#if defined(HAVE_LINUX_NETWORK)
- setsockopt(tftpfd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
-#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
- setsockopt(tftpfd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
- setsockopt(tftpfd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
-#endif
- bind(tftpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
- return NULL;
- }
-#endif
-
+
l = safe_malloc(sizeof(struct listener));
l->family = AF_INET;
l->fd = fd;
l->tcpfd = tcpfd;
- l->tftpfd = tftpfd;
l->iface = NULL;
l->next = l6;
@@ -442,7 +421,6 @@ void create_bound_listener(struct listener **listeners, struct irec *iface)
new->family = iface->addr.sa.sa_family;
new->iface = iface;
new->next = *listeners;
- new->tftpfd = -1;
new->tcpfd = -1;
new->fd = -1;
*listeners = new;
@@ -502,20 +480,6 @@ void create_bound_listener(struct listener **listeners, struct irec *iface)
if (listen(new->tcpfd, 5) == -1)
die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
}
-
-#ifdef HAVE_TFTP
- if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
- {
- short save = iface->addr.in.sin_port;
- iface->addr.in.sin_port = htons(TFTP_PORT);
- if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
- setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
- !fix_fd(new->tftpfd) ||
- bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
- die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
- iface->addr.in.sin_port = save;
- }
-#endif
}
/**
@@ -559,11 +523,6 @@ int delete_listener(struct listener **l)
my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
}
- if (listener->tftpfd != -1)
- {
- close(listener->tftpfd);
- listener->tftpfd = -1;
- }
if (listener->tcpfd != -1)
{
close(listener->tcpfd);
@@ -633,7 +592,6 @@ struct listener *create_bound_listeners(void)
new->family = iface->addr.sa.sa_family;
new->iface = iface;
new->next = listeners;
- new->tftpfd = -1;
new->tcpfd = -1;
new->fd = -1;
listeners = new;
@@ -686,20 +644,6 @@ struct listener *create_bound_listeners(void)
if (listen(new->tcpfd, 5) == -1)
die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
}
-
-#ifdef HAVE_TFTP
- if ((daemon->options & OPT_TFTP) && iface->addr.sa.sa_family == AF_INET && iface->dhcp_ok)
- {
- short save = iface->addr.in.sin_port;
- iface->addr.in.sin_port = htons(TFTP_PORT);
- if ((new->tftpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
- setsockopt(new->tftpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
- !fix_fd(new->tftpfd) ||
- bind(new->tftpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
- die(_("failed to create TFTP socket: %s"), NULL, EC_BADNET);
- iface->addr.in.sin_port = save;
- }
-#endif
#endif /* !__ANDROID */
}
diff --git a/src/option.c b/src/option.c
index 8d5a39e..3b190ab 100755
--- a/src/option.c
+++ b/src/option.c
@@ -611,7 +611,6 @@ static void do_usage(void)
{ '*', EDNS_PKTSZ },
{ '&', MAXLEASES },
{ '!', FTABSIZ },
- { '#', TFTP_MAX_CONNECTIONS },
{ '\0', 0 }
};
@@ -1585,33 +1584,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
option = '?';
break;
#endif
-
-#ifdef HAVE_TFTP
- case LOPT_TFTP_MAX: /* --tftp-max */
- if (!atoi_check(arg, &daemon->tftp_max))
- option = '?';
- break;
- case LOPT_PREFIX: /* --tftp-prefix */
- daemon->tftp_prefix = opt_string_alloc(arg);
- break;
-
- case LOPT_TFTPPORTS: /* --tftp-port-range */
- if (!(comma = split(arg)) ||
- !atoi_check16(arg, &daemon->start_tftp_port) ||
- !atoi_check16(comma, &daemon->end_tftp_port))
- problem = _("bad port range");
-
- if (daemon->start_tftp_port > daemon->end_tftp_port)
- {
- int tmp = daemon->start_tftp_port;
- daemon->start_tftp_port = daemon->end_tftp_port;
- daemon->end_tftp_port = tmp;
- }
-
- break;
-#endif
-
case LOPT_BRIDGE: /* --bridge-interface */
{
struct dhcp_bridge *new = opt_malloc(sizeof(struct dhcp_bridge));
@@ -2506,17 +2479,17 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
{
char *endptr;
uint32_t mark = strtoul(arg, &endptr, 0);
-my_syslog(LOG_WARNING, "passed-in mark: %s", arg);
+ // my_syslog(LOG_WARNING, "passed-in mark: %s", arg);
if (!*endptr)
daemon->listen_mark = mark;
else
problem = _("invalid mark");
-my_syslog(LOG_WARNING, "daemon->listen_mark: 0x%x, *endptr=%d", daemon->listen_mark, *endptr);
+ // my_syslog(LOG_WARNING, "daemon->listen_mark: 0x%x, *endptr=%d", daemon->listen_mark, *endptr);
break;
}
default:
- return _("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)");
+ return _("unsupported option (check that dnsmasq was compiled with DHCP support)");
}
@@ -2802,7 +2775,6 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon->username = CHUSER;
daemon->runfile = RUNFILE;
daemon->dhcp_max = MAXLEASES;
- daemon->tftp_max = TFTP_MAX_CONNECTIONS;
daemon->edns_pktsz = EDNS_PKTSZ;
daemon->log_fac = -1;
add_txt("version.bind", "dnsmasq-" VERSION );
diff --git a/src/tftp.c b/src/tftp.c
deleted file mode 100755
index c1ddb19..0000000
--- a/src/tftp.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* dnsmasq is Copyright (c) 2000-2009 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, or
- (at your option) version 3 dated 29 June, 2007.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "dnsmasq.h"
-
-#ifdef HAVE_TFTP
-
-static struct tftp_file *check_tftp_fileperm(ssize_t *len);
-static void free_transfer(struct tftp_transfer *transfer);
-static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
-static ssize_t tftp_err_oops(char *packet, char *file);
-static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
-static char *next(char **p, char *end);
-
-#define OP_RRQ 1
-#define OP_WRQ 2
-#define OP_DATA 3
-#define OP_ACK 4
-#define OP_ERR 5
-#define OP_OACK 6
-
-#define ERR_NOTDEF 0
-#define ERR_FNF 1
-#define ERR_PERM 2
-#define ERR_FULL 3
-#define ERR_ILL 4
-
-void tftp_request(struct listener *listen, time_t now)
-{
- ssize_t len;
- char *packet = daemon->packet;
- char *filename, *mode, *p, *end, *opt;
- struct sockaddr_in addr, peer;
- struct msghdr msg;
- struct iovec iov;
- struct ifreq ifr;
- int is_err = 1, if_index = 0, mtu = 0;
- struct iname *tmp;
- struct tftp_transfer *transfer;
- int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
-#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
- int mtuflag = IP_PMTUDISC_DONT;
-#endif
-
- union {
- struct cmsghdr align; /* this ensures alignment */
-#if defined(HAVE_LINUX_NETWORK)
- char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
-#elif defined(HAVE_SOLARIS_NETWORK)
- char control[CMSG_SPACE(sizeof(unsigned int))];
-#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
- char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
-#endif
- } control_u;
-
- msg.msg_controllen = sizeof(control_u);
- msg.msg_control = control_u.control;
- msg.msg_flags = 0;
- msg.msg_name = &peer;
- msg.msg_namelen = sizeof(peer);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- iov.iov_base = packet;
- iov.iov_len = daemon->packet_buff_sz;
-
- /* we overwrote the buffer... */
- daemon->srv_save = NULL;
-
- if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
- return;
-
- if (daemon->options & OPT_NOWILD)
- {
- addr = listen->iface->addr.in;
- mtu = listen->iface->mtu;
- }
- else
- {
- char name[IF_NAMESIZE];
- struct cmsghdr *cmptr;
-
- addr.sin_addr.s_addr = 0;
-
-#if defined(HAVE_LINUX_NETWORK)
- for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
- if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
- {
- addr.sin_addr = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_spec_dst;
- if_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
- }
-
-#elif defined(HAVE_SOLARIS_NETWORK)
- for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
- if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
- addr.sin_addr = *((struct in_addr *)CMSG_DATA(cmptr));
- else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
- if_index = *((unsigned int *)CMSG_DATA(cmptr));
-
-
-#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
- for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
- if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
- addr.sin_addr = *((struct in_addr *)CMSG_DATA(cmptr));
- else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
- if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
-
-#endif
-
- if (!indextoname(listen->tftpfd, if_index, name) ||
- addr.sin_addr.s_addr == 0 ||
- !iface_check(AF_INET, (struct all_addr *)&addr.sin_addr, name, &if_index))
- return;
-
- /* allowed interfaces are the same as for DHCP */
- for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
- if (tmp->name && (strcmp(tmp->name, name) == 0))
- return;
-
- strncpy(name, ifr.ifr_name, IF_NAMESIZE);
- if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
- mtu = ifr.ifr_mtu;
- }
-
- addr.sin_port = htons(port);
- addr.sin_family = AF_INET;
-#ifdef HAVE_SOCKADDR_SA_LEN
- addr.sin_len = sizeof(addr);
-#endif
-
- if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
- return;
-
- if ((transfer->sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- {
- free(transfer);
- return;
- }
-
- transfer->peer = peer;
- transfer->timeout = now + 2;
- transfer->backoff = 1;
- transfer->block = 1;
- transfer->blocksize = 512;
- transfer->offset = 0;
- transfer->file = NULL;
- transfer->opt_blocksize = transfer->opt_transize = 0;
- transfer->netascii = transfer->carrylf = 0;
-
- /* if we have a nailed-down range, iterate until we find a free one. */
- while (1)
- {
- if (bind(transfer->sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1 ||
-#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
- setsockopt(transfer->sockfd, SOL_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
-#endif
- !fix_fd(transfer->sockfd))
- {
- if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
- {
- if (++port <= daemon->end_tftp_port)
- {
- addr.sin_port = htons(port);
- continue;
- }
- my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
- }
- free_transfer(transfer);
- return;
- }
- break;
- }
-
- p = packet + 2;
- end = packet + len;
-
- if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
- !(filename = next(&p, end)) ||
- !(mode = next(&p, end)) ||
- (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
- len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), inet_ntoa(peer.sin_addr));
- else
- {
- if (strcasecmp(mode, "netascii") == 0)
- transfer->netascii = 1;
-
- while ((opt = next(&p, end)))
- {
- if (strcasecmp(opt, "blksize") == 0)
- {
- if ((opt = next(&p, end)) &&
- !(daemon->options & OPT_TFTP_NOBLOCK))
- {
- transfer->blocksize = atoi(opt);
- if (transfer->blocksize < 1)
- transfer->blocksize = 1;
- if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
- transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
- /* 32 bytes for IP, UDP and TFTP headers */
- if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
- transfer->blocksize = (unsigned)mtu - 32;
- transfer->opt_blocksize = 1;
- transfer->block = 0;
- }
- }
- else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
- {
- transfer->opt_transize = 1;
- transfer->block = 0;
- }
- }
-
- /* cope with backslashes from windows boxen. */
- while ((p = strchr(filename, '\\')))
- *p = '/';
-
- strcpy(daemon->namebuff, "/");
- if (daemon->tftp_prefix)
- {
- if (daemon->tftp_prefix[0] == '/')
- daemon->namebuff[0] = 0;
- strncat(daemon->namebuff, daemon->tftp_prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
- if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
- strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
-
- if (daemon->options & OPT_TFTP_APREF)
- {
- size_t oldlen = strlen(daemon->namebuff);
- struct stat statbuf;
-
- strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), (MAXDNAME-1) - strlen(daemon->namebuff));
- strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
-
- /* remove unique-directory if it doesn't exist */
- if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
- daemon->namebuff[oldlen] = 0;
- }
-
- /* 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] == '/')
- daemon->namebuff[0] = 0;
- strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
-
- /* check permissions and open file */
- if ((transfer->file = check_tftp_fileperm(&len)))
- {
- if ((len = get_block(packet, transfer)) == -1)
- len = tftp_err_oops(packet, daemon->namebuff);
- else
- is_err = 0;
- }
- }
-
- while (sendto(transfer->sockfd, packet, len, 0,
- (struct sockaddr *)&peer, sizeof(peer)) == -1 && errno == EINTR);
-
- if (is_err)
- free_transfer(transfer);
- else
- {
- my_syslog(MS_TFTP | LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
- transfer->next = daemon->tftp_trans;
- daemon->tftp_trans = transfer;
- }
-}
-
-static struct tftp_file *check_tftp_fileperm(ssize_t *len)
-{
- char *packet = daemon->packet, *namebuff = daemon->namebuff;
- struct tftp_file *file;
- struct tftp_transfer *t;
- uid_t uid = geteuid();
- struct stat statbuf;
- int fd = -1;
-
- /* trick to ban moving out of the subtree */
- if (daemon->tftp_prefix && strstr(namebuff, "/../"))
- goto perm;
-
- if ((fd = open(namebuff, O_RDONLY)) == -1)
- {
- if (errno == ENOENT)
- {
- *len = tftp_err(ERR_FNF, packet, _("file %s not found"), namebuff);
- return NULL;
- }
- else if (errno == EACCES)
- goto perm;
- else
- goto oops;
- }
-
- /* stat the file descriptor to avoid stat->open races */
- if (fstat(fd, &statbuf) == -1)
- goto oops;
-
- /* running as root, must be world-readable */
- if (uid == 0)
- {
- if (!(statbuf.st_mode & S_IROTH))
- goto perm;
- }
- /* in secure mode, must be owned by user running dnsmasq */
- else if ((daemon->options & OPT_TFTP_SECURE) && uid != statbuf.st_uid)
- goto perm;
-
- /* If we're doing many tranfers from the same file, only
- open it once this saves lots of file descriptors
- when mass-booting a big cluster, for instance.
- Be conservative and only share when inode and name match
- this keeps error messages sane. */
- for (t = daemon->tftp_trans; t; t = t->next)
- if (t->file->dev == statbuf.st_dev &&
- t->file->inode == statbuf.st_ino &&
- strcmp(t->file->filename, namebuff) == 0)
- {
- close(fd);
- t->file->refcount++;
- return t->file;
- }
-
- if (!(file = whine_malloc(sizeof(struct tftp_file) + strlen(namebuff) + 1)))
- {
- errno = ENOMEM;
- goto oops;
- }
-
- file->fd = fd;
- file->size = statbuf.st_size;
- file->dev = statbuf.st_dev;
- file->inode = statbuf.st_ino;
- file->refcount = 1;
- strcpy(file->filename, namebuff);
- return file;
-
- perm:
- errno = EACCES;
- *len = tftp_err(ERR_PERM, packet, _("cannot access %s: %s"), namebuff);
- if (fd != -1)
- close(fd);
- return NULL;
-
- oops:
- *len = tftp_err_oops(packet, namebuff);
- if (fd != -1)
- close(fd);
- return NULL;
-}
-
-void check_tftp_listeners(fd_set *rset, time_t now)
-{
- struct tftp_transfer *transfer, *tmp, **up;
- ssize_t len;
-
- struct ack {
- unsigned short op, block;
- } *mess = (struct ack *)daemon->packet;
-
- /* Check for activity on any existing transfers */
- for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
- {
- tmp = transfer->next;
-
- if (FD_ISSET(transfer->sockfd, rset))
- {
- /* we overwrote the buffer... */
- daemon->srv_save = NULL;
-
- if ((len = recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0)) >= (ssize_t)sizeof(struct ack))
- {
- if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block)
- {
- /* Got ack, ensure we take the (re)transmit path */
- transfer->timeout = now;
- transfer->backoff = 0;
- if (transfer->block++ != 0)
- transfer->offset += transfer->blocksize - transfer->expansion;
- }
- else if (ntohs(mess->op) == OP_ERR)
- {
- char *p = daemon->packet + sizeof(struct ack);
- char *end = daemon->packet + len;
- char *err = next(&p, end);
- /* Sanitise error message */
- if (!err)
- err = "";
- else
- {
- char *q, *r;
- for (q = r = err; *r; r++)
- if (isprint((int)*r))
- *(q++) = *r;
- *q = 0;
- }
- my_syslog(MS_TFTP | 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;
- transfer->backoff = 100;
- }
- }
- }
-
- if (difftime(now, transfer->timeout) >= 0.0)
- {
- int endcon = 0;
-
- /* timeout, retransmit */
- transfer->timeout += 1 + (1<<transfer->backoff);
-
- /* we overwrote the buffer... */
- daemon->srv_save = NULL;
-
- if ((len = get_block(daemon->packet, transfer)) == -1)
- {
- len = tftp_err_oops(daemon->packet, transfer->file->filename);
- endcon = 1;
- }
- else if (++transfer->backoff > 5)
- {
- /* don't complain about timeout when we're awaiting the last
- ACK, some clients never send it */
- if (len != 0)
- my_syslog(MS_TFTP | LOG_ERR, _("TFTP failed sending %s to %s"),
- transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
- len = 0;
- }
-
- if (len != 0)
- while(sendto(transfer->sockfd, daemon->packet, len, 0,
- (struct sockaddr *)&transfer->peer, sizeof(transfer->peer)) == -1 && errno == EINTR);
-
- if (endcon || len == 0)
- {
- /* unlink */
- *up = tmp;
- free_transfer(transfer);
- continue;
- }
- }
-
- up = &transfer->next;
- }
-}
-
-static void free_transfer(struct tftp_transfer *transfer)
-{
- close(transfer->sockfd);
- if (transfer->file && (--transfer->file->refcount) == 0)
- {
- close(transfer->file->fd);
- free(transfer->file);
- }
- free(transfer);
-}
-
-static char *next(char **p, char *end)
-{
- char *ret = *p;
- size_t len;
-
- if (*(end-1) != 0 ||
- *p == end ||
- (len = strlen(ret)) == 0)
- return NULL;
-
- *p += len + 1;
- return ret;
-}
-
-static ssize_t tftp_err(int err, char *packet, char *message, char *file)
-{
- struct errmess {
- unsigned short op, err;
- char message[];
- } *mess = (struct errmess *)packet;
- ssize_t ret = 4;
- char *errstr = strerror(errno);
-
- mess->op = htons(OP_ERR);
- mess->err = htons(err);
- ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
- my_syslog(MS_TFTP | LOG_ERR, "TFTP %s", mess->message);
-
- return ret;
-}
-
-static ssize_t tftp_err_oops(char *packet, char *file)
-{
- return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), file);
-}
-
-/* return -1 for error, zero for done. */
-static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
-{
- if (transfer->block == 0)
- {
- /* send OACK */
- char *p;
- struct oackmess {
- unsigned short op;
- char data[];
- } *mess = (struct oackmess *)packet;
-
- p = mess->data;
- mess->op = htons(OP_OACK);
- if (transfer->opt_blocksize)
- {
- p += (sprintf(p, "blksize") + 1);
- p += (sprintf(p, "%d", transfer->blocksize) + 1);
- }
- if (transfer->opt_transize)
- {
- p += (sprintf(p,"tsize") + 1);
- p += (sprintf(p, "%u", (unsigned int)transfer->file->size) + 1);
- }
-
- return p - packet;
- }
- else
- {
- /* send data packet */
- struct datamess {
- unsigned short op, block;
- unsigned char data[];
- } *mess = (struct datamess *)packet;
-
- size_t size = transfer->file->size - transfer->offset;
-
- if (transfer->offset > transfer->file->size)
- return 0; /* finished */
-
- if (size > transfer->blocksize)
- size = transfer->blocksize;
-
- mess->op = htons(OP_DATA);
- mess->block = htons((unsigned short)(transfer->block));
-
- if (lseek(transfer->file->fd, transfer->offset, SEEK_SET) == (off_t)-1 ||
- !read_write(transfer->file->fd, mess->data, size, 1))
- return -1;
-
- transfer->expansion = 0;
-
- /* Map '\n' to CR-LF in netascii mode */
- if (transfer->netascii)
- {
- size_t i;
- int newcarrylf;
-
- for (i = 0, newcarrylf = 0; i < size; i++)
- if (mess->data[i] == '\n' && ( i != 0 || !transfer->carrylf))
- {
- if (size == transfer->blocksize)
- {
- transfer->expansion++;
- if (i == size - 1)
- newcarrylf = 1; /* don't expand LF again if it moves to the next block */
- }
- else
- size++; /* room in this block */
-
- /* make space and insert CR */
- memmove(&mess->data[i+1], &mess->data[i], size - (i + 1));
- mess->data[i] = '\r';
-
- i++;
- }
- transfer->carrylf = newcarrylf;
-
- }
-
- return size + 4;
- }
-}
-
-#endif