mirror of
https://github.com/sheumann/hush.git
synced 2024-09-12 00:55:11 +00:00
udhcp: logging improvements, field and variable renames
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
2b0e957808
commit
6947d2c7e1
@ -41,7 +41,7 @@ enum {
|
|||||||
|
|
||||||
/* Returns 1 if no reply received */
|
/* Returns 1 if no reply received */
|
||||||
|
|
||||||
int FAST_FUNC arpping(uint32_t test_ip,
|
int FAST_FUNC arpping(uint32_t test_nip,
|
||||||
const uint8_t *safe_mac,
|
const uint8_t *safe_mac,
|
||||||
uint32_t from_ip,
|
uint32_t from_ip,
|
||||||
uint8_t *from_mac,
|
uint8_t *from_mac,
|
||||||
@ -78,7 +78,7 @@ int FAST_FUNC arpping(uint32_t test_ip,
|
|||||||
memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */
|
memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */
|
||||||
memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
|
memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
|
||||||
/* tHaddr is zero-filled */ /* target hardware address */
|
/* tHaddr is zero-filled */ /* target hardware address */
|
||||||
memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */
|
memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
|
safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
|
||||||
@ -111,7 +111,7 @@ int FAST_FUNC arpping(uint32_t test_ip,
|
|||||||
&& arp.operation == htons(ARPOP_REPLY)
|
&& arp.operation == htons(ARPOP_REPLY)
|
||||||
/* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
|
/* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
|
||||||
/* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
|
/* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
|
||||||
&& *((uint32_t *) arp.sInaddr) == test_ip
|
&& *((uint32_t *) arp.sInaddr) == test_nip
|
||||||
) {
|
) {
|
||||||
/* if ARP source MAC matches safe_mac
|
/* if ARP source MAC matches safe_mac
|
||||||
* (which is client's MAC), then it's not a conflict
|
* (which is client's MAC), then it's not a conflict
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
|
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
|
||||||
int dhcp_verbose;
|
unsigned dhcp_verbose;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = {
|
const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = {
|
||||||
|
@ -93,14 +93,14 @@ int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uin
|
|||||||
int udhcp_raw_socket(int ifindex) FAST_FUNC;
|
int udhcp_raw_socket(int ifindex) FAST_FUNC;
|
||||||
int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC;
|
int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC;
|
||||||
/* Returns 1 if no reply received */
|
/* Returns 1 if no reply received */
|
||||||
int arpping(uint32_t test_ip,
|
int arpping(uint32_t test_nip,
|
||||||
const uint8_t *safe_mac,
|
const uint8_t *safe_mac,
|
||||||
uint32_t from_ip,
|
uint32_t from_ip,
|
||||||
uint8_t *from_mac,
|
uint8_t *from_mac,
|
||||||
const char *interface) FAST_FUNC;
|
const char *interface) FAST_FUNC;
|
||||||
|
|
||||||
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
|
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
|
||||||
extern int dhcp_verbose;
|
extern unsigned dhcp_verbose;
|
||||||
# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
|
# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
|
||||||
# if CONFIG_UDHCP_DEBUG >= 2
|
# if CONFIG_UDHCP_DEBUG >= 2
|
||||||
void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
|
void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
struct dyn_lease *leases;
|
struct dyn_lease *g_leases;
|
||||||
/* struct server_config_t server_config is in bb_common_bufsiz1 */
|
/* struct server_config_t server_config is in bb_common_bufsiz1 */
|
||||||
|
|
||||||
|
|
||||||
@ -28,15 +28,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
int server_socket = -1, retval, max_sock;
|
int server_socket = -1, retval, max_sock;
|
||||||
struct dhcp_packet packet;
|
struct dhcp_packet packet;
|
||||||
uint8_t *state, *server_id, *requested;
|
uint8_t *state;
|
||||||
uint32_t server_id_aligned = server_id_aligned; /* for compiler */
|
|
||||||
uint32_t requested_aligned = requested_aligned;
|
|
||||||
uint32_t static_lease_ip;
|
uint32_t static_lease_ip;
|
||||||
unsigned timeout_end;
|
unsigned timeout_end;
|
||||||
unsigned num_ips;
|
unsigned num_ips;
|
||||||
unsigned opt;
|
unsigned opt;
|
||||||
struct option_set *option;
|
struct option_set *option;
|
||||||
struct dyn_lease *lease, static_lease;
|
struct dyn_lease *lease, fake_lease;
|
||||||
IF_FEATURE_UDHCP_PORT(char *str_P;)
|
IF_FEATURE_UDHCP_PORT(char *str_P;)
|
||||||
|
|
||||||
#if ENABLE_FEATURE_UDHCP_PORT
|
#if ENABLE_FEATURE_UDHCP_PORT
|
||||||
@ -84,10 +82,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_info_msg("%s (v"BB_VER") started", applet_name);
|
bb_info_msg("%s (v"BB_VER") started", applet_name);
|
||||||
|
|
||||||
option = find_option(server_config.options, DHCP_LEASE_TIME);
|
option = find_option(server_config.options, DHCP_LEASE_TIME);
|
||||||
server_config.lease = LEASE_TIME;
|
server_config.max_lease_sec = LEASE_TIME;
|
||||||
if (option) {
|
if (option) {
|
||||||
move_from_unaligned32(server_config.lease, option->data + 2);
|
move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA);
|
||||||
server_config.lease = ntohl(server_config.lease);
|
server_config.max_lease_sec = ntohl(server_config.max_lease_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
@ -98,7 +96,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
server_config.max_leases = num_ips;
|
server_config.max_leases = num_ips;
|
||||||
}
|
}
|
||||||
|
|
||||||
leases = xzalloc(server_config.max_leases * sizeof(*leases));
|
g_leases = xzalloc(server_config.max_leases * sizeof(g_leases[0]));
|
||||||
read_leases(server_config.lease_file);
|
read_leases(server_config.lease_file);
|
||||||
|
|
||||||
if (udhcp_read_interface(server_config.interface,
|
if (udhcp_read_interface(server_config.interface,
|
||||||
@ -186,13 +184,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
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);
|
||||||
|
|
||||||
memcpy(&static_lease.lease_mac, &packet.chaddr, 6);
|
memcpy(&fake_lease.lease_mac, &packet.chaddr, 6);
|
||||||
static_lease.lease_nip = static_lease_ip;
|
fake_lease.lease_nip = static_lease_ip;
|
||||||
static_lease.expires = 0;
|
fake_lease.expires = 0;
|
||||||
|
|
||||||
lease = &static_lease;
|
lease = &fake_lease;
|
||||||
} else {
|
} else {
|
||||||
lease = find_lease_by_chaddr(packet.chaddr);
|
lease = find_lease_by_mac(packet.chaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state[0]) {
|
switch (state[0]) {
|
||||||
@ -203,29 +201,32 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_error_msg("send OFFER failed");
|
bb_error_msg("send OFFER failed");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DHCPREQUEST:
|
case DHCPREQUEST: {
|
||||||
|
uint8_t *server_id_opt, *requested_opt;
|
||||||
|
uint32_t server_id_net = server_id_net; /* for compiler */
|
||||||
|
uint32_t requested_nip = requested_nip; /* for compiler */
|
||||||
|
|
||||||
log1("Received REQUEST");
|
log1("Received REQUEST");
|
||||||
|
|
||||||
requested = get_option(&packet, DHCP_REQUESTED_IP);
|
requested_opt = get_option(&packet, DHCP_REQUESTED_IP);
|
||||||
server_id = get_option(&packet, DHCP_SERVER_ID);
|
server_id_opt = get_option(&packet, DHCP_SERVER_ID);
|
||||||
|
if (requested_opt)
|
||||||
if (requested)
|
move_from_unaligned32(requested_nip, requested_opt);
|
||||||
move_from_unaligned32(requested_aligned, requested);
|
if (server_id_opt)
|
||||||
if (server_id)
|
move_from_unaligned32(server_id_net, server_id_opt);
|
||||||
move_from_unaligned32(server_id_aligned, server_id);
|
|
||||||
|
|
||||||
if (lease) {
|
if (lease) {
|
||||||
if (server_id) {
|
if (server_id_opt) {
|
||||||
/* SELECTING State */
|
/* SELECTING State */
|
||||||
if (server_id_aligned == server_config.server_nip
|
if (server_id_net == server_config.server_nip
|
||||||
&& requested
|
&& requested_opt
|
||||||
&& requested_aligned == lease->lease_nip
|
&& requested_nip == lease->lease_nip
|
||||||
) {
|
) {
|
||||||
send_ACK(&packet, lease->lease_nip);
|
send_ACK(&packet, lease->lease_nip);
|
||||||
}
|
}
|
||||||
} else if (requested) {
|
} else if (requested_opt) {
|
||||||
/* INIT-REBOOT State */
|
/* INIT-REBOOT State */
|
||||||
if (lease->lease_nip == requested_aligned)
|
if (lease->lease_nip == requested_nip)
|
||||||
send_ACK(&packet, lease->lease_nip);
|
send_ACK(&packet, lease->lease_nip);
|
||||||
else
|
else
|
||||||
send_NAK(&packet);
|
send_NAK(&packet);
|
||||||
@ -237,14 +238,14 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* what to do if we have no record of the client */
|
/* what to do if we have no record of the client */
|
||||||
} else if (server_id) {
|
} else if (server_id_opt) {
|
||||||
/* SELECTING State */
|
/* SELECTING State */
|
||||||
|
|
||||||
} else if (requested) {
|
} else if (requested_opt) {
|
||||||
/* INIT-REBOOT State */
|
/* INIT-REBOOT State */
|
||||||
lease = find_lease_by_yiaddr(requested_aligned);
|
lease = find_lease_by_nip(requested_nip);
|
||||||
if (lease) {
|
if (lease) {
|
||||||
if (lease_expired(lease)) {
|
if (is_expired_lease(lease)) {
|
||||||
/* probably best if we drop this lease */
|
/* probably best if we drop this lease */
|
||||||
memset(lease->lease_mac, 0, sizeof(lease->lease_mac));
|
memset(lease->lease_mac, 0, sizeof(lease->lease_mac));
|
||||||
} else {
|
} else {
|
||||||
@ -252,7 +253,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
send_NAK(&packet);
|
send_NAK(&packet);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t r = ntohl(requested_aligned);
|
uint32_t r = ntohl(requested_nip);
|
||||||
if (r < server_config.start_ip
|
if (r < server_config.start_ip
|
||||||
|| r > server_config.end_ip
|
|| r > server_config.end_ip
|
||||||
) {
|
) {
|
||||||
@ -265,6 +266,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* RENEWING or REBINDING State */
|
/* RENEWING or REBINDING State */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DHCPDECLINE:
|
case DHCPDECLINE:
|
||||||
log1("Received DECLINE");
|
log1("Received DECLINE");
|
||||||
if (lease) {
|
if (lease) {
|
||||||
|
@ -46,15 +46,15 @@ struct server_config_t {
|
|||||||
/* start,end are in host order: we need to compare start <= ip <= end */
|
/* start,end are in host order: we need to compare start <= ip <= end */
|
||||||
uint32_t start_ip; /* start address of leases, in host order */
|
uint32_t start_ip; /* start address of leases, in host order */
|
||||||
uint32_t end_ip; /* end of leases, in host order */
|
uint32_t end_ip; /* end of leases, in host order */
|
||||||
uint32_t lease; /* lease time in seconds (host order) */
|
uint32_t max_lease_sec; /* maximum lease time (host order) */
|
||||||
uint32_t max_leases; /* maximum number of leases (including reserved address) */
|
uint32_t min_lease_sec; /* minimum lease time a client can request */
|
||||||
|
uint32_t max_leases; /* maximum number of leases (including reserved addresses) */
|
||||||
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.
|
||||||
* if this is zero, it will only write one on SIGUSR1 */
|
* if this is zero, it will only write one on SIGUSR1 */
|
||||||
uint32_t decline_time; /* how long an address is reserved if a client returns a
|
uint32_t decline_time; /* how long an address is reserved if a client returns a
|
||||||
* 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 time a client can request */
|
|
||||||
uint32_t siaddr_nip; /* "next server" bootp option */
|
uint32_t siaddr_nip; /* "next server" bootp option */
|
||||||
char *lease_file;
|
char *lease_file;
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
@ -89,24 +89,24 @@ struct dyn_lease {
|
|||||||
/* We use lease_mac[6], since e.g. ARP probing uses
|
/* We use lease_mac[6], since e.g. ARP probing uses
|
||||||
* only 6 first bytes anyway. We check received dhcp packets
|
* only 6 first bytes anyway. We check received dhcp packets
|
||||||
* that their hlen == 6 and thus chaddr has only 6 significant bytes
|
* that their hlen == 6 and thus chaddr has only 6 significant bytes
|
||||||
* (dhcp packet has chaddr[16])
|
* (dhcp packet has chaddr[16], not [6])
|
||||||
*/
|
*/
|
||||||
uint8_t lease_mac[6];
|
uint8_t lease_mac[6];
|
||||||
uint8_t hostname[20];
|
uint8_t hostname[20];
|
||||||
uint8_t pad[2];
|
uint8_t pad[2];
|
||||||
/* total size is a multiply of 4 */
|
/* total size is a multiply of 4 */
|
||||||
};
|
} PACKED;
|
||||||
|
|
||||||
extern struct dyn_lease *leases;
|
extern struct dyn_lease *g_leases;
|
||||||
|
|
||||||
struct dyn_lease *add_lease(
|
struct dyn_lease *add_lease(
|
||||||
const uint8_t *chaddr, uint32_t yiaddr,
|
const uint8_t *chaddr, uint32_t yiaddr,
|
||||||
leasetime_t leasetime, uint8_t *hostname
|
leasetime_t leasetime, uint8_t *hostname
|
||||||
) FAST_FUNC;
|
) FAST_FUNC;
|
||||||
int lease_expired(struct dyn_lease *lease) FAST_FUNC;
|
int is_expired_lease(struct dyn_lease *lease) FAST_FUNC;
|
||||||
struct dyn_lease *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC;
|
struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC;
|
||||||
struct dyn_lease *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC;
|
struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC;
|
||||||
uint32_t find_free_or_expired_address(const uint8_t *chaddr) FAST_FUNC;
|
uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC;
|
||||||
|
|
||||||
|
|
||||||
/*** static_leases.h ***/
|
/*** static_leases.h ***/
|
||||||
|
@ -295,7 +295,7 @@ static const struct config_keyword keywords[] = {
|
|||||||
{"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"},
|
||||||
{"offer_time", read_u32, &(server_config.offer_time), "60"},
|
{"offer_time", read_u32, &(server_config.offer_time), "60"},
|
||||||
{"min_lease", read_u32, &(server_config.min_lease), "60"},
|
{"min_lease", read_u32, &(server_config.min_lease_sec),"60"},
|
||||||
{"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
|
{"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
|
||||||
{"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
|
{"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
|
||||||
{"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"},
|
{"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"},
|
||||||
@ -359,23 +359,23 @@ void FAST_FUNC write_leases(void)
|
|||||||
for (i = 0; i < server_config.max_leases; i++) {
|
for (i = 0; i < server_config.max_leases; i++) {
|
||||||
leasetime_t tmp_time;
|
leasetime_t tmp_time;
|
||||||
|
|
||||||
if (leases[i].lease_nip == 0)
|
if (g_leases[i].lease_nip == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Screw with the time in the struct, for easier writing */
|
/* Screw with the time in the struct, for easier writing */
|
||||||
tmp_time = leases[i].expires;
|
tmp_time = g_leases[i].expires;
|
||||||
|
|
||||||
leases[i].expires -= curr;
|
g_leases[i].expires -= curr;
|
||||||
if ((signed_leasetime_t) leases[i].expires < 0)
|
if ((signed_leasetime_t) g_leases[i].expires < 0)
|
||||||
leases[i].expires = 0;
|
g_leases[i].expires = 0;
|
||||||
leases[i].expires = htonl(leases[i].expires);
|
g_leases[i].expires = htonl(g_leases[i].expires);
|
||||||
|
|
||||||
/* No error check. If the file gets truncated,
|
/* No error check. If the file gets truncated,
|
||||||
* we lose some leases on restart. Oh well. */
|
* we lose some leases on restart. Oh well. */
|
||||||
full_write(fd, &leases[i], sizeof(leases[i]));
|
full_write(fd, &g_leases[i], sizeof(g_leases[i]));
|
||||||
|
|
||||||
/* Then restore it when done */
|
/* Then restore it when done */
|
||||||
leases[i].expires = tmp_time;
|
g_leases[i].expires = tmp_time;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@ static struct dyn_lease *oldest_expired_lease(void)
|
|||||||
leasetime_t oldest_time = time(NULL);
|
leasetime_t oldest_time = time(NULL);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* Unexpired leases have leases[i].expires >= current time
|
/* Unexpired leases have g_leases[i].expires >= current time
|
||||||
* and therefore can't ever match */
|
* and therefore can't ever match */
|
||||||
for (i = 0; i < server_config.max_leases; i++) {
|
for (i = 0; i < server_config.max_leases; i++) {
|
||||||
if (leases[i].expires < oldest_time) {
|
if (g_leases[i].expires < oldest_time) {
|
||||||
oldest_time = leases[i].expires;
|
oldest_time = g_leases[i].expires;
|
||||||
oldest_lease = &leases[i];
|
oldest_lease = &g_leases[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return oldest_lease;
|
return oldest_lease;
|
||||||
@ -38,10 +38,10 @@ static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
|
|||||||
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].lease_mac, chaddr, 6) == 0)
|
if ((j != 16 && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0)
|
||||||
|| (yiaddr && leases[i].lease_nip == yiaddr)
|
|| (yiaddr && g_leases[i].lease_nip == yiaddr)
|
||||||
) {
|
) {
|
||||||
memset(&leases[i], 0, sizeof(leases[i]));
|
memset(&g_leases[i], 0, sizeof(g_leases[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,40 +85,40 @@ struct dyn_lease* FAST_FUNC add_lease(
|
|||||||
|
|
||||||
|
|
||||||
/* True if a lease has expired */
|
/* True if a lease has expired */
|
||||||
int FAST_FUNC lease_expired(struct dyn_lease *lease)
|
int FAST_FUNC is_expired_lease(struct dyn_lease *lease)
|
||||||
{
|
{
|
||||||
return (lease->expires < (leasetime_t) time(NULL));
|
return (lease->expires < (leasetime_t) time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Find the first lease that matches chaddr, NULL if no match */
|
/* Find the first lease that matches MAC, NULL if no match */
|
||||||
struct dyn_lease* FAST_FUNC find_lease_by_chaddr(const uint8_t *chaddr)
|
struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < server_config.max_leases; i++)
|
for (i = 0; i < server_config.max_leases; i++)
|
||||||
if (memcmp(leases[i].lease_mac, chaddr, 6) == 0)
|
if (memcmp(g_leases[i].lease_mac, mac, 6) == 0)
|
||||||
return &(leases[i]);
|
return &g_leases[i];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Find the first lease that matches yiaddr, NULL is no match */
|
/* Find the first lease that matches IP, NULL is no match */
|
||||||
struct dyn_lease* FAST_FUNC find_lease_by_yiaddr(uint32_t yiaddr)
|
struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < server_config.max_leases; i++)
|
for (i = 0; i < server_config.max_leases; i++)
|
||||||
if (leases[i].lease_nip == yiaddr)
|
if (g_leases[i].lease_nip == nip)
|
||||||
return &leases[i];
|
return &g_leases[i];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check if the IP is taken; if it is, add it to the lease table */
|
/* Check if the IP is taken; if it is, add it to the lease table */
|
||||||
static int nobody_responds_to_arp(uint32_t addr, const uint8_t *safe_mac)
|
static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
|
||||||
{
|
{
|
||||||
/* 16 zero bytes */
|
/* 16 zero bytes */
|
||||||
static const uint8_t blank_chaddr[16] = { 0 };
|
static const uint8_t blank_chaddr[16] = { 0 };
|
||||||
@ -127,30 +127,30 @@ static int nobody_responds_to_arp(uint32_t addr, const uint8_t *safe_mac)
|
|||||||
struct in_addr temp;
|
struct in_addr temp;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = arpping(addr, safe_mac,
|
r = arpping(nip, safe_mac,
|
||||||
server_config.server_nip,
|
server_config.server_nip,
|
||||||
server_config.server_mac,
|
server_config.server_mac,
|
||||||
server_config.interface);
|
server_config.interface);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
temp.s_addr = addr;
|
temp.s_addr = nip;
|
||||||
bb_info_msg("%s belongs to someone, reserving it for %u seconds",
|
bb_info_msg("%s belongs to someone, reserving it for %u seconds",
|
||||||
inet_ntoa(temp), (unsigned)server_config.conflict_time);
|
inet_ntoa(temp), (unsigned)server_config.conflict_time);
|
||||||
add_lease(blank_chaddr, addr, server_config.conflict_time, NULL);
|
add_lease(blank_chaddr, nip, server_config.conflict_time, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Find a new usable (we think) address */
|
/* Find a new usable (we think) address */
|
||||||
uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr)
|
uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
struct dyn_lease *oldest_lease = NULL;
|
struct dyn_lease *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;
|
uint32_t nip;
|
||||||
struct dyn_lease *lease;
|
struct dyn_lease *lease;
|
||||||
|
|
||||||
/* ie, 192.168.55.0 */
|
/* ie, 192.168.55.0 */
|
||||||
@ -159,23 +159,23 @@ uint32_t FAST_FUNC find_free_or_expired_address(const uint8_t *chaddr)
|
|||||||
/* ie, 192.168.55.255 */
|
/* ie, 192.168.55.255 */
|
||||||
if ((addr & 0xff) == 0xff)
|
if ((addr & 0xff) == 0xff)
|
||||||
continue;
|
continue;
|
||||||
net_addr = htonl(addr);
|
nip = htonl(addr);
|
||||||
/* is this a static lease addr? */
|
/* is this a static lease addr? */
|
||||||
if (is_nip_reserved(server_config.static_leases, net_addr))
|
if (is_nip_reserved(server_config.static_leases, nip))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lease = find_lease_by_yiaddr(net_addr);
|
lease = find_lease_by_nip(nip);
|
||||||
if (!lease) {
|
if (!lease) {
|
||||||
if (nobody_responds_to_arp(net_addr, chaddr))
|
if (nobody_responds_to_arp(nip, safe_mac))
|
||||||
return net_addr;
|
return nip;
|
||||||
} else {
|
} else {
|
||||||
if (!oldest_lease || lease->expires < oldest_lease->expires)
|
if (!oldest_lease || lease->expires < oldest_lease->expires)
|
||||||
oldest_lease = lease;
|
oldest_lease = lease;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldest_lease && lease_expired(oldest_lease)
|
if (oldest_lease && is_expired_lease(oldest_lease)
|
||||||
&& nobody_responds_to_arp(oldest_lease->lease_nip, chaddr)
|
&& nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac)
|
||||||
) {
|
) {
|
||||||
return oldest_lease->lease_nip;
|
return oldest_lease->lease_nip;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,20 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
|
||||||
|
static void log_option(const char *pfx, const uint8_t *opt)
|
||||||
|
{
|
||||||
|
if (dhcp_verbose >= 2) {
|
||||||
|
char buf[256 * 2 + 2];
|
||||||
|
*bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0';
|
||||||
|
bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define log_option(pfx, opt) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* get an option with bounds checking (warning, result is not aligned). */
|
/* get an option with bounds checking (warning, result is not aligned). */
|
||||||
uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code)
|
uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code)
|
||||||
{
|
{
|
||||||
@ -167,11 +181,7 @@ uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code)
|
|||||||
continue; /* complain and return NULL */
|
continue; /* complain and return NULL */
|
||||||
|
|
||||||
if (optionptr[OPT_CODE] == code) {
|
if (optionptr[OPT_CODE] == code) {
|
||||||
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
|
log_option("Option found", optionptr);
|
||||||
char buf[256 * 2 + 2];
|
|
||||||
*bin2hex(buf, (void*) (optionptr + OPT_DATA), optionptr[OPT_LEN]) = '\0';
|
|
||||||
log2("Option 0x%02x found: %s", code, buf);
|
|
||||||
#endif
|
|
||||||
return optionptr + OPT_DATA;
|
return optionptr + OPT_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +224,7 @@ int FAST_FUNC add_option_string(uint8_t *optionptr, uint8_t *string)
|
|||||||
string[OPT_CODE]);
|
string[OPT_CODE]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log1("Adding option 0x%02x", string[OPT_CODE]);
|
log_option("Adding option", string);
|
||||||
memcpy(optionptr + end, string, string[OPT_LEN] + 2);
|
memcpy(optionptr + end, string, string[OPT_LEN] + 2);
|
||||||
optionptr[end + string[OPT_LEN] + 2] = DHCP_END;
|
optionptr[end + string[OPT_LEN] + 2] = DHCP_END;
|
||||||
return string[OPT_LEN] + 2;
|
return string[OPT_LEN] + 2;
|
||||||
|
@ -78,7 +78,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet)
|
|||||||
//, packet->cookie
|
//, packet->cookie
|
||||||
//, packet->options[]
|
//, packet->options[]
|
||||||
);
|
);
|
||||||
bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr));
|
*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0';
|
||||||
bb_info_msg(" chaddr %s", buf);
|
bb_info_msg(" chaddr %s", buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -218,17 +218,17 @@ void FAST_FUNC udhcp_run_script(struct dhcp_packet *packet, const char *name)
|
|||||||
if (client_config.script == NULL)
|
if (client_config.script == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log1("Executing %s", client_config.script);
|
|
||||||
|
|
||||||
envp = fill_envp(packet);
|
envp = fill_envp(packet);
|
||||||
|
|
||||||
/* call script */
|
/* call script */
|
||||||
|
log1("Executing %s", client_config.script);
|
||||||
argv[0] = (char*) client_config.script;
|
argv[0] = (char*) client_config.script;
|
||||||
argv[1] = (char*) name;
|
argv[1] = (char*) name;
|
||||||
argv[2] = NULL;
|
argv[2] = NULL;
|
||||||
wait4pid(spawn(argv));
|
wait4pid(spawn(argv));
|
||||||
|
|
||||||
for (curr = envp; *curr; curr++) {
|
for (curr = envp; *curr; curr++) {
|
||||||
|
log2(" %s", *curr);
|
||||||
bb_unsetenv(*curr);
|
bb_unsetenv(*curr);
|
||||||
free(*curr);
|
free(*curr);
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,30 @@ static void add_bootp_options(struct dhcp_packet *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t select_lease_time(struct dhcp_packet *packet)
|
||||||
|
{
|
||||||
|
uint32_t lease_time_sec = server_config.max_lease_sec;
|
||||||
|
uint8_t *lease_time_opt = get_option(packet, DHCP_LEASE_TIME);
|
||||||
|
if (lease_time_opt) {
|
||||||
|
move_from_unaligned32(lease_time_sec, lease_time_opt);
|
||||||
|
lease_time_sec = ntohl(lease_time_sec);
|
||||||
|
if (lease_time_sec > server_config.max_lease_sec)
|
||||||
|
lease_time_sec = server_config.max_lease_sec;
|
||||||
|
if (lease_time_sec < server_config.min_lease_sec)
|
||||||
|
lease_time_sec = server_config.min_lease_sec;
|
||||||
|
}
|
||||||
|
return lease_time_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* send a DHCP OFFER to a DHCP DISCOVER */
|
/* send a DHCP OFFER to a DHCP DISCOVER */
|
||||||
int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
|
int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
|
||||||
{
|
{
|
||||||
struct dhcp_packet packet;
|
struct dhcp_packet packet;
|
||||||
uint32_t req_align;
|
uint32_t req_nip;
|
||||||
uint32_t lease_time_aligned = server_config.lease;
|
uint32_t lease_time_sec = server_config.max_lease_sec;
|
||||||
uint32_t static_lease_ip;
|
uint32_t static_lease_ip;
|
||||||
uint8_t *req, *lease_time, *p_host_name;
|
uint8_t *req_ip_opt, *p_host_name;
|
||||||
struct option_set *curr;
|
struct option_set *curr;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
@ -126,31 +142,31 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
|
|||||||
if (!static_lease_ip) {
|
if (!static_lease_ip) {
|
||||||
struct dyn_lease *lease;
|
struct dyn_lease *lease;
|
||||||
|
|
||||||
lease = find_lease_by_chaddr(oldpacket->chaddr);
|
lease = find_lease_by_mac(oldpacket->chaddr);
|
||||||
/* The client is in our lease/offered table */
|
/* The client is in our lease/offered table */
|
||||||
if (lease) {
|
if (lease) {
|
||||||
signed_leasetime_t tmp = lease->expires - time(NULL);
|
signed_leasetime_t tmp = lease->expires - time(NULL);
|
||||||
if (tmp >= 0)
|
if (tmp >= 0)
|
||||||
lease_time_aligned = tmp;
|
lease_time_sec = tmp;
|
||||||
packet.yiaddr = lease->lease_nip;
|
packet.yiaddr = lease->lease_nip;
|
||||||
}
|
}
|
||||||
/* Or the client has requested an IP */
|
/* Or the client has requested an IP */
|
||||||
else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
|
else if ((req_ip_opt = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
|
||||||
/* (read IP) */
|
/* (read IP) */
|
||||||
&& (move_from_unaligned32(req_align, req), 1)
|
&& (move_from_unaligned32(req_nip, req_ip_opt), 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_nip) >= server_config.start_ip
|
||||||
&& ntohl(req_align) <= server_config.end_ip
|
&& ntohl(req_nip) <= server_config.end_ip
|
||||||
/* and is not already taken/offered */
|
/* and is not already taken/offered */
|
||||||
&& (!(lease = find_lease_by_yiaddr(req_align))
|
&& (!(lease = find_lease_by_nip(req_nip))
|
||||||
/* or its taken, but expired */
|
/* or its taken, but expired */
|
||||||
|| lease_expired(lease))
|
|| is_expired_lease(lease))
|
||||||
) {
|
) {
|
||||||
packet.yiaddr = req_align;
|
packet.yiaddr = req_nip;
|
||||||
}
|
}
|
||||||
/* Otherwise, find a free IP */
|
/* Otherwise, find a free IP */
|
||||||
else {
|
else {
|
||||||
packet.yiaddr = find_free_or_expired_address(oldpacket->chaddr);
|
packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packet.yiaddr) {
|
if (!packet.yiaddr) {
|
||||||
@ -162,23 +178,13 @@ int FAST_FUNC send_offer(struct dhcp_packet *oldpacket)
|
|||||||
bb_error_msg("lease pool is full - OFFER abandoned");
|
bb_error_msg("lease pool is full - OFFER abandoned");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
lease_time = get_option(oldpacket, DHCP_LEASE_TIME);
|
lease_time_sec = select_lease_time(oldpacket);
|
||||||
if (lease_time) {
|
|
||||||
move_from_unaligned32(lease_time_aligned, lease_time);
|
|
||||||
lease_time_aligned = ntohl(lease_time_aligned);
|
|
||||||
if (lease_time_aligned > server_config.lease)
|
|
||||||
lease_time_aligned = server_config.lease;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure we aren't just using the lease time from the previous offer */
|
|
||||||
if (lease_time_aligned < server_config.min_lease)
|
|
||||||
lease_time_aligned = server_config.min_lease;
|
|
||||||
} 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
|
add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec));
|
||||||
|
|
||||||
curr = server_config.options;
|
curr = server_config.options;
|
||||||
while (curr) {
|
while (curr) {
|
||||||
@ -210,25 +216,16 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
|
|||||||
{
|
{
|
||||||
struct dhcp_packet packet;
|
struct dhcp_packet packet;
|
||||||
struct option_set *curr;
|
struct option_set *curr;
|
||||||
uint8_t *lease_time;
|
uint32_t lease_time_sec;
|
||||||
uint32_t lease_time_aligned = server_config.lease;
|
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
uint8_t *p_host_name;
|
uint8_t *p_host_name;
|
||||||
|
|
||||||
init_packet(&packet, oldpacket, DHCPACK);
|
init_packet(&packet, oldpacket, DHCPACK);
|
||||||
packet.yiaddr = yiaddr;
|
packet.yiaddr = yiaddr;
|
||||||
|
|
||||||
lease_time = get_option(oldpacket, DHCP_LEASE_TIME);
|
lease_time_sec = select_lease_time(oldpacket);
|
||||||
if (lease_time) {
|
|
||||||
move_from_unaligned32(lease_time_aligned, lease_time);
|
|
||||||
lease_time_aligned = ntohl(lease_time_aligned);
|
|
||||||
if (lease_time_aligned > server_config.lease)
|
|
||||||
lease_time_aligned = server_config.lease;
|
|
||||||
else if (lease_time_aligned < server_config.min_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_sec));
|
||||||
|
|
||||||
curr = server_config.options;
|
curr = server_config.options;
|
||||||
while (curr) {
|
while (curr) {
|
||||||
@ -246,7 +243,7 @@ int FAST_FUNC send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
p_host_name = get_option(oldpacket, DHCP_HOST_NAME);
|
p_host_name = get_option(oldpacket, DHCP_HOST_NAME);
|
||||||
add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned, p_host_name);
|
add_lease(packet.chaddr, packet.yiaddr, lease_time_sec, p_host_name);
|
||||||
if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
|
if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
|
||||||
/* rewrite the file with leases at every new acceptance */
|
/* rewrite the file with leases at every new acceptance */
|
||||||
write_leases();
|
write_leases();
|
||||||
|
Loading…
Reference in New Issue
Block a user