Commit 2937f8a0 authored by Simon Kelley's avatar Simon Kelley

Provide independent control over which interfaces get TFTP.

parent edf0bde0
...@@ -95,6 +95,12 @@ version 2.67 ...@@ -95,6 +95,12 @@ version 2.67
Make --listen-address higher priority than --except-interface Make --listen-address higher priority than --except-interface
in all circumstances. Thanks to Thomas Hood for the bugreport. 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 version 2.66
Add the ability to act as an authoritative DNS Add the ability to act as an authoritative DNS
......
...@@ -1493,11 +1493,12 @@ drops back to sending "maintenance" advertisements every 10 minutes or so. This ...@@ -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 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. lose conectivity; with frequent RAs they recover in a reasonable time after wakeup.
.TP .TP
.B --enable-tftp .B --enable-tftp[=<interface>[,<interface>]]
Enable the TFTP server function. This is deliberately limited to that Enable the TFTP server function. This is deliberately limited to that
needed to net-boot a client. Only reading is allowed; the tsize and needed to net-boot a client. Only reading is allowed; the tsize and
blksize extensions are supported (tsize is only supported in octet 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 .TP
.B --tftp-root=<directory>[,<interface>] .B --tftp-root=<directory>[,<interface>]
Look for files to transfer using TFTP relative to the given Look for files to transfer using TFTP relative to the given
......
...@@ -803,7 +803,7 @@ extern struct daemon { ...@@ -803,7 +803,7 @@ extern struct daemon {
struct cond_domain *cond_domain, *synth_domains; struct cond_domain *cond_domain, *synth_domains;
char *runfile; char *runfile;
char *lease_change_command; 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 bogus_addr *bogus_addr;
struct server *servers; struct server *servers;
struct ipsets *ipsets; struct ipsets *ipsets;
......
...@@ -359,6 +359,16 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, ...@@ -359,6 +359,16 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
} }
#endif #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 */ /* add to list */
if ((iface = whine_malloc(sizeof(struct irec)))) if ((iface = whine_malloc(sizeof(struct irec))))
{ {
......
...@@ -208,7 +208,7 @@ static const struct myoption opts[] = ...@@ -208,7 +208,7 @@ static const struct myoption opts[] =
{ "dns-forward-max", 1, 0, '0' }, { "dns-forward-max", 1, 0, '0' },
{ "clear-on-reload", 0, 0, LOPT_RELOAD }, { "clear-on-reload", 0, 0, LOPT_RELOAD },
{ "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES }, { "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-secure", 0, 0, LOPT_SECURE },
{ "tftp-unique-root", 0, 0, LOPT_APREF }, { "tftp-unique-root", 0, 0, LOPT_APREF },
{ "tftp-root", 1, 0, LOPT_PREFIX }, { "tftp-root", 1, 0, LOPT_PREFIX },
...@@ -368,7 +368,7 @@ static struct { ...@@ -368,7 +368,7 @@ static struct {
{ LOPT_RELOAD, OPT_RELOAD, NULL, gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE }, { 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_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_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_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_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 }, { 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 ...@@ -1904,6 +1904,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
} while (arg); } while (arg);
break; break;
case LOPT_TFTP: /* --enable-tftp */
set_option_bool(OPT_TFTP);
if (!arg)
break;
/* fall through */
case 'I': /* --except-interface */ case 'I': /* --except-interface */
case '2': /* --no-dhcp-interface */ case '2': /* --no-dhcp-interface */
do { do {
...@@ -1915,6 +1921,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -1915,6 +1921,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->next = daemon->if_except; new->next = daemon->if_except;
daemon->if_except = new; daemon->if_except = new;
} }
else if (option == LOPT_TFTP)
{
new->next = daemon->tftp_interfaces;
daemon->tftp_interfaces = new;
}
else else
{ {
new->next = daemon->dhcp_except; new->next = daemon->dhcp_except;
......
...@@ -198,22 +198,36 @@ void tftp_request(struct listener *listen, time_t now) ...@@ -198,22 +198,36 @@ void tftp_request(struct listener *listen, time_t now)
addra.addr.addr6 = addr.in6.sin6_addr; addra.addr.addr6 = addr.in6.sin6_addr;
#endif #endif
if (!iface_check(listen->family, &addra, name, NULL)) if (daemon->tftp_interfaces)
{ {
if (!option_bool(OPT_CLEVERBIND)) /* dedicated tftp interface list */
enumerate_interfaces(0); for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) && if (tmp->name && wildcard_match(tmp->name, name))
!label_exception(if_index, listen->family, &addra) ) break;
if (!tmp)
return; 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 #ifdef HAVE_DHCP
/* allowed interfaces are the same as for DHCP */ /* allowed interfaces are the same as for DHCP */
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, name)) if (tmp->name && wildcard_match(tmp->name, name))
return; return;
#endif #endif
}
strncpy(ifr.ifr_name, name, IF_NAMESIZE); strncpy(ifr.ifr_name, name, IF_NAMESIZE);
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1) if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu; mtu = ifr.ifr_mtu;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment