udhcp: new config option "Rewrite the lease file at every new acknowledge"
(Mats Erik Andersson <mats@blue2net.com> (Blue2Net AB)) udhcp: consistently treat server_config.start/end IPs as host-order fix IP parsing for 64bit machines fix unsafe hton macro usage in read_opt() do not chdir("/") when daemonizing fix help text
This commit is contained in:
parent
dc7a5eae36
commit
c82b5108e1
@ -3575,7 +3575,8 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
|
|||||||
"Adjust filesystem options on ext[23] filesystems"
|
"Adjust filesystem options on ext[23] filesystems"
|
||||||
|
|
||||||
#define udhcpc_trivial_usage \
|
#define udhcpc_trivial_usage \
|
||||||
"[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n[-p pidfile] [-r IP] [-s script]"
|
"[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
|
||||||
|
" [-p pidfile] [-r IP] [-s script]"
|
||||||
#define udhcpc_full_usage \
|
#define udhcpc_full_usage \
|
||||||
" -V,--vendorclass=CLASSID Set vendor class identifier\n" \
|
" -V,--vendorclass=CLASSID Set vendor class identifier\n" \
|
||||||
" -i,--interface=INTERFACE Interface to use (default: eth0)\n" \
|
" -i,--interface=INTERFACE Interface to use (default: eth0)\n" \
|
||||||
@ -3594,7 +3595,7 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
|
|||||||
" -v,--version Display version" \
|
" -v,--version Display version" \
|
||||||
|
|
||||||
#define udhcpd_trivial_usage \
|
#define udhcpd_trivial_usage \
|
||||||
"[configfile]\n" \
|
"[configfile]" \
|
||||||
|
|
||||||
#define udhcpd_full_usage \
|
#define udhcpd_full_usage \
|
||||||
""
|
""
|
||||||
|
@ -32,6 +32,16 @@ config APP_DUMPLEASES
|
|||||||
|
|
||||||
See http://udhcp.busybox.net for further details.
|
See http://udhcp.busybox.net for further details.
|
||||||
|
|
||||||
|
config FEATURE_UDHCPD_WRITE_LEASES_EARLY
|
||||||
|
bool "Rewrite the lease file at every new acknowledge"
|
||||||
|
default n
|
||||||
|
depends on APP_UDHCPD
|
||||||
|
help
|
||||||
|
If selected, udhcpd will write a new file with leases every
|
||||||
|
time a new lease has been accepted, thus eleminating the need
|
||||||
|
to send SIGUSR1 for the initial writing, or updating. Any timed
|
||||||
|
rewriting remains undisturbed
|
||||||
|
|
||||||
config APP_UDHCPC
|
config APP_UDHCPC
|
||||||
bool "udhcp Client (udhcpc)"
|
bool "udhcp Client (udhcpc)"
|
||||||
default n
|
default n
|
||||||
|
@ -114,8 +114,7 @@ static void client_background(void)
|
|||||||
* If that will be properly disabled for NOMMU, client_background()
|
* If that will be properly disabled for NOMMU, client_background()
|
||||||
* will work on NOMMU too */
|
* will work on NOMMU too */
|
||||||
#else
|
#else
|
||||||
// chdir(/) is problematic. Imagine that e.g. pidfile name is RELATIVE! what will unlink do then, eh?
|
bb_daemonize(0);
|
||||||
bb_daemonize(DAEMON_CHDIR_ROOT);
|
|
||||||
/* rewrite pidfile, as our pid is different now */
|
/* rewrite pidfile, as our pid is different now */
|
||||||
if (client_config.pidfile)
|
if (client_config.pidfile)
|
||||||
write_pidfile(client_config.pidfile);
|
write_pidfile(client_config.pidfile);
|
||||||
|
@ -17,7 +17,7 @@ struct client_config_t {
|
|||||||
/* (can be set directly to the result of getopt32) */
|
/* (can be set directly to the result of getopt32) */
|
||||||
char foreground; /* Do not fork */
|
char foreground; /* Do not fork */
|
||||||
char quit_after_lease; /* Quit after obtaining lease */
|
char quit_after_lease; /* Quit after obtaining lease */
|
||||||
char release_on_quit; /* perform release on quit */
|
char release_on_quit; /* Perform release on quit */
|
||||||
char abort_if_no_lease; /* Abort if no lease */
|
char abort_if_no_lease; /* Abort if no lease */
|
||||||
char background_if_no_lease; /* Fork to background if no lease */
|
char background_if_no_lease; /* Fork to background if no lease */
|
||||||
const char *interface; /* The name of the interface to use */
|
const char *interface; /* The name of the interface to use */
|
||||||
|
@ -37,7 +37,7 @@ int udhcpd_main(int argc, char **argv)
|
|||||||
//Huh, dhcpd don't have --foreground, --syslog options?? TODO
|
//Huh, dhcpd don't have --foreground, --syslog options?? TODO
|
||||||
|
|
||||||
if (!ENABLE_FEATURE_UDHCP_DEBUG) {
|
if (!ENABLE_FEATURE_UDHCP_DEBUG) {
|
||||||
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
|
bb_daemonize_or_rexec(0, argv);
|
||||||
logmode &= ~LOGMODE_STDIO;
|
logmode &= ~LOGMODE_STDIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,15 +60,15 @@ int udhcpd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
|
num_ips = server_config.end_ip - server_config.start_ip + 1;
|
||||||
if (server_config.max_leases > num_ips) {
|
if (server_config.max_leases > num_ips) {
|
||||||
bb_error_msg("max_leases value (%lu) not sane, "
|
bb_error_msg("max_leases=%lu is too big, "
|
||||||
"setting to %lu instead",
|
"setting to %lu",
|
||||||
server_config.max_leases, num_ips);
|
server_config.max_leases, num_ips);
|
||||||
server_config.max_leases = num_ips;
|
server_config.max_leases = num_ips;
|
||||||
}
|
}
|
||||||
|
|
||||||
leases = xzalloc(server_config.max_leases * sizeof(struct dhcpOfferedAddr));
|
leases = xzalloc(server_config.max_leases * sizeof(*leases));
|
||||||
read_leases(server_config.lease_file);
|
read_leases(server_config.lease_file);
|
||||||
|
|
||||||
if (read_interface(server_config.interface, &server_config.ifindex,
|
if (read_interface(server_config.interface, &server_config.ifindex,
|
||||||
@ -207,10 +207,13 @@ int udhcpd_main(int argc, char **argv)
|
|||||||
/* make some contention for this address */
|
/* make some contention for this address */
|
||||||
} else
|
} else
|
||||||
sendNAK(&packet);
|
sendNAK(&packet);
|
||||||
} else if (requested_align < server_config.start
|
} else {
|
||||||
|| requested_align > server_config.end
|
uint32_t r = ntohl(requested_align);
|
||||||
|
if (r < server_config.start_ip
|
||||||
|
|| r > server_config.end_ip
|
||||||
) {
|
) {
|
||||||
sendNAK(&packet);
|
sendNAK(&packet);
|
||||||
|
}
|
||||||
} /* else remain silent */
|
} /* else remain silent */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,16 +27,17 @@ struct static_lease {
|
|||||||
|
|
||||||
struct server_config_t {
|
struct server_config_t {
|
||||||
uint32_t server; /* Our IP, in network order */
|
uint32_t server; /* Our IP, in network order */
|
||||||
uint32_t start; /* Start address of leases, network order */
|
/* start,end are in host order: we need to compare start <= ip <= end */
|
||||||
uint32_t end; /* End of leases, network order */
|
uint32_t start_ip; /* Start address of leases, in host order */
|
||||||
|
uint32_t end_ip; /* End of leases, in host order */
|
||||||
struct option_set *options; /* List of DHCP options loaded from the config file */
|
struct option_set *options; /* List of DHCP options loaded from the config file */
|
||||||
char *interface; /* The name of the interface to use */
|
char *interface; /* The name of the interface to use */
|
||||||
int ifindex; /* Index number of the interface to use */
|
int ifindex; /* Index number of the interface to use */
|
||||||
uint8_t arp[6]; /* Our arp address */
|
uint8_t arp[6]; /* Our arp address */
|
||||||
unsigned long lease; /* lease time in seconds (host order) */
|
|
||||||
unsigned long max_leases; /* maximum number of leases (including reserved address) */
|
|
||||||
char remaining; /* should the lease file be interpreted as lease time remaining, or
|
char remaining; /* should the lease file be interpreted as lease time remaining, or
|
||||||
* as the time the lease expires */
|
* as the time the lease expires */
|
||||||
|
unsigned long lease; /* lease time in seconds (host order) */
|
||||||
|
unsigned long max_leases; /* maximum number of leases (including reserved address) */
|
||||||
unsigned long auto_time; /* how long should udhcpd wait before writing a config file.
|
unsigned long auto_time; /* how long should udhcpd wait before writing a config file.
|
||||||
* if this is zero, it will only write one on SIGUSR1 */
|
* if this is zero, it will only write one on SIGUSR1 */
|
||||||
unsigned long decline_time; /* how long an address is reserved if a client returns a
|
unsigned long decline_time; /* how long an address is reserved if a client returns a
|
||||||
@ -95,13 +96,6 @@ int send_inform(struct dhcpMessage *oldpacket);
|
|||||||
|
|
||||||
/*** files.h ***/
|
/*** files.h ***/
|
||||||
|
|
||||||
struct config_keyword {
|
|
||||||
const char *keyword;
|
|
||||||
int (* const handler)(const char *line, void *var);
|
|
||||||
void *var;
|
|
||||||
const char *def;
|
|
||||||
};
|
|
||||||
|
|
||||||
int read_config(const char *file);
|
int read_config(const char *file);
|
||||||
void write_leases(void);
|
void write_leases(void);
|
||||||
void read_leases(const char *file);
|
void read_leases(const char *file);
|
||||||
|
@ -11,42 +11,30 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* on these functions, make sure your datatype matches */
|
||||||
* Domain names may have 254 chars, and string options can be 254
|
|
||||||
* chars long. However, 80 bytes will be enough for most, and won't
|
|
||||||
* hog up memory. If you have a special application, change it
|
|
||||||
*/
|
|
||||||
#define READ_CONFIG_BUF_SIZE 80
|
|
||||||
|
|
||||||
/* on these functions, make sure you datatype matches */
|
|
||||||
static int read_ip(const char *line, void *arg)
|
static int read_ip(const char *line, void *arg)
|
||||||
{
|
{
|
||||||
len_and_sockaddr *lsa;
|
len_and_sockaddr *lsa;
|
||||||
int retval = 0;
|
|
||||||
|
|
||||||
lsa = host_and_af2sockaddr(line, 0, AF_INET);
|
lsa = host_and_af2sockaddr(line, 0, AF_INET);
|
||||||
if (lsa) {
|
if (lsa) {
|
||||||
*(struct in_addr*)arg = lsa->sin.sin_addr;
|
*(uint32_t*)arg = lsa->sin.sin_addr.s_addr;
|
||||||
free(lsa);
|
free(lsa);
|
||||||
retval = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return retval;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_mac(const char *line, void *arg)
|
static int read_mac(const char *line, void *arg)
|
||||||
{
|
{
|
||||||
uint8_t *mac_bytes = arg;
|
uint8_t *mac_bytes = arg;
|
||||||
struct ether_addr *temp_ether_addr;
|
struct ether_addr *temp_ether_addr;
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
temp_ether_addr = ether_aton(line);
|
temp_ether_addr = ether_aton(line);
|
||||||
|
|
||||||
if (temp_ether_addr == NULL)
|
if (temp_ether_addr == NULL)
|
||||||
retval = 0;
|
return 0;
|
||||||
else
|
|
||||||
memcpy(mac_bytes, temp_ether_addr, 6);
|
memcpy(mac_bytes, temp_ether_addr, 6);
|
||||||
|
return 1;
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -56,14 +44,13 @@ static int read_str(const char *line, void *arg)
|
|||||||
|
|
||||||
free(*dest);
|
free(*dest);
|
||||||
*dest = xstrdup(line);
|
*dest = xstrdup(line);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int read_u32(const char *line, void *arg)
|
static int read_u32(const char *line, void *arg)
|
||||||
{
|
{
|
||||||
*((uint32_t*)arg) = bb_strtou32(line, NULL, 10);
|
*(uint32_t*)arg = bb_strtou32(line, NULL, 10);
|
||||||
return errno == 0;
|
return errno == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,15 +58,16 @@ static int read_u32(const char *line, void *arg)
|
|||||||
static int read_yn(const char *line, void *arg)
|
static int read_yn(const char *line, void *arg)
|
||||||
{
|
{
|
||||||
char *dest = arg;
|
char *dest = arg;
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
if (!strcasecmp("yes", line))
|
if (!strcasecmp("yes", line)) {
|
||||||
*dest = 1;
|
*dest = 1;
|
||||||
else if (!strcasecmp("no", line))
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcasecmp("no", line)) {
|
||||||
*dest = 0;
|
*dest = 0;
|
||||||
else retval = 0;
|
return 1;
|
||||||
|
}
|
||||||
return retval;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -89,8 +77,9 @@ struct option_set *find_option(struct option_set *opt_list, char code)
|
|||||||
while (opt_list && opt_list->data[OPT_CODE] < code)
|
while (opt_list && opt_list->data[OPT_CODE] < code)
|
||||||
opt_list = opt_list->next;
|
opt_list = opt_list->next;
|
||||||
|
|
||||||
if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
|
if (opt_list && opt_list->data[OPT_CODE] == code)
|
||||||
else return NULL;
|
return opt_list;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -111,7 +100,7 @@ static void attach_option(struct option_set **opt_list,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make a new option */
|
/* make a new option */
|
||||||
new = xmalloc(sizeof(struct option_set));
|
new = xmalloc(sizeof(*new));
|
||||||
new->data = xmalloc(length + 2);
|
new->data = xmalloc(length + 2);
|
||||||
new->data[OPT_CODE] = option->code;
|
new->data[OPT_CODE] = option->code;
|
||||||
new->data[OPT_LEN] = length;
|
new->data[OPT_LEN] = length;
|
||||||
@ -199,8 +188,11 @@ static int read_opt(const char *const_line, void *arg)
|
|||||||
break;
|
break;
|
||||||
case OPTION_IP_PAIR:
|
case OPTION_IP_PAIR:
|
||||||
retval = read_ip(val, buffer);
|
retval = read_ip(val, buffer);
|
||||||
if (!(val = strtok(NULL, ", \t/-"))) retval = 0;
|
val = strtok(NULL, ", \t/-");
|
||||||
if (retval) retval = read_ip(val, buffer + 4);
|
if (!val)
|
||||||
|
retval = 0;
|
||||||
|
if (retval)
|
||||||
|
retval = read_ip(val, buffer + 4);
|
||||||
break;
|
break;
|
||||||
case OPTION_STRING:
|
case OPTION_STRING:
|
||||||
#if ENABLE_FEATURE_RFC3397
|
#if ENABLE_FEATURE_RFC3397
|
||||||
@ -220,22 +212,33 @@ static int read_opt(const char *const_line, void *arg)
|
|||||||
buffer[0] = strtoul(val, &endptr, 0);
|
buffer[0] = strtoul(val, &endptr, 0);
|
||||||
retval = (endptr[0] == '\0');
|
retval = (endptr[0] == '\0');
|
||||||
break;
|
break;
|
||||||
case OPTION_U16:
|
/* htonX are macros in older libc's, using temp var
|
||||||
*result_u16 = htons(strtoul(val, &endptr, 0));
|
* in code below for safety */
|
||||||
|
/* TODO: use bb_strtoX? */
|
||||||
|
case OPTION_U16: {
|
||||||
|
unsigned long tmp = strtoul(val, &endptr, 0);
|
||||||
|
*result_u16 = htons(tmp);
|
||||||
|
retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OPTION_S16: {
|
||||||
|
long tmp = strtol(val, &endptr, 0);
|
||||||
|
*result_u16 = htons(tmp);
|
||||||
retval = (endptr[0] == '\0');
|
retval = (endptr[0] == '\0');
|
||||||
break;
|
break;
|
||||||
case OPTION_S16:
|
}
|
||||||
*result_u16 = htons(strtol(val, &endptr, 0));
|
case OPTION_U32: {
|
||||||
|
unsigned long tmp = strtoul(val, &endptr, 0);
|
||||||
|
*result_u32 = htonl(tmp);
|
||||||
retval = (endptr[0] == '\0');
|
retval = (endptr[0] == '\0');
|
||||||
break;
|
break;
|
||||||
case OPTION_U32:
|
}
|
||||||
*result_u32 = htonl(strtoul(val, &endptr, 0));
|
case OPTION_S32: {
|
||||||
retval = (endptr[0] == '\0');
|
long tmp = strtol(val, &endptr, 0);
|
||||||
break;
|
*result_u32 = htonl(tmp);
|
||||||
case OPTION_S32:
|
|
||||||
*result_u32 = htonl(strtol(val, &endptr, 0));
|
|
||||||
retval = (endptr[0] == '\0');
|
retval = (endptr[0] == '\0');
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -253,7 +256,6 @@ static int read_staticlease(const char *const_line, void *arg)
|
|||||||
uint8_t *mac_bytes;
|
uint8_t *mac_bytes;
|
||||||
uint32_t *ip;
|
uint32_t *ip;
|
||||||
|
|
||||||
|
|
||||||
/* Allocate memory for addresses */
|
/* Allocate memory for addresses */
|
||||||
mac_bytes = xmalloc(sizeof(unsigned char) * 8);
|
mac_bytes = xmalloc(sizeof(unsigned char) * 8);
|
||||||
ip = xmalloc(sizeof(uint32_t));
|
ip = xmalloc(sizeof(uint32_t));
|
||||||
@ -275,14 +277,23 @@ static int read_staticlease(const char *const_line, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct config_keyword {
|
||||||
|
const char *keyword;
|
||||||
|
int (*handler)(const char *line, void *var);
|
||||||
|
void *var;
|
||||||
|
const char *def;
|
||||||
|
};
|
||||||
|
|
||||||
static const struct config_keyword keywords[] = {
|
static const struct config_keyword keywords[] = {
|
||||||
/* keyword handler variable address default */
|
/* keyword handler variable address default */
|
||||||
{"start", read_ip, &(server_config.start), "192.168.0.20"},
|
{"start", read_ip, &(server_config.start_ip), "192.168.0.20"},
|
||||||
{"end", read_ip, &(server_config.end), "192.168.0.254"},
|
{"end", read_ip, &(server_config.end_ip), "192.168.0.254"},
|
||||||
{"interface", read_str, &(server_config.interface), "eth0"},
|
{"interface", read_str, &(server_config.interface), "eth0"},
|
||||||
{"option", read_opt, &(server_config.options), ""},
|
{"option", read_opt, &(server_config.options), ""},
|
||||||
{"opt", read_opt, &(server_config.options), ""},
|
{"opt", read_opt, &(server_config.options), ""},
|
||||||
{"max_leases", read_u32, &(server_config.max_leases), "254"},
|
/* Avoid "max_leases value not sane" warning by setting default
|
||||||
|
* to default_end_ip - default_start_ip + 1: */
|
||||||
|
{"max_leases", read_u32, &(server_config.max_leases), "235"},
|
||||||
{"remaining", read_yn, &(server_config.remaining), "yes"},
|
{"remaining", read_yn, &(server_config.remaining), "yes"},
|
||||||
{"auto_time", read_u32, &(server_config.auto_time), "7200"},
|
{"auto_time", read_u32, &(server_config.auto_time), "7200"},
|
||||||
{"decline_time", read_u32, &(server_config.decline_time), "3600"},
|
{"decline_time", read_u32, &(server_config.decline_time), "3600"},
|
||||||
@ -297,17 +308,23 @@ static const struct config_keyword keywords[] = {
|
|||||||
{"boot_file", read_str, &(server_config.boot_file), ""},
|
{"boot_file", read_str, &(server_config.boot_file), ""},
|
||||||
{"static_lease", read_staticlease, &(server_config.static_leases), ""},
|
{"static_lease", read_staticlease, &(server_config.static_leases), ""},
|
||||||
/* ADDME: static lease */
|
/* ADDME: static lease */
|
||||||
{"", NULL, NULL, ""}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Domain names may have 254 chars, and string options can be 254
|
||||||
|
* chars long. However, 80 bytes will be enough for most, and won't
|
||||||
|
* hog up memory. If you have a special application, change it
|
||||||
|
*/
|
||||||
|
#define READ_CONFIG_BUF_SIZE 80
|
||||||
|
|
||||||
int read_config(const char *file)
|
int read_config(const char *file)
|
||||||
{
|
{
|
||||||
FILE *in;
|
FILE *in;
|
||||||
char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
|
char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
|
||||||
int i, lm = 0;
|
int i, lm = 0;
|
||||||
|
|
||||||
for (i = 0; keywords[i].keyword[0]; i++)
|
for (i = 0; i < ARRAY_SIZE(keywords); i++)
|
||||||
if (keywords[i].def[0])
|
if (keywords[i].def[0])
|
||||||
keywords[i].handler(keywords[i].def, keywords[i].var);
|
keywords[i].handler(keywords[i].def, keywords[i].var);
|
||||||
|
|
||||||
@ -337,7 +354,7 @@ int read_config(const char *file)
|
|||||||
while (i >= 0 && isspace(line[i]))
|
while (i >= 0 && isspace(line[i]))
|
||||||
line[i--] = '\0';
|
line[i--] = '\0';
|
||||||
|
|
||||||
for (i = 0; keywords[i].keyword[0]; i++)
|
for (i = 0; i < ARRAY_SIZE(keywords); i++)
|
||||||
if (!strcasecmp(token, keywords[i].keyword))
|
if (!strcasecmp(token, keywords[i].keyword))
|
||||||
if (!keywords[i].handler(line, keywords[i].var)) {
|
if (!keywords[i].handler(line, keywords[i].var)) {
|
||||||
bb_error_msg("cannot parse line %d of %s", lm, file);
|
bb_error_msg("cannot parse line %d of %s", lm, file);
|
||||||
@ -348,6 +365,10 @@ int read_config(const char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
|
server_config.start_ip = ntohl(server_config.start_ip);
|
||||||
|
server_config.end_ip = ntohl(server_config.end_ip);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,9 +429,11 @@ void read_leases(const char *file)
|
|||||||
&& full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
|
&& full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
|
||||||
) {
|
) {
|
||||||
/* ADDME: is it a static lease */
|
/* ADDME: is it a static lease */
|
||||||
if (lease.yiaddr >= server_config.start && lease.yiaddr <= server_config.end) {
|
uint32_t y = ntohl(lease.yiaddr);
|
||||||
|
if (y >= server_config.start_ip && y <= server_config.end_ip) {
|
||||||
lease.expires = ntohl(lease.expires);
|
lease.expires = ntohl(lease.expires);
|
||||||
if (!server_config.remaining) lease.expires -= time(0);
|
if (!server_config.remaining)
|
||||||
|
lease.expires -= time(0);
|
||||||
if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
|
if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
|
||||||
bb_error_msg("too many leases while loading %s", file);
|
bb_error_msg("too many leases while loading %s", file);
|
||||||
break;
|
break;
|
||||||
|
@ -119,8 +119,8 @@ uint32_t find_address(int check_expired)
|
|||||||
uint32_t addr, ret;
|
uint32_t addr, ret;
|
||||||
struct dhcpOfferedAddr *lease = NULL;
|
struct dhcpOfferedAddr *lease = NULL;
|
||||||
|
|
||||||
addr = ntohl(server_config.start); /* addr is in host order here */
|
addr = server_config.start_ip; /* addr is in host order here */
|
||||||
for (;addr <= ntohl(server_config.end); addr++) {
|
for (;addr <= server_config.end_ip; addr++) {
|
||||||
|
|
||||||
/* ie, 192.168.55.0 */
|
/* ie, 192.168.55.0 */
|
||||||
if (!(addr & 0xFF)) continue;
|
if (!(addr & 0xFF)) continue;
|
||||||
|
@ -122,14 +122,13 @@ int sendOffer(struct dhcpMessage *oldpacket)
|
|||||||
if (!lease_expired(lease))
|
if (!lease_expired(lease))
|
||||||
lease_time_align = lease->expires - time(0);
|
lease_time_align = lease->expires - time(0);
|
||||||
packet.yiaddr = lease->yiaddr;
|
packet.yiaddr = lease->yiaddr;
|
||||||
|
|
||||||
/* Or the client has a requested ip */
|
/* Or the client has a requested ip */
|
||||||
} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP))
|
} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP))
|
||||||
/* Don't look here (ugly hackish thing to do) */
|
/* Don't look here (ugly hackish thing to do) */
|
||||||
&& memcpy(&req_align, req, 4)
|
&& memcpy(&req_align, req, 4)
|
||||||
/* and the ip is in the lease range */
|
/* and the ip is in the lease range */
|
||||||
&& ntohl(req_align) >= ntohl(server_config.start)
|
&& ntohl(req_align) >= server_config.start_ip
|
||||||
&& ntohl(req_align) <= ntohl(server_config.end)
|
&& ntohl(req_align) <= server_config.end_ip
|
||||||
&& !static_lease_ip /* Check that its not a static lease */
|
&& !static_lease_ip /* Check that its not a static lease */
|
||||||
/* and is not already taken/offered */
|
/* and is not already taken/offered */
|
||||||
&& (!(lease = find_lease_by_yiaddr(req_align))
|
&& (!(lease = find_lease_by_yiaddr(req_align))
|
||||||
@ -142,7 +141,8 @@ int sendOffer(struct dhcpMessage *oldpacket)
|
|||||||
/* Is it a static lease? (No, because find_address skips static lease) */
|
/* Is it a static lease? (No, because find_address skips static lease) */
|
||||||
packet.yiaddr = find_address(0);
|
packet.yiaddr = find_address(0);
|
||||||
/* try for an expired lease */
|
/* try for an expired lease */
|
||||||
if (!packet.yiaddr) packet.yiaddr = find_address(1);
|
if (!packet.yiaddr)
|
||||||
|
packet.yiaddr = find_address(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packet.yiaddr) {
|
if (!packet.yiaddr) {
|
||||||
@ -209,7 +209,8 @@ int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
|
|||||||
init_packet(&packet, oldpacket, DHCPACK);
|
init_packet(&packet, oldpacket, DHCPACK);
|
||||||
packet.yiaddr = yiaddr;
|
packet.yiaddr = yiaddr;
|
||||||
|
|
||||||
if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) {
|
lease_time = get_option(oldpacket, DHCP_LEASE_TIME);
|
||||||
|
if (lease_time) {
|
||||||
memcpy(&lease_time_align, lease_time, 4);
|
memcpy(&lease_time_align, lease_time, 4);
|
||||||
lease_time_align = ntohl(lease_time_align);
|
lease_time_align = ntohl(lease_time_align);
|
||||||
if (lease_time_align > server_config.lease)
|
if (lease_time_align > server_config.lease)
|
||||||
@ -236,6 +237,10 @@ int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
add_lease(packet.chaddr, packet.yiaddr, lease_time_align);
|
add_lease(packet.chaddr, packet.yiaddr, lease_time_align);
|
||||||
|
if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
|
||||||
|
/* rewrite the file with leases at every new acceptance */
|
||||||
|
write_leases();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t
|
|||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct sockaddr_in *our_ip;
|
struct sockaddr_in *our_ip;
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(struct ifreq));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
bb_perror_msg("socket failed");
|
bb_perror_msg("socket failed");
|
||||||
@ -54,7 +54,8 @@ int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t
|
|||||||
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
|
strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
|
||||||
if (addr) {
|
if (addr) {
|
||||||
if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) {
|
if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) {
|
||||||
bb_perror_msg("SIOCGIFADDR failed, is the interface up and configured?");
|
bb_perror_msg("SIOCGIFADDR failed (is interface %s "
|
||||||
|
"up and configured?)", interface);
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -117,7 +118,7 @@ int listen_socket(uint32_t ip, int port, const char *inf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
|
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user