udhcpd: disable opton to have absolute lease times in lease file
(that does not work with dumpleases) dumpleases: fix -a option. networking/udhcp/*: code shrink, more compact static leases struture, better comments, etc function old new delta find_free_or_expired_address - 147 +147 nobody_responds_to_arp - 84 +84 read_opt 781 830 +49 dumpleases_main 435 447 +12 send_ACK 229 232 +3 read_staticlease 90 93 +3 addStaticLease 60 61 +1 getIpByMac 46 43 -3 reservedIp 31 20 -11 keywords 304 288 -16 send_offer 428 403 -25 write_leases 225 193 -32 read_leases 184 143 -41 read_yn 64 - -64 find_address 191 - -191 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 5/6 up/down: 299/-383) Total: -84 bytes
This commit is contained in:
parent
b2ec03813c
commit
0416e3dde1
@ -26,8 +26,7 @@ int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||||||
int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
int server_socket = -1, retval, max_sock;
|
||||||
int server_socket = -1, bytes, retval, max_sock;
|
|
||||||
struct dhcpMessage packet;
|
struct dhcpMessage packet;
|
||||||
uint8_t *state, *server_id, *requested;
|
uint8_t *state, *server_id, *requested;
|
||||||
uint32_t server_id_aligned = server_id_aligned; /* for compiler */
|
uint32_t server_id_aligned = server_id_aligned; /* for compiler */
|
||||||
@ -107,6 +106,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
timeout_end = monotonic_sec() + server_config.auto_time;
|
timeout_end = monotonic_sec() + server_config.auto_time;
|
||||||
while (1) { /* loop until universe collapses */
|
while (1) { /* loop until universe collapses */
|
||||||
|
int bytes;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
if (server_socket < 0) {
|
if (server_socket < 0) {
|
||||||
server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT,
|
server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT,
|
||||||
@ -143,12 +144,15 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
bb_info_msg("Received a SIGTERM");
|
bb_info_msg("Received a SIGTERM");
|
||||||
goto ret0;
|
goto ret0;
|
||||||
case 0: break; /* no signal */
|
case 0: /* no signal: read a packet */
|
||||||
default: continue; /* signal or error (probably EINTR) */
|
break;
|
||||||
|
default: /* signal or error (probably EINTR): back to select */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = udhcp_recv_kernel_packet(&packet, server_socket); /* this waits for a packet - idle */
|
bytes = udhcp_recv_kernel_packet(&packet, server_socket);
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
|
/* bytes can also be -2 ("bad packet data") */
|
||||||
if (bytes == -1 && errno != EINTR) {
|
if (bytes == -1 && errno != EINTR) {
|
||||||
DEBUG("error on read, %s, reopening socket", strerror(errno));
|
DEBUG("error on read, %s, reopening socket", strerror(errno));
|
||||||
close(server_socket);
|
close(server_socket);
|
||||||
@ -165,7 +169,6 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
/* Look for a static lease */
|
/* Look for a static lease */
|
||||||
static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);
|
static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);
|
||||||
|
|
||||||
if (static_lease_ip) {
|
if (static_lease_ip) {
|
||||||
bb_info_msg("Found static lease: %x", static_lease_ip);
|
bb_info_msg("Found static lease: %x", static_lease_ip);
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ struct option_set {
|
|||||||
|
|
||||||
struct static_lease {
|
struct static_lease {
|
||||||
struct static_lease *next;
|
struct static_lease *next;
|
||||||
uint8_t *mac;
|
uint32_t ip;
|
||||||
uint32_t *ip;
|
uint8_t mac[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server_config_t {
|
struct server_config_t {
|
||||||
@ -42,8 +42,11 @@ struct server_config_t {
|
|||||||
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 */
|
||||||
char remaining; /* should the lease file be interpreted as lease time remaining, or
|
// disabled: dumpleases has no way of knowing this value,
|
||||||
* as the time the lease expires */
|
// and will break if it's off. Now it's on always.
|
||||||
|
// char remaining; /* Should the lease time in lease file
|
||||||
|
// * be written as lease time remaining, or
|
||||||
|
// * as the absolute time the lease expires */
|
||||||
uint32_t lease; /* lease time in seconds (host order) */
|
uint32_t lease; /* lease time in seconds (host order) */
|
||||||
uint32_t max_leases; /* maximum number of leases (including reserved address) */
|
uint32_t max_leases; /* maximum number of leases (including reserved address) */
|
||||||
uint32_t auto_time; /* how long should udhcpd wait before writing a config file.
|
uint32_t auto_time; /* how long should udhcpd wait before writing a config file.
|
||||||
@ -52,11 +55,11 @@ struct server_config_t {
|
|||||||
* decline message */
|
* decline message */
|
||||||
uint32_t conflict_time; /* how long an arp conflict offender is leased for */
|
uint32_t conflict_time; /* how long an arp conflict offender is leased for */
|
||||||
uint32_t offer_time; /* how long an offered address is reserved */
|
uint32_t offer_time; /* how long an offered address is reserved */
|
||||||
uint32_t min_lease; /* minimum lease a client can request */
|
uint32_t min_lease; /* minimum lease time a client can request */
|
||||||
|
uint32_t siaddr; /* next server bootp option */
|
||||||
char *lease_file;
|
char *lease_file;
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
char *notify_file; /* What to run whenever leases are written */
|
char *notify_file; /* What to run whenever leases are written */
|
||||||
uint32_t siaddr; /* next server bootp option */
|
|
||||||
char *sname; /* bootp server name */
|
char *sname; /* bootp server name */
|
||||||
char *boot_file; /* bootp boot file option */
|
char *boot_file; /* bootp boot file option */
|
||||||
struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */
|
struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */
|
||||||
@ -76,28 +79,37 @@ extern struct dhcpOfferedAddr *leases;
|
|||||||
|
|
||||||
/*** leases.h ***/
|
/*** leases.h ***/
|
||||||
|
|
||||||
|
typedef uint32_t leasetime_t;
|
||||||
|
typedef int32_t signed_leasetime_t;
|
||||||
|
|
||||||
struct dhcpOfferedAddr {
|
struct dhcpOfferedAddr {
|
||||||
uint8_t chaddr[16];
|
uint8_t chaddr[16];
|
||||||
uint32_t yiaddr; /* network order */
|
/* In network order */
|
||||||
uint32_t expires; /* host order */
|
uint32_t yiaddr;
|
||||||
|
/* Unix time when lease expires, regardless of value of
|
||||||
|
* server_config.remaining. Kept in memory in host order.
|
||||||
|
* When written to file, converted to network order
|
||||||
|
* and optionally adjusted (current time subtracted)
|
||||||
|
* if server_config.remaining = 1 */
|
||||||
|
leasetime_t expires;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) FAST_FUNC;
|
struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime) FAST_FUNC;
|
||||||
int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC;
|
int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC;
|
||||||
struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC;
|
struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC;
|
||||||
struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC;
|
struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC;
|
||||||
uint32_t find_address(int check_expired) FAST_FUNC;
|
uint32_t find_free_or_expired_address(void) FAST_FUNC;
|
||||||
|
|
||||||
|
|
||||||
/*** static_leases.h ***/
|
/*** static_leases.h ***/
|
||||||
|
|
||||||
/* Config file will pass static lease info to this function which will add it
|
/* Config file will pass static lease info to this function which will add it
|
||||||
* to a data structure that can be searched later */
|
* to a data structure that can be searched later */
|
||||||
int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) FAST_FUNC;
|
void addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t ip) FAST_FUNC;
|
||||||
/* Check to see if a mac has an associated static lease */
|
/* Check to see if a mac has an associated static lease */
|
||||||
uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) FAST_FUNC;
|
uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) FAST_FUNC;
|
||||||
/* Check to see if an ip is reserved as a static ip */
|
/* Check to see if an ip is reserved as a static ip */
|
||||||
uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip) FAST_FUNC;
|
int reservedIp(struct static_lease *lease_struct, uint32_t ip) FAST_FUNC;
|
||||||
/* Print out static leases just to check what's going on (debug code) */
|
/* Print out static leases just to check what's going on (debug code) */
|
||||||
void printStaticLeases(struct static_lease **lease_struct) FAST_FUNC;
|
void printStaticLeases(struct static_lease **lease_struct) FAST_FUNC;
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
int fd;
|
int fd;
|
||||||
int i;
|
int i;
|
||||||
unsigned opt;
|
unsigned opt;
|
||||||
time_t expires;
|
leasetime_t expires;
|
||||||
|
leasetime_t curr;
|
||||||
const char *file = LEASES_FILE;
|
const char *file = LEASES_FILE;
|
||||||
struct dhcpOfferedAddr lease;
|
struct dhcpOfferedAddr lease;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
@ -38,27 +39,33 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
printf("Mac Address IP-Address Expires %s\n", (opt & OPT_a) ? "at" : "in");
|
printf("Mac Address IP-Address Expires %s\n", (opt & OPT_a) ? "at" : "in");
|
||||||
/* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */
|
/* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */
|
||||||
|
|
||||||
|
curr = time(NULL);
|
||||||
while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
|
while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
|
||||||
printf(":%02x"+1, lease.chaddr[0]);
|
const char *fmt = ":%02x" + 1;
|
||||||
for (i = 1; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
printf(":%02x", lease.chaddr[i]);
|
printf(fmt, lease.chaddr[i]);
|
||||||
|
fmt = ":%02x";
|
||||||
}
|
}
|
||||||
addr.s_addr = lease.yiaddr;
|
addr.s_addr = lease.yiaddr;
|
||||||
printf(" %-15s ", inet_ntoa(addr));
|
printf(" %-15s ", inet_ntoa(addr));
|
||||||
|
if (lease.expires == 0) {
|
||||||
|
puts("expired");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
expires = ntohl(lease.expires);
|
expires = ntohl(lease.expires);
|
||||||
if (!(opt & OPT_a)) { /* no -a */
|
if (!(opt & OPT_a)) { /* no -a */
|
||||||
if (!expires)
|
unsigned d, h, m;
|
||||||
puts("expired");
|
d = expires / (24*60*60); expires %= (24*60*60);
|
||||||
else {
|
h = expires / (60*60); expires %= (60*60);
|
||||||
unsigned d, h, m;
|
m = expires / 60; expires %= 60;
|
||||||
d = expires / (24*60*60); expires %= (24*60*60);
|
if (d)
|
||||||
h = expires / (60*60); expires %= (60*60);
|
printf("%u days ", d);
|
||||||
m = expires / 60; expires %= 60;
|
printf("%02u:%02u:%02u\n", h, m, (unsigned)expires);
|
||||||
if (d) printf("%u days ", d);
|
} else { /* -a */
|
||||||
printf("%02u:%02u:%02u\n", h, m, (unsigned)expires);
|
time_t t = expires + curr;
|
||||||
}
|
fputs(ctime(&t), stdout);
|
||||||
} else /* -a */
|
}
|
||||||
fputs(ctime(&expires), stdout);
|
|
||||||
}
|
}
|
||||||
/* close(fd); */
|
/* close(fd); */
|
||||||
|
|
||||||
|
@ -28,12 +28,7 @@ static int read_ip(const char *line, void *arg)
|
|||||||
|
|
||||||
static int read_mac(const char *line, void *arg)
|
static int read_mac(const char *line, void *arg)
|
||||||
{
|
{
|
||||||
struct ether_addr *temp_ether_addr;
|
return NULL == ether_aton_r(line, (struct ether_addr *)arg);
|
||||||
|
|
||||||
temp_ether_addr = ether_aton_r(line, (struct ether_addr *)arg);
|
|
||||||
if (temp_ether_addr == NULL)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -250,23 +245,19 @@ static int read_staticlease(const char *const_line, void *arg)
|
|||||||
char *line;
|
char *line;
|
||||||
char *mac_string;
|
char *mac_string;
|
||||||
char *ip_string;
|
char *ip_string;
|
||||||
uint8_t *mac_bytes;
|
struct ether_addr mac_bytes;
|
||||||
uint32_t *ip;
|
uint32_t ip;
|
||||||
|
|
||||||
/* Allocate memory for addresses */
|
|
||||||
mac_bytes = xmalloc(sizeof(unsigned char) * 8);
|
|
||||||
ip = xmalloc(sizeof(uint32_t));
|
|
||||||
|
|
||||||
/* Read mac */
|
/* Read mac */
|
||||||
line = (char *) const_line;
|
line = (char *) const_line;
|
||||||
mac_string = strtok(line, " \t");
|
mac_string = strtok_r(line, " \t", &line);
|
||||||
read_mac(mac_string, mac_bytes);
|
read_mac(mac_string, &mac_bytes);
|
||||||
|
|
||||||
/* Read ip */
|
/* Read ip */
|
||||||
ip_string = strtok(NULL, " \t");
|
ip_string = strtok_r(NULL, " \t", &line);
|
||||||
read_ip(ip_string, ip);
|
read_ip(ip_string, &ip);
|
||||||
|
|
||||||
addStaticLease(arg, mac_bytes, ip);
|
addStaticLease(arg, (uint8_t*) &mac_bytes, ip);
|
||||||
|
|
||||||
if (ENABLE_UDHCP_DEBUG) printStaticLeases(arg);
|
if (ENABLE_UDHCP_DEBUG) printStaticLeases(arg);
|
||||||
|
|
||||||
@ -289,7 +280,7 @@ static const struct config_keyword keywords[] = {
|
|||||||
/* Avoid "max_leases value not sane" warning by setting default
|
/* Avoid "max_leases value not sane" warning by setting default
|
||||||
* to default_end_ip - default_start_ip + 1: */
|
* to default_end_ip - default_start_ip + 1: */
|
||||||
{"max_leases", read_u32, &(server_config.max_leases), "235"},
|
{"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"},
|
||||||
{"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
|
{"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
|
||||||
@ -305,7 +296,6 @@ static const struct config_keyword keywords[] = {
|
|||||||
{"sname", read_str, &(server_config.sname), ""},
|
{"sname", read_str, &(server_config.sname), ""},
|
||||||
{"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 */
|
|
||||||
};
|
};
|
||||||
enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };
|
enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };
|
||||||
|
|
||||||
@ -342,36 +332,42 @@ void FAST_FUNC read_config(const char *file)
|
|||||||
|
|
||||||
void FAST_FUNC write_leases(void)
|
void FAST_FUNC write_leases(void)
|
||||||
{
|
{
|
||||||
int fp;
|
int fd;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
time_t curr = time(0);
|
leasetime_t curr;
|
||||||
unsigned long tmp_time;
|
|
||||||
|
|
||||||
fp = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC);
|
fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC);
|
||||||
if (fp < 0) {
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
curr = time(NULL);
|
||||||
|
//TODO: write out current time? Readers need to adjust .expires field
|
||||||
|
// to account for time between file was written and when it was read back.
|
||||||
|
|
||||||
for (i = 0; i < server_config.max_leases; i++) {
|
for (i = 0; i < server_config.max_leases; i++) {
|
||||||
if (leases[i].yiaddr != 0) {
|
leasetime_t tmp_time;
|
||||||
|
|
||||||
/* screw with the time in the struct, for easier writing */
|
if (leases[i].yiaddr == 0)
|
||||||
tmp_time = leases[i].expires;
|
continue;
|
||||||
|
|
||||||
if (server_config.remaining) {
|
/* screw with the time in the struct, for easier writing */
|
||||||
if (lease_expired(&(leases[i])))
|
tmp_time = leases[i].expires;
|
||||||
leases[i].expires = 0;
|
|
||||||
else leases[i].expires -= curr;
|
|
||||||
} /* else stick with the time we got */
|
|
||||||
leases[i].expires = htonl(leases[i].expires);
|
|
||||||
// FIXME: error check??
|
|
||||||
full_write(fp, &leases[i], sizeof(leases[i]));
|
|
||||||
|
|
||||||
/* then restore it when done */
|
//if (server_config.remaining) {
|
||||||
leases[i].expires = tmp_time;
|
leases[i].expires -= curr;
|
||||||
}
|
if ((signed_leasetime_t) leases[i].expires < 0)
|
||||||
|
leases[i].expires = 0;
|
||||||
|
//} /* else stick with the time we got */
|
||||||
|
leases[i].expires = htonl(leases[i].expires);
|
||||||
|
|
||||||
|
/* No error check. If the file gets truncated,
|
||||||
|
* we lose some leases on restart. Oh well. */
|
||||||
|
full_write(fd, &leases[i], sizeof(leases[i]));
|
||||||
|
|
||||||
|
/* then restore it when done */
|
||||||
|
leases[i].expires = tmp_time;
|
||||||
}
|
}
|
||||||
close(fp);
|
close(fd);
|
||||||
|
|
||||||
if (server_config.notify_file) {
|
if (server_config.notify_file) {
|
||||||
// TODO: vfork-based child creation
|
// TODO: vfork-based child creation
|
||||||
@ -384,26 +380,29 @@ void FAST_FUNC write_leases(void)
|
|||||||
|
|
||||||
void FAST_FUNC read_leases(const char *file)
|
void FAST_FUNC read_leases(const char *file)
|
||||||
{
|
{
|
||||||
int fp;
|
int fd;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
// leasetime_t curr;
|
||||||
struct dhcpOfferedAddr lease;
|
struct dhcpOfferedAddr lease;
|
||||||
|
|
||||||
fp = open_or_warn(file, O_RDONLY);
|
fd = open_or_warn(file, O_RDONLY);
|
||||||
if (fp < 0) {
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
// curr = time(NULL);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < server_config.max_leases
|
while (i < server_config.max_leases
|
||||||
&& full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
|
&& full_read(fd, &lease, sizeof(lease)) == sizeof(lease)
|
||||||
) {
|
) {
|
||||||
/* ADDME: is it a static lease */
|
/* ADDME: what if it matches some static lease? */
|
||||||
uint32_t y = ntohl(lease.yiaddr);
|
uint32_t y = ntohl(lease.yiaddr);
|
||||||
if (y >= server_config.start_ip && y <= server_config.end_ip) {
|
if (y >= server_config.start_ip && y <= server_config.end_ip) {
|
||||||
lease.expires = ntohl(lease.expires);
|
leasetime_t expires = ntohl(lease.expires);
|
||||||
if (!server_config.remaining)
|
// if (!server_config.remaining)
|
||||||
lease.expires -= time(NULL);
|
// expires -= curr;
|
||||||
if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
|
/* NB: add_lease takes "relative time", IOW,
|
||||||
|
* lease duration, not lease deadline. */
|
||||||
|
if (!(add_lease(lease.chaddr, lease.yiaddr, expires))) {
|
||||||
bb_error_msg("too many leases while loading %s", file);
|
bb_error_msg("too many leases while loading %s", file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -411,5 +410,5 @@ void FAST_FUNC read_leases(const char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG("Read %d leases", i);
|
DEBUG("Read %d leases", i);
|
||||||
close(fp);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -13,21 +13,23 @@
|
|||||||
/* Find the oldest expired lease, NULL if there are no expired leases */
|
/* Find the oldest expired lease, NULL if there are no expired leases */
|
||||||
static struct dhcpOfferedAddr *oldest_expired_lease(void)
|
static struct dhcpOfferedAddr *oldest_expired_lease(void)
|
||||||
{
|
{
|
||||||
struct dhcpOfferedAddr *oldest = NULL;
|
struct dhcpOfferedAddr *oldest_lease = NULL;
|
||||||
// TODO: use monotonic_sec()
|
leasetime_t oldest_time = time(NULL);
|
||||||
unsigned long oldest_lease = time(0);
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < server_config.max_leases; i++)
|
/* Unexpired leases have leases[i].expires >= current time
|
||||||
if (oldest_lease > leases[i].expires) {
|
* and therefore can't ever match */
|
||||||
oldest_lease = leases[i].expires;
|
for (i = 0; i < server_config.max_leases; i++) {
|
||||||
oldest = &(leases[i]);
|
if (leases[i].expires < oldest_time) {
|
||||||
|
oldest_time = leases[i].expires;
|
||||||
|
oldest_lease = &(leases[i]);
|
||||||
}
|
}
|
||||||
return oldest;
|
}
|
||||||
|
return oldest_lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* clear every lease out that chaddr OR yiaddr matches and is nonzero */
|
/* Clear every lease out that chaddr OR yiaddr matches and is nonzero */
|
||||||
static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
|
static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
|
||||||
{
|
{
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
@ -35,17 +37,18 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
|
|||||||
for (j = 0; j < 16 && !chaddr[j]; j++)
|
for (j = 0; j < 16 && !chaddr[j]; j++)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = 0; i < server_config.max_leases; i++)
|
for (i = 0; i < server_config.max_leases; i++) {
|
||||||
if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
|
if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
|
||||||
|| (yiaddr && leases[i].yiaddr == yiaddr)
|
|| (yiaddr && leases[i].yiaddr == yiaddr)
|
||||||
) {
|
) {
|
||||||
memset(&(leases[i]), 0, sizeof(leases[i]));
|
memset(&(leases[i]), 0, sizeof(leases[i]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* add a lease into the table, clearing out any old ones */
|
/* Add a lease into the table, clearing out any old ones */
|
||||||
struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)
|
struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime)
|
||||||
{
|
{
|
||||||
struct dhcpOfferedAddr *oldest;
|
struct dhcpOfferedAddr *oldest;
|
||||||
|
|
||||||
@ -57,17 +60,17 @@ struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiad
|
|||||||
if (oldest) {
|
if (oldest) {
|
||||||
memcpy(oldest->chaddr, chaddr, 16);
|
memcpy(oldest->chaddr, chaddr, 16);
|
||||||
oldest->yiaddr = yiaddr;
|
oldest->yiaddr = yiaddr;
|
||||||
oldest->expires = time(0) + lease;
|
oldest->expires = time(NULL) + leasetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldest;
|
return oldest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* true if a lease has expired */
|
/* True if a lease has expired */
|
||||||
int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease)
|
int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease)
|
||||||
{
|
{
|
||||||
return (lease->expires < (unsigned long) time(0));
|
return (lease->expires < (leasetime_t) time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -119,33 +122,43 @@ static int nobody_responds_to_arp(uint32_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* find an assignable address, if check_expired is true, we check all the expired leases as well.
|
/* Find a new usable (we think) address. */
|
||||||
* Maybe this should try expired leases by age... */
|
uint32_t FAST_FUNC find_free_or_expired_address(void)
|
||||||
uint32_t FAST_FUNC find_address(int check_expired)
|
|
||||||
{
|
{
|
||||||
uint32_t addr, ret;
|
uint32_t addr;
|
||||||
struct dhcpOfferedAddr *lease = NULL;
|
struct dhcpOfferedAddr *oldest_lease = NULL;
|
||||||
|
|
||||||
addr = server_config.start_ip; /* addr is in host order here */
|
addr = server_config.start_ip; /* addr is in host order here */
|
||||||
for (; addr <= server_config.end_ip; addr++) {
|
for (; addr <= server_config.end_ip; addr++) {
|
||||||
|
uint32_t net_addr;
|
||||||
|
struct dhcpOfferedAddr *lease;
|
||||||
|
|
||||||
/* ie, 192.168.55.0 */
|
/* ie, 192.168.55.0 */
|
||||||
if (!(addr & 0xFF))
|
if ((addr & 0xff) == 0)
|
||||||
continue;
|
continue;
|
||||||
/* ie, 192.168.55.255 */
|
/* ie, 192.168.55.255 */
|
||||||
if ((addr & 0xFF) == 0xFF)
|
if ((addr & 0xff) == 0xff)
|
||||||
continue;
|
continue;
|
||||||
/* Only do if it isn't assigned as a static lease */
|
net_addr = htonl(addr);
|
||||||
ret = htonl(addr);
|
/* addr has a static lease? */
|
||||||
if (!reservedIp(server_config.static_leases, ret)) {
|
if (reservedIp(server_config.static_leases, net_addr))
|
||||||
/* lease is not taken */
|
continue;
|
||||||
lease = find_lease_by_yiaddr(ret);
|
|
||||||
/* no lease or it expired and we are checking for expired leases */
|
lease = find_lease_by_yiaddr(net_addr);
|
||||||
if ((!lease || (check_expired && lease_expired(lease)))
|
if (!lease) {
|
||||||
&& nobody_responds_to_arp(ret) /* it isn't used on the network */
|
if (nobody_responds_to_arp(net_addr))
|
||||||
) {
|
return net_addr;
|
||||||
return ret;
|
} else {
|
||||||
}
|
if (!oldest_lease || lease->expires < oldest_lease->expires)
|
||||||
|
oldest_lease = lease;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldest_lease && lease_expired(oldest_lease)
|
||||||
|
&& nobody_responds_to_arp(oldest_lease->yiaddr)
|
||||||
|
) {
|
||||||
|
return oldest_lease->yiaddr;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -102,48 +102,44 @@ static void add_bootp_options(struct dhcpMessage *packet)
|
|||||||
int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
|
int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
|
||||||
{
|
{
|
||||||
struct dhcpMessage packet;
|
struct dhcpMessage packet;
|
||||||
struct dhcpOfferedAddr *lease = NULL;
|
|
||||||
uint32_t req_align;
|
uint32_t req_align;
|
||||||
uint32_t lease_time_aligned = server_config.lease;
|
uint32_t lease_time_aligned = server_config.lease;
|
||||||
|
uint32_t static_lease_ip;
|
||||||
uint8_t *req, *lease_time;
|
uint8_t *req, *lease_time;
|
||||||
struct option_set *curr;
|
struct option_set *curr;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
uint32_t static_lease_ip;
|
|
||||||
|
|
||||||
init_packet(&packet, oldpacket, DHCPOFFER);
|
init_packet(&packet, oldpacket, DHCPOFFER);
|
||||||
|
|
||||||
static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr);
|
static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr);
|
||||||
|
|
||||||
/* ADDME: if static, short circuit */
|
/* ADDME: if static, short circuit */
|
||||||
if (!static_lease_ip) {
|
if (!static_lease_ip) {
|
||||||
/* the client is in our lease/offered table */
|
struct dhcpOfferedAddr *lease;
|
||||||
|
|
||||||
lease = find_lease_by_chaddr(oldpacket->chaddr);
|
lease = find_lease_by_chaddr(oldpacket->chaddr);
|
||||||
|
/* the client is in our lease/offered table */
|
||||||
if (lease) {
|
if (lease) {
|
||||||
if (!lease_expired(lease))
|
signed_leasetime_t tmp = lease->expires - time(NULL);
|
||||||
lease_time_aligned = lease->expires - time(0);
|
if (tmp >= 0)
|
||||||
|
lease_time_aligned = tmp;
|
||||||
packet.yiaddr = lease->yiaddr;
|
packet.yiaddr = lease->yiaddr;
|
||||||
/* Or the client has a requested ip */
|
/* Or the client has requested an ip */
|
||||||
} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP))
|
} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
|
||||||
/* Don't look here (ugly hackish thing to do) */
|
/* Don't look here (ugly hackish thing to do) */
|
||||||
&& memcpy(&req_align, req, 4)
|
&& (move_from_unaligned32(req_align, req), 1)
|
||||||
/* and the ip is in the lease range */
|
/* and the ip is in the lease range */
|
||||||
&& ntohl(req_align) >= server_config.start_ip
|
&& ntohl(req_align) >= server_config.start_ip
|
||||||
&& ntohl(req_align) <= server_config.end_ip
|
&& ntohl(req_align) <= server_config.end_ip
|
||||||
&& !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))
|
||||||
/* or its taken, but expired */ /* ADDME: or maybe in here */
|
/* or its taken, but expired */
|
||||||
|| lease_expired(lease))
|
|| lease_expired(lease))
|
||||||
) {
|
) {
|
||||||
packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */
|
packet.yiaddr = req_align;
|
||||||
/* otherwise, find a free IP */
|
/* otherwise, find a free IP */
|
||||||
} else {
|
} else {
|
||||||
/* Is it a static lease? (No, because find_address skips static lease) */
|
packet.yiaddr = find_free_or_expired_address();
|
||||||
packet.yiaddr = find_address(0);
|
|
||||||
/* try for an expired lease */
|
|
||||||
if (!packet.yiaddr)
|
|
||||||
packet.yiaddr = find_address(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packet.yiaddr) {
|
if (!packet.yiaddr) {
|
||||||
@ -164,8 +160,7 @@ int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
|
|||||||
|
|
||||||
/* Make sure we aren't just using the lease time from the previous offer */
|
/* Make sure we aren't just using the lease time from the previous offer */
|
||||||
if (lease_time_aligned < server_config.min_lease)
|
if (lease_time_aligned < server_config.min_lease)
|
||||||
lease_time_aligned = server_config.lease;
|
lease_time_aligned = server_config.min_lease;
|
||||||
/* ADDME: end of short circuit */
|
|
||||||
} else {
|
} else {
|
||||||
/* It is a static lease... use it */
|
/* It is a static lease... use it */
|
||||||
packet.yiaddr = static_lease_ip;
|
packet.yiaddr = static_lease_ip;
|
||||||
@ -217,7 +212,7 @@ int FAST_FUNC send_ACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
|
|||||||
if (lease_time_aligned > server_config.lease)
|
if (lease_time_aligned > server_config.lease)
|
||||||
lease_time_aligned = server_config.lease;
|
lease_time_aligned = server_config.lease;
|
||||||
else if (lease_time_aligned < server_config.min_lease)
|
else if (lease_time_aligned < server_config.min_lease)
|
||||||
lease_time_aligned = server_config.lease;
|
lease_time_aligned = server_config.min_lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
|
add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
|
||||||
|
@ -15,69 +15,49 @@
|
|||||||
/* Takes the address of the pointer to the static_leases linked list,
|
/* Takes the address of the pointer to the static_leases linked list,
|
||||||
* Address to a 6 byte mac address
|
* Address to a 6 byte mac address
|
||||||
* Address to a 4 byte ip address */
|
* Address to a 4 byte ip address */
|
||||||
int FAST_FUNC addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip)
|
void FAST_FUNC addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t ip)
|
||||||
{
|
{
|
||||||
struct static_lease *cur;
|
|
||||||
struct static_lease *new_static_lease;
|
struct static_lease *new_static_lease;
|
||||||
|
|
||||||
/* Build new node */
|
/* Build new node */
|
||||||
new_static_lease = xmalloc(sizeof(struct static_lease));
|
new_static_lease = xzalloc(sizeof(struct static_lease));
|
||||||
new_static_lease->mac = mac;
|
memcpy(new_static_lease->mac, mac, 6);
|
||||||
new_static_lease->ip = ip;
|
new_static_lease->ip = ip;
|
||||||
new_static_lease->next = NULL;
|
/*new_static_lease->next = NULL;*/
|
||||||
|
|
||||||
/* If it's the first node to be added... */
|
/* If it's the first node to be added... */
|
||||||
if (*lease_struct == NULL) {
|
if (*lease_struct == NULL) {
|
||||||
*lease_struct = new_static_lease;
|
*lease_struct = new_static_lease;
|
||||||
} else {
|
} else {
|
||||||
cur = *lease_struct;
|
struct static_lease *cur = *lease_struct;
|
||||||
while (cur->next) {
|
while (cur->next)
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
|
||||||
|
|
||||||
cur->next = new_static_lease;
|
cur->next = new_static_lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if a mac has an associated static lease */
|
/* Check to see if a mac has an associated static lease */
|
||||||
uint32_t FAST_FUNC getIpByMac(struct static_lease *lease_struct, void *arg)
|
uint32_t FAST_FUNC getIpByMac(struct static_lease *lease_struct, void *mac)
|
||||||
{
|
{
|
||||||
uint32_t return_ip;
|
while (lease_struct) {
|
||||||
struct static_lease *cur = lease_struct;
|
if (memcmp(lease_struct->mac, mac, 6) == 0)
|
||||||
uint8_t *mac = arg;
|
return lease_struct->ip;
|
||||||
|
lease_struct = lease_struct->next;
|
||||||
return_ip = 0;
|
|
||||||
|
|
||||||
while (cur) {
|
|
||||||
/* If the client has the correct mac */
|
|
||||||
if (memcmp(cur->mac, mac, 6) == 0) {
|
|
||||||
return_ip = *(cur->ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return return_ip;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if an ip is reserved as a static ip */
|
/* Check to see if an ip is reserved as a static ip */
|
||||||
uint32_t FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip)
|
int FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip)
|
||||||
{
|
{
|
||||||
struct static_lease *cur = lease_struct;
|
while (lease_struct) {
|
||||||
|
if (lease_struct->ip == ip)
|
||||||
uint32_t return_val = 0;
|
return 1;
|
||||||
|
lease_struct = lease_struct->next;
|
||||||
while (cur) {
|
|
||||||
/* If the client has the correct ip */
|
|
||||||
if (*cur->ip == ip)
|
|
||||||
return_val = 1;
|
|
||||||
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return return_val;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_UDHCP_DEBUG
|
#if ENABLE_UDHCP_DEBUG
|
||||||
@ -85,15 +65,14 @@ uint32_t FAST_FUNC reservedIp(struct static_lease *lease_struct, uint32_t ip)
|
|||||||
/* Takes the address of the pointer to the static_leases linked list */
|
/* Takes the address of the pointer to the static_leases linked list */
|
||||||
void FAST_FUNC printStaticLeases(struct static_lease **arg)
|
void FAST_FUNC printStaticLeases(struct static_lease **arg)
|
||||||
{
|
{
|
||||||
/* Get a pointer to the linked list */
|
|
||||||
struct static_lease *cur = *arg;
|
struct static_lease *cur = *arg;
|
||||||
|
|
||||||
while (cur) {
|
while (cur) {
|
||||||
/* printf("PrintStaticLeases: Lease mac Address: %x\n", cur->mac); */
|
printf("PrintStaticLeases: Lease mac Value: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
printf("PrintStaticLeases: Lease mac Value: %x\n", *(cur->mac));
|
cur->mac[0], cur->mac[1], cur->mac[2],
|
||||||
/* printf("PrintStaticLeases: Lease ip Address: %x\n", cur->ip); */
|
cur->mac[3], cur->mac[4], cur->mac[5]
|
||||||
printf("PrintStaticLeases: Lease ip Value: %x\n", *(cur->ip));
|
);
|
||||||
|
printf("PrintStaticLeases: Lease ip Value: %x\n", cur->ip);
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user