diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2013-07-29 19:49:07 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2013-07-29 19:49:07 +0100 |
commit | 2937f8a0404604e431bc42abf3f931f68165c5e3 (patch) | |
tree | 4dfc66d11b156693f8a96cb30ade751407bb1592 | |
parent | edf0bde0c6837b010560c40e6b74d2f67b64da09 (diff) | |
download | dnsmasq-2937f8a0404604e431bc42abf3f931f68165c5e3.tar.gz |
Provide independent control over which interfaces get TFTP.
-rw-r--r-- | CHANGELOG | 6 | ||||
-rw-r--r-- | man/dnsmasq.8 | 5 | ||||
-rw-r--r-- | src/dnsmasq.h | 2 | ||||
-rw-r--r-- | src/network.c | 10 | ||||
-rw-r--r-- | src/option.c | 15 | ||||
-rw-r--r-- | src/tftp.c | 36 |
6 files changed, 58 insertions, 16 deletions
@@ -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; @@ -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; |