summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2013-07-29 19:49:07 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2013-07-29 19:49:07 +0100
commit2937f8a0404604e431bc42abf3f931f68165c5e3 (patch)
tree4dfc66d11b156693f8a96cb30ade751407bb1592
parentedf0bde0c6837b010560c40e6b74d2f67b64da09 (diff)
downloaddnsmasq-2937f8a0404604e431bc42abf3f931f68165c5e3.tar.gz
Provide independent control over which interfaces get TFTP.
-rw-r--r--CHANGELOG6
-rw-r--r--man/dnsmasq.85
-rw-r--r--src/dnsmasq.h2
-rw-r--r--src/network.c10
-rw-r--r--src/option.c15
-rw-r--r--src/tftp.c36
6 files changed, 58 insertions, 16 deletions
diff --git a/CHANGELOG b/CHANGELOG
index bc27a53..78b9316 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -95,6 +95,12 @@ version 2.67
Make --listen-address higher priority than --except-interface
in all circumstances. Thanks to Thomas Hood for the bugreport.
+ Provide independent control over which interfaces get TFTP
+ service. If enable-tftp is given a list of interfaces, then TFTP
+ is provided on those. Without the list, the previous behaviour
+ (provide TFTP to the same interfaces we provide DHCP to)
+ is retained. Thanks to Lonnie Abelbeck for the suggestion.
+
version 2.66
Add the ability to act as an authoritative DNS
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 061c0ac..e843885 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -1493,11 +1493,12 @@ drops back to sending "maintenance" advertisements every 10 minutes or so. This
frequent RA mode. It's a bug workaround for mobile devices which go deaf to RAs during sleep and therefore
lose conectivity; with frequent RAs they recover in a reasonable time after wakeup.
.TP
-.B --enable-tftp
+.B --enable-tftp[=<interface>[,<interface>]]
Enable the TFTP server function. This is deliberately limited to that
needed to net-boot a client. Only reading is allowed; the tsize and
blksize extensions are supported (tsize is only supported in octet
-mode).
+mode). Without an argument, the TFTP service is provided to the same set of interfaces as DHCP service.
+If the list of interfaces is provided, that defines which interfaces recieve TFTP service.
.TP
.B --tftp-root=<directory>[,<interface>]
Look for files to transfer using TFTP relative to the given
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 38c8a4d..0295376 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -803,7 +803,7 @@ extern struct daemon {
struct cond_domain *cond_domain, *synth_domains;
char *runfile;
char *lease_change_command;
- struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
+ struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
struct bogus_addr *bogus_addr;
struct server *servers;
struct ipsets *ipsets;
diff --git a/src/network.c b/src/network.c
index 9833973..7a5d49e 100644
--- a/src/network.c
+++ b/src/network.c
@@ -359,6 +359,16 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
}
#endif
+
+ if (daemon->tftp_interfaces)
+ {
+ /* dedicated tftp interface list */
+ tftp_ok = 0;
+ for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
+ if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
+ tftp_ok = 1;
+ }
+
/* add to list */
if ((iface = whine_malloc(sizeof(struct irec))))
{
diff --git a/src/option.c b/src/option.c
index 1dc3753..006e4cc 100644
--- a/src/option.c
+++ b/src/option.c
@@ -208,7 +208,7 @@ static const struct myoption opts[] =
{ "dns-forward-max", 1, 0, '0' },
{ "clear-on-reload", 0, 0, LOPT_RELOAD },
{ "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
- { "enable-tftp", 0, 0, LOPT_TFTP },
+ { "enable-tftp", 2, 0, LOPT_TFTP },
{ "tftp-secure", 0, 0, LOPT_SECURE },
{ "tftp-unique-root", 0, 0, LOPT_APREF },
{ "tftp-root", 1, 0, LOPT_PREFIX },
@@ -368,7 +368,7 @@ static struct {
{ LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE },
{ LOPT_NO_NAMES, ARG_DUP, "[=tag:<tag>]...", gettext_noop("Ignore hostnames provided by DHCP clients."), NULL },
{ LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL },
- { LOPT_TFTP, OPT_TFTP, NULL, gettext_noop("Enable integrated read-only TFTP server."), NULL },
+ { LOPT_TFTP, ARG_DUP, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL },
{ LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
{ LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },
{ LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
@@ -1904,6 +1904,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
} while (arg);
break;
+ case LOPT_TFTP: /* --enable-tftp */
+ set_option_bool(OPT_TFTP);
+ if (!arg)
+ break;
+ /* fall through */
+
case 'I': /* --except-interface */
case '2': /* --no-dhcp-interface */
do {
@@ -1915,6 +1921,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->next = daemon->if_except;
daemon->if_except = new;
}
+ else if (option == LOPT_TFTP)
+ {
+ new->next = daemon->tftp_interfaces;
+ daemon->tftp_interfaces = new;
+ }
else
{
new->next = daemon->dhcp_except;
diff --git a/src/tftp.c b/src/tftp.c
index 088fb92..d611dea 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -198,22 +198,36 @@ void tftp_request(struct listener *listen, time_t now)
addra.addr.addr6 = addr.in6.sin6_addr;
#endif
- if (!iface_check(listen->family, &addra, name, NULL))
+ if (daemon->tftp_interfaces)
{
- if (!option_bool(OPT_CLEVERBIND))
- enumerate_interfaces(0);
- if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
- !label_exception(if_index, listen->family, &addra) )
+ /* dedicated tftp interface list */
+ for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
+ if (tmp->name && wildcard_match(tmp->name, name))
+ break;
+
+ if (!tmp)
return;
}
-
+ else
+ {
+ /* Do the same as DHCP */
+ if (!iface_check(listen->family, &addra, name, NULL))
+ {
+ if (!option_bool(OPT_CLEVERBIND))
+ enumerate_interfaces(0);
+ if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
+ !label_exception(if_index, listen->family, &addra) )
+ return;
+ }
+
#ifdef HAVE_DHCP
- /* allowed interfaces are the same as for DHCP */
- for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
- if (tmp->name && wildcard_match(tmp->name, name))
- return;
+ /* allowed interfaces are the same as for DHCP */
+ for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+ if (tmp->name && wildcard_match(tmp->name, name))
+ return;
#endif
-
+ }
+
strncpy(ifr.ifr_name, name, IF_NAMESIZE);
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu;