Commit 6b01084f authored by Simon Kelley's avatar Simon Kelley

import of dnsmasq-2.38.tar.gz

parent 1b7ecd11
...@@ -2119,7 +2119,36 @@ version 2.37 ...@@ -2119,7 +2119,36 @@ version 2.37
Added a LIMITS section to the man-page, with guidance on Added a LIMITS section to the man-page, with guidance on
maximum numbers of clients, file sizes and tuning. maximum numbers of clients, file sizes and tuning.
release 2.38
Fix compilation on *BSD. Thanks to Tom Hensel.
Don't send length zero DHCP option 43 and cope with
encapsulated options whose total length exceeds 255 octets
by splitting them into multiple option 43 pieces.
Avoid queries being retried forever when --strict-order is
set and an upstream server returns a SERVFAIL
error. Thanks to Johannes Stezenbach for spotting this.
Fix BOOTP support, broken in version 2.37.
Add example dhcp-options for Etherboot.
Add \e (for ASCII ESCape) to the set of valid escapes
in config-file strings.
Added --dhcp-option-force flag and examples in the
configuration file which use this to control PXELinux.
Added --tftp-no-blocksize option.
Set netid tag "bootp" when BOOTP (rather than DHCP) is in
use. This makes it easy to customise which options are
sent to BOOTP clients. (BOOTP allows only 64 octets for
options, so it can be necessary to trim things.)
Fix rare hang in cache code, a 2.37 regression. This
probably needs an infinite DHCP lease and some bad luck to
trigger. Thanks to Detlef Reichelt for bug reports and testing.
...@@ -276,6 +276,23 @@ ...@@ -276,6 +276,23 @@
# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true # http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
#dhcp-option=vendor:MSFT,2,1i #dhcp-option=vendor:MSFT,2,1i
# Send the Encapsulated-vendor-class ID needed by some configurations of
# Etherboot to allow is to recognise the DHCP server.
#dhcp-option=vendor:Etherboot,60,"Etherboot"
# Send options to PXELinux. Note that we need to send the options even
# though they don't appear in the parameter request list, so we need
# to use dhcp-option-force here.
# See http://syslinux.zytor.com/pxe.php#special for details.
# Magic number - needed before anything else is recognised
#dhcp-option-force=208,f1:00:74:7e
# Configuration file name
#dhcp-option-force=209,configs/common
# Path prefix
#dhcp-option-force=210,/tftpboot/pxelinux/files/
# Reboot time. (Note 'i' to send 32-bit value)
#dhcp-option-force=211,30i
# Set the boot filename for BOOTP. You will only need # Set the boot filename for BOOTP. You will only need
# this is you want to boot machines over the network and you will need # this is you want to boot machines over the network and you will need
# a TFTP server; either dnsmasq's built in TFTP server or an # a TFTP server; either dnsmasq's built in TFTP server or an
......
...@@ -484,13 +484,23 @@ Encapsulated Vendor-class options may also be specified using ...@@ -484,13 +484,23 @@ Encapsulated Vendor-class options may also be specified using
sends the encapsulated vendor sends the encapsulated vendor
class-specific option "mftp-address=0.0.0.0" to any client whose class-specific option "mftp-address=0.0.0.0" to any client whose
vendor-class matches "PXEClient". The vendor-class matching is vendor-class matches "PXEClient". The vendor-class matching is
substring based (see --dhcp-vendorclass for details) and it is substring based (see --dhcp-vendorclass for details). If a
vendor-class option (number 60) is sent by dnsmasq, then that is used
for selecting encapsulated options in preference to any sent by the
client. It is
possible to omit the vendorclass completely; possible to omit the vendorclass completely;
.B --dhcp-option=vendor:,1,0.0.0.0 .B --dhcp-option=vendor:,1,0.0.0.0
in which case the encapsulated option is always sent. in which case the encapsulated option is always sent.
The address 0.0.0.0 is not treated specially in The address 0.0.0.0 is not treated specially in
encapsulated vendor class options. encapsulated vendor class options.
.TP .TP
.B --dhcp-option-force=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],]<opt>,[<value>[,<value>]]
This works in exactly the same way as
.B --dhcp-otion
except that the option will always be sent, even of the client does
not ask for it in the parameter request list. This is sometimes
needed, for example when sending options to PXELinux.
.TP
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class> .B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
Map from a vendor-class string to a network id. Most DHCP clients provide a Map from a vendor-class string to a network id. Most DHCP clients provide a
"vendor class" which represents, in some sense, the type of host. This option "vendor class" which represents, in some sense, the type of host. This option
...@@ -686,6 +696,11 @@ file descriptor per unique file (plus a few others). So serving the ...@@ -686,6 +696,11 @@ file descriptor per unique file (plus a few others). So serving the
same file simultaneously to n clients will use require about n + 10 file same file simultaneously to n clients will use require about n + 10 file
descriptors, serving different files simultaneously to n clients will descriptors, serving different files simultaneously to n clients will
require about (2*n) + 10 descriptors. require about (2*n) + 10 descriptors.
.TP
.B --tftp-no-blocksize
Stop the TFTP server from negotiating the "blocksize" option with a
client. Some buggy clients request this option but then behave badly
when it is granted.
.TP .TP
.B \-C, --conf-file=<file> .B \-C, --conf-file=<file>
Specify a different configuration file. The conf-file option is also allowed in Specify a different configuration file. The conf-file option is also allowed in
...@@ -835,7 +850,7 @@ on a particular network. (Setting --bootp-dynamic removes the need for ...@@ -835,7 +850,7 @@ on a particular network. (Setting --bootp-dynamic removes the need for
static address mappings.) The filename static address mappings.) The filename
parameter in a BOOTP request is matched against netids in parameter in a BOOTP request is matched against netids in
.B dhcp-option .B dhcp-option
configurations, allowing some control over the options returned to configurations, as is the tag "bootp", allowing some control over the options returned to
different classes of hosts. different classes of hosts.
.SH LIMITS .SH LIMITS
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "dnsmasq.h" #include "dnsmasq.h"
static struct crec *cache_head, *cache_tail, **hash_table; static struct crec *cache_head, *cache_tail, **hash_table;
static struct crec *dhcp_inuse, *dhcp_spare, *new_chain; static struct crec *dhcp_spare, *new_chain;
static int cache_inserted, cache_live_freed, insert_error; static int cache_inserted, cache_live_freed, insert_error;
static union bigname *big_free; static union bigname *big_free;
static int bignames_left, log_queries, cache_size, hash_size; static int bignames_left, log_queries, cache_size, hash_size;
...@@ -74,7 +74,7 @@ void cache_init(int size, int logq) ...@@ -74,7 +74,7 @@ void cache_init(int size, int logq)
addrbuff = NULL; addrbuff = NULL;
cache_head = cache_tail = NULL; cache_head = cache_tail = NULL;
dhcp_inuse = dhcp_spare = NULL; dhcp_spare = NULL;
new_chain = NULL; new_chain = NULL;
hash_table = NULL; hash_table = NULL;
cache_size = size; cache_size = size;
...@@ -170,7 +170,7 @@ static void cache_hash(struct crec *crecp) ...@@ -170,7 +170,7 @@ static void cache_hash(struct crec *crecp)
up = &((*up)->hash_next); up = &((*up)->hash_next);
if (crecp->flags & F_IMMORTAL) if (crecp->flags & F_IMMORTAL)
while (*up && (!(*up)->flags & F_IMMORTAL)) while (*up && !((*up)->flags & F_IMMORTAL))
up = &((*up)->hash_next); up = &((*up)->hash_next);
} }
crecp->hash_next = *up; crecp->hash_next = *up;
...@@ -282,9 +282,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign ...@@ -282,9 +282,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
if (flags & F_FORWARD) if (flags & F_FORWARD)
{ {
for (up = hash_bucket(name), crecp = *up; for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
crecp = crecp->hash_next)
if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp)) if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
{ {
*up = crecp->hash_next; *up = crecp->hash_next;
...@@ -601,8 +599,7 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr, ...@@ -601,8 +599,7 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
crecp = crecp->hash_next) crecp = crecp->hash_next)
if (!is_expired(now, crecp)) if (!is_expired(now, crecp))
{ {
if ((crecp->flags & F_REVERSE) && if ((crecp->flags & prot) &&
(crecp->flags & prot) &&
memcmp(&crecp->addr.addr, addr, addrlen) == 0) memcmp(&crecp->addr.addr, addr, addrlen) == 0)
{ {
if (crecp->flags & (F_HOSTS | F_DHCP)) if (crecp->flags & (F_HOSTS | F_DHCP))
...@@ -834,25 +831,19 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a ...@@ -834,25 +831,19 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a
void cache_unhash_dhcp(void) void cache_unhash_dhcp(void)
{ {
struct crec *tmp, *cache, **up; struct crec *cache, **up;
int i; int i;
for (i=0; i<hash_size; i++) for (i=0; i<hash_size; i++)
for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next) for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
if (cache->flags & F_DHCP) if (cache->flags & F_DHCP)
*up = cache->hash_next; {
*up = cache->hash_next;
cache->next = dhcp_spare;
dhcp_spare = cache;
}
else else
up = &cache->hash_next; up = &cache->hash_next;
/* prev field links all dhcp entries */
for (cache = dhcp_inuse; cache; cache = tmp)
{
tmp = cache->prev;
cache->prev = dhcp_spare;
dhcp_spare = cache;
}
dhcp_inuse = NULL;
} }
void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
...@@ -893,7 +884,7 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -893,7 +884,7 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
} }
if ((crec = dhcp_spare)) if ((crec = dhcp_spare))
dhcp_spare = dhcp_spare->prev; dhcp_spare = dhcp_spare->next;
else /* need new one */ else /* need new one */
crec = malloc(sizeof(struct crec)); crec = malloc(sizeof(struct crec));
...@@ -906,14 +897,10 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -906,14 +897,10 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
crec->ttd = ttd; crec->ttd = ttd;
crec->addr.addr.addr.addr4 = *host_address; crec->addr.addr.addr.addr4 = *host_address;
crec->name.namep = host_name; crec->name.namep = host_name;
crec->prev = dhcp_inuse;
dhcp_inuse = crec;
cache_hash(crec); cache_hash(crec);
} }
} }
void dump_cache(struct daemon *daemon, time_t now) 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."), syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#define VERSION "2.37" #define VERSION "2.38"
#define FTABSIZ 150 /* max number of outstanding requests (default) */ #define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* max no children for TCP requests */ #define MAX_PROCS 20 /* max no children for TCP requests */
...@@ -180,7 +180,7 @@ NOTES: ...@@ -180,7 +180,7 @@ NOTES:
# error HAVE_ISC_READER is not compatible with HAVE_BROKEN_RTC # error HAVE_ISC_READER is not compatible with HAVE_BROKEN_RTC
#endif #endif
/* Allow TFTP to be disabled with CFLAGS=-DNO_TFTP */ /* Allow TFTP to be disabled with COPT=-DNO_TFTP */
#ifdef NO_TFTP #ifdef NO_TFTP
#undef HAVE_TFTP #undef HAVE_TFTP
#endif #endif
...@@ -276,6 +276,7 @@ typedef unsigned long in_addr_t; ...@@ -276,6 +276,7 @@ typedef unsigned long in_addr_t;
#endif #endif
/* Decide if we're going to support IPv6 */ /* Decide if we're going to support IPv6 */
/* IPv6 can be forced off with "make COPTS=-DNO_IPV6" */
/* We assume that systems which don't have IPv6 /* We assume that systems which don't have IPv6
headers don't have ntop and pton either */ headers don't have ntop and pton either */
......
...@@ -114,6 +114,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data); ...@@ -114,6 +114,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data);
#define OPT_RELOAD (1<<24) #define OPT_RELOAD (1<<24)
#define OPT_TFTP (1<<25) #define OPT_TFTP (1<<25)
#define OPT_TFTP_SECURE (1<<26) #define OPT_TFTP_SECURE (1<<26)
#define OPT_TFTP_NOBLOCK (1<<27)
struct all_addr { struct all_addr {
union { union {
...@@ -365,7 +366,9 @@ struct dhcp_opt { ...@@ -365,7 +366,9 @@ struct dhcp_opt {
#define DHOPT_ADDR 1 #define DHOPT_ADDR 1
#define DHOPT_STRING 2 #define DHOPT_STRING 2
#define DHOPT_VENDOR_MATCH 4 #define DHOPT_ENCAPSULATE 4
#define DHOPT_VENDOR_MATCH 8
#define DHOPT_FORCE 16
struct dhcp_boot { struct dhcp_boot {
char *file, *sname; char *file, *sname;
...@@ -474,7 +477,7 @@ struct daemon { ...@@ -474,7 +477,7 @@ struct daemon {
struct hostsfile *addn_hosts; struct hostsfile *addn_hosts;
struct dhcp_context *dhcp; struct dhcp_context *dhcp;
struct dhcp_config *dhcp_conf; struct dhcp_config *dhcp_conf;
struct dhcp_opt *dhcp_opts, *vendor_opts; struct dhcp_opt *dhcp_opts;
struct dhcp_vendor *dhcp_vendors; struct dhcp_vendor *dhcp_vendors;
struct dhcp_mac *dhcp_macs; struct dhcp_mac *dhcp_macs;
struct dhcp_boot *boot_config; struct dhcp_boot *boot_config;
......
...@@ -447,7 +447,9 @@ void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now) ...@@ -447,7 +447,9 @@ void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now)
{ {
struct server *server = forward->sentto; struct server *server = forward->sentto;
if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0) if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
!(daemon->options & OPT_ORDER) &&
forward->forwardall == 0)
/* for broken servers, attempt to send to another one. */ /* for broken servers, attempt to send to another one. */
{ {
unsigned char *pheader; unsigned char *pheader;
......
...@@ -35,6 +35,8 @@ struct myoption { ...@@ -35,6 +35,8 @@ struct myoption {
#define LOPT_PTR 261 #define LOPT_PTR 261
#define LOPT_BRIDGE 262 #define LOPT_BRIDGE 262
#define LOPT_TFTP_MAX 263 #define LOPT_TFTP_MAX 263
#define LOPT_FORCE 264
#define LOPT_NOBLOCK 265
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
static const struct option opts[] = static const struct option opts[] =
...@@ -117,6 +119,8 @@ static const struct myoption opts[] = ...@@ -117,6 +119,8 @@ static const struct myoption opts[] =
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)
{"bridge-interface", 1, 0 , LOPT_BRIDGE }, {"bridge-interface", 1, 0 , LOPT_BRIDGE },
#endif #endif
{"dhcp-option-force", 1, 0, LOPT_FORCE },
{"tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
...@@ -151,6 +155,7 @@ static const struct optflags optmap[] = { ...@@ -151,6 +155,7 @@ static const struct optflags optmap[] = {
{ LOPT_RELOAD, OPT_RELOAD }, { LOPT_RELOAD, OPT_RELOAD },
{ LOPT_TFTP, OPT_TFTP }, { LOPT_TFTP, OPT_TFTP },
{ LOPT_SECURE, OPT_TFTP_SECURE }, { LOPT_SECURE, OPT_TFTP_SECURE },
{ LOPT_NOBLOCK, OPT_TFTP_NOBLOCK },
{ 'v', 0}, { 'v', 0},
{ 'w', 0}, { 'w', 0},
{ 0, 0 } { 0, 0 }
...@@ -190,7 +195,8 @@ static const struct { ...@@ -190,7 +195,8 @@ static const struct {
{ "-n, --no-poll", gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE }, { "-n, --no-poll", gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE },
{ "-N, --no-negcache", gettext_noop("Do NOT cache failed search results."), NULL }, { "-N, --no-negcache", gettext_noop("Do NOT cache failed search results."), NULL },
{ "-o, --strict-order", gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE }, { "-o, --strict-order", gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE },
{ "-O, --dhcp-option=<optspec>", gettext_noop("Set extra options to be set to DHCP clients."), NULL }, { "-O, --dhcp-option=<optspec>", gettext_noop("Specify options to be sent to DHCP clients."), NULL },
{ " --dhcp-option-force=<optspec>", gettext_noop("DHCP option sent even if the client does not request it."), NULL},
{ "-p, --port=number", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL }, { "-p, --port=number", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
{ "-P, --edns-packet-max=<size>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" }, { "-P, --edns-packet-max=<size>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
{ "-q, --log-queries", gettext_noop("Log queries."), NULL }, { "-q, --log-queries", gettext_noop("Log queries."), NULL },
...@@ -234,17 +240,18 @@ static const struct { ...@@ -234,17 +240,18 @@ static const struct {
{ " --tftp-root=<directory>", gettext_noop("Export files by TFTP only from the specified subtree."), NULL }, { " --tftp-root=<directory>", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
{ " --tftp-secure", gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL }, { " --tftp-secure", gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
{ " --tftp-max=<connections>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" }, { " --tftp-max=<connections>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
{ " --tftp-no-blocksize", gettext_noop("Disable the TFTP blocksize extension."), NULL },
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
/* We hide metacharaters in quoted strings by mapping them into the ASCII control /* We hide metacharaters in quoted strings by mapping them into the ASCII control
character space. Note that the \0, \t \a \b \r and \n characters are carefully placed in the character space. Note that the \0, \t \a \b \r \033 and \n characters are carefully placed in the
following sequence so that they map to themselves: it is therefore possible to call following sequence so that they map to themselves: it is therefore possible to call
unhide_metas repeatedly on string without breaking things. unhide_metas repeatedly on string without breaking things.
The transformation gets undone by opt_canonicalise, atoi_check and safe_string_alloc, and a The transformation gets undone by opt_canonicalise, atoi_check and safe_string_alloc, and a
couple of other places. */ couple of other places. */
static const char meta[] = "\000123456\a\b\t\n78\r90abcdefABCDEF:,."; static const char meta[] = "\000123456\a\b\t\n78\r90abcdefABCDE\033F:,.";
static void one_file(struct daemon *daemon, char *file, int nest); static void one_file(struct daemon *daemon, char *file, int nest);
...@@ -380,15 +387,15 @@ static void do_usage(void) ...@@ -380,15 +387,15 @@ static void do_usage(void)
} }
/* This is too insanely large to keep in-line in the switch */ /* This is too insanely large to keep in-line in the switch */
static char *parse_dhcp_opt(struct daemon *daemon, char *arg) static char *parse_dhcp_opt(struct daemon *daemon, char *arg, int forced)
{ {
struct dhcp_opt *new = safe_malloc(sizeof(struct dhcp_opt)); struct dhcp_opt *new = safe_malloc(sizeof(struct dhcp_opt));
char lenchar = 0, *cp; char lenchar = 0, *cp;
int addrs, digs, is_addr, is_hex, is_dec, is_vend = 0; int addrs, digs, is_addr, is_hex, is_dec;
char *comma, *problem = NULL; char *comma, *problem = NULL;
new->len = 0; new->len = 0;
new->flags = 0; new->flags = forced ? DHOPT_FORCE : 0;
new->netid = NULL; new->netid = NULL;
new->val = NULL; new->val = NULL;
new->vendor_class = NULL; new->vendor_class = NULL;
...@@ -408,7 +415,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg) ...@@ -408,7 +415,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg)
if (strstr(arg, "vendor:") == arg) if (strstr(arg, "vendor:") == arg)
{ {
new->vendor_class = (unsigned char *)safe_string_alloc(arg+7); new->vendor_class = (unsigned char *)safe_string_alloc(arg+7);
is_vend = 1; new->flags |= DHOPT_ENCAPSULATE;
} }
else else
{ {
...@@ -488,7 +495,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg) ...@@ -488,7 +495,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg)
new->len = 2; new->len = 2;
else if (lenchar == 'i') else if (lenchar == 'i')
new->len = 4; new->len = 4;
else if (new->vendor_class) else if (new->flags & DHOPT_ENCAPSULATE)
{ {
if (val & 0xffff0000) if (val & 0xffff0000)
new->len = 4; new->len = 4;
...@@ -517,12 +524,12 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg) ...@@ -517,12 +524,12 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg)
/* max length of address/subnet descriptor is five bytes, /* max length of address/subnet descriptor is five bytes,
add one for the option 120 enc byte too */ add one for the option 120 enc byte too */
new->val = op = safe_malloc((5 * addrs) + 1); new->val = op = safe_malloc((5 * addrs) + 1);
if (!new->vendor_class) new->flags |= DHOPT_ADDR;
if (!(new->flags & DHOPT_ENCAPSULATE) && new->opt == 120)
{ {
if (new->opt == 120) *(op++) = 1; /* RFC 3361 "enc byte" */
*(op++) = 1; /* RFC 3361 "enc byte" */ new->flags &= ~DHOPT_ADDR;
else
new->flags |= DHOPT_ADDR;
} }
while (addrs--) while (addrs--)
{ {
...@@ -558,7 +565,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg) ...@@ -558,7 +565,7 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg)
else else
{ {
/* text arg */ /* text arg */
if ((new->opt == 119 || new->opt == 120) && !new->vendor_class) if ((new->opt == 119 || new->opt == 120) && !(new->flags & DHOPT_ENCAPSULATE))
{ {
/* dns search, RFC 3397, or SIP, RFC 3361 */ /* dns search, RFC 3397, or SIP, RFC 3361 */
unsigned char *q, *r, *tail; unsigned char *q, *r, *tail;
...@@ -643,11 +650,6 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg) ...@@ -643,11 +650,6 @@ static char *parse_dhcp_opt(struct daemon *daemon, char *arg)
free(new->vendor_class); free(new->vendor_class);
free(new); free(new);
} }
else if (is_vend)
{
new->next = daemon->vendor_opts;
daemon->vendor_opts = new;
}
else else
{ {
new->next = daemon->dhcp_opts; new->next = daemon->dhcp_opts;
...@@ -1501,7 +1503,8 @@ static char *one_opt(struct daemon *daemon, int option, char *arg, char *problem ...@@ -1501,7 +1503,8 @@ static char *one_opt(struct daemon *daemon, int option, char *arg, char *problem
} }
case 'O': case 'O':
if ((problem = parse_dhcp_opt(daemon, arg))) case LOPT_FORCE:
if ((problem = parse_dhcp_opt(daemon, arg, option == LOPT_FORCE)))
option = '?'; option = '?';
break; break;
...@@ -1899,6 +1902,8 @@ static void one_file(struct daemon *daemon, char *file, int nest) ...@@ -1899,6 +1902,8 @@ static void one_file(struct daemon *daemon, char *file, int nest)
p[1] = '\b'; p[1] = '\b';
else if (p[1] == 'r') else if (p[1] == 'r')
p[1] = '\r'; p[1] = '\r';
else if (p[1] == 'e') /* escape */
p[1] = '\033';
memmove(p, p+1, strlen(p+1)+1); memmove(p, p+1, strlen(p+1)+1);
} }
*p = hide_meta(*p); *p = hide_meta(*p);
......
This diff is collapsed.
...@@ -160,7 +160,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now) ...@@ -160,7 +160,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
while ((opt = next(&p, end))) while ((opt = next(&p, end)))
{ {
if (strcasecmp(opt, "blksize") == 0 && if (strcasecmp(opt, "blksize") == 0 &&
(opt = next(&p, end))) (opt = next(&p, end)) &&
!(daemon->options & OPT_TFTP_NOBLOCK))
{ {
transfer->blocksize = atoi(opt); transfer->blocksize = atoi(opt);
if (transfer->blocksize < 1) if (transfer->blocksize < 1)
......
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