1303 files changed, 32187 insertions, 57138 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index a1a7f6b..e116ba3 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -20,6 +20,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +//applet:IF_UDHCPD(APPLET(udhcpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UDHCPD) += common.o packet.o signalpipe.o socket.o +//kbuild:lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o +//kbuild:lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o //usage:#define udhcpd_trivial_usage //usage: "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]" @@ -28,15 +33,512 @@ //usage: "\n -f Run in foreground" //usage: "\n -S Log to syslog too" //usage: "\n -I ADDR Local address" +//usage: "\n -a MSEC Timeout for ARP ping (default 2000)" //usage: IF_FEATURE_UDHCP_PORT( //usage: "\n -P N Use port N (default 67)" //usage: ) +#include <netinet/ether.h> #include <syslog.h> #include "common.h" #include "dhcpc.h" #include "dhcpd.h" +/* globals */ +struct dyn_lease *g_leases; +/* struct server_config_t server_config is in bb_common_bufsiz1 */ + +/* Takes the address of the pointer to the static_leases linked list, + * address to a 6 byte mac address, + * 4 byte IP address */ +static void add_static_lease(struct static_lease **st_lease_pp, + uint8_t *mac, + uint32_t nip) +{ + struct static_lease *st_lease; + + /* Find the tail of the list */ + while ((st_lease = *st_lease_pp) != NULL) { + st_lease_pp = &st_lease->next; + } + + /* Add new node */ + *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease)); + memcpy(st_lease->mac, mac, 6); + st_lease->nip = nip; + /*st_lease->next = NULL;*/ +} + +/* Find static lease IP by mac */ +static uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *mac) +{ + while (st_lease) { + if (memcmp(st_lease->mac, mac, 6) == 0) + return st_lease->nip; + st_lease = st_lease->next; + } + + return 0; +} + +static int is_nip_reserved(struct static_lease *st_lease, uint32_t nip) +{ + while (st_lease) { + if (st_lease->nip == nip) + return 1; + st_lease = st_lease->next; + } + + return 0; +} + +#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 +/* Print out static leases just to check what's going on */ +/* Takes the address of the pointer to the static_leases linked list */ +static void log_static_leases(struct static_lease **st_lease_pp) +{ + struct static_lease *cur; + + if (dhcp_verbose < 2) + return; + + cur = *st_lease_pp; + while (cur) { + bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", + cur->mac[0], cur->mac[1], cur->mac[2], + cur->mac[3], cur->mac[4], cur->mac[5], + cur->nip + ); + cur = cur->next; + } +} +#else +# define log_static_leases(st_lease_pp) ((void)0) +#endif + +/* Find the oldest expired lease, NULL if there are no expired leases */ +static struct dyn_lease *oldest_expired_lease(void) +{ + struct dyn_lease *oldest_lease = NULL; + leasetime_t oldest_time = time(NULL); + unsigned i; + + /* Unexpired leases have g_leases[i].expires >= current time + * and therefore can't ever match */ + for (i = 0; i < server_config.max_leases; i++) { + if (g_leases[i].expires == 0 /* empty entry */ + || g_leases[i].expires < oldest_time + ) { + oldest_time = g_leases[i].expires; + oldest_lease = &g_leases[i]; + } + } + return oldest_lease; +} + +/* Clear out all leases with matching nonzero chaddr OR yiaddr. + * If chaddr == NULL, this is a conflict lease. + */ +static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr) +{ + unsigned i; + + for (i = 0; i < server_config.max_leases; i++) { + if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) + || (yiaddr && g_leases[i].lease_nip == yiaddr) + ) { + memset(&g_leases[i], 0, sizeof(g_leases[i])); + } + } +} + +/* Add a lease into the table, clearing out any old ones. + * If chaddr == NULL, this is a conflict lease. + */ +static struct dyn_lease *add_lease( + const uint8_t *chaddr, uint32_t yiaddr, + leasetime_t leasetime, + const char *hostname, int hostname_len) +{ + struct dyn_lease *oldest; + + /* clean out any old ones */ + clear_leases(chaddr, yiaddr); + + oldest = oldest_expired_lease(); + + if (oldest) { + memset(oldest, 0, sizeof(*oldest)); + if (hostname) { + char *p; + + hostname_len++; /* include NUL */ + if (hostname_len > sizeof(oldest->hostname)) + hostname_len = sizeof(oldest->hostname); + p = safe_strncpy(oldest->hostname, hostname, hostname_len); + /* + * Sanitization (s/bad_char/./g). + * The intent is not to allow only "DNS-valid" hostnames, + * but merely make dumpleases output safe for shells to use. + * We accept "0-9A-Za-z._-", all other chars turn to dots. + */ + while (*p) { + if (!isalnum(*p) && *p != '-' && *p != '_') + *p = '.'; + p++; + } + } + if (chaddr) + memcpy(oldest->lease_mac, chaddr, 6); + oldest->lease_nip = yiaddr; + oldest->expires = time(NULL) + leasetime; + } + + return oldest; +} + +/* True if a lease has expired */ +static int is_expired_lease(struct dyn_lease *lease) +{ + return (lease->expires < (leasetime_t) time(NULL)); +} + +/* Find the first lease that matches MAC, NULL if no match */ +static struct dyn_lease *find_lease_by_mac(const uint8_t *mac) +{ + unsigned i; + + for (i = 0; i < server_config.max_leases; i++) + if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) + return &g_leases[i]; + + return NULL; +} + +/* Find the first lease that matches IP, NULL is no match */ +static struct dyn_lease *find_lease_by_nip(uint32_t nip) +{ + unsigned i; + + for (i = 0; i < server_config.max_leases; i++) + if (g_leases[i].lease_nip == nip) + return &g_leases[i]; + + return NULL; +} + +/* Check if the IP is taken; if it is, add it to the lease table */ +static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) +{ + struct in_addr temp; + int r; + + r = arpping(nip, safe_mac, + server_config.server_nip, + server_config.server_mac, + server_config.interface, + arpping_ms); + if (r) + return r; + + temp.s_addr = nip; + bb_error_msg("%s belongs to someone, reserving it for %u seconds", + inet_ntoa(temp), (unsigned)server_config.conflict_time); + add_lease(NULL, nip, server_config.conflict_time, NULL, 0); + return 0; +} + +/* Find a new usable (we think) address */ +static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) +{ + uint32_t addr; + struct dyn_lease *oldest_lease = NULL; + +#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC + uint32_t stop; + unsigned i, hash; + + /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good + * dispersal even with similarly-valued "strings". + */ + hash = 0; + for (i = 0; i < 6; i++) + hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; + + /* pick a seed based on hwaddr then iterate until we find a free address. */ + addr = server_config.start_ip + + (hash % (1 + server_config.end_ip - server_config.start_ip)); + stop = addr; +#else + addr = server_config.start_ip; +#define stop (server_config.end_ip + 1) +#endif + do { + uint32_t nip; + struct dyn_lease *lease; + + /* ie, 192.168.55.0 */ + if ((addr & 0xff) == 0) + goto next_addr; + /* ie, 192.168.55.255 */ + if ((addr & 0xff) == 0xff) + goto next_addr; + nip = htonl(addr); + /* skip our own address */ + if (nip == server_config.server_nip) + goto next_addr; + /* is this a static lease addr? */ + if (is_nip_reserved(server_config.static_leases, nip)) + goto next_addr; + + lease = find_lease_by_nip(nip); + if (!lease) { +//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! + if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) + return nip; + } else { + if (!oldest_lease || lease->expires < oldest_lease->expires) + oldest_lease = lease; + } + + next_addr: + addr++; +#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC + if (addr > server_config.end_ip) + addr = server_config.start_ip; +#endif + } while (addr != stop); + + if (oldest_lease + && is_expired_lease(oldest_lease) + && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) + ) { + return oldest_lease->lease_nip; + } + + return 0; +} + +/* On these functions, make sure your datatype matches */ +static int FAST_FUNC read_str(const char *line, void *arg) +{ + char **dest = arg; + + free(*dest); + *dest = xstrdup(line); + return 1; +} + +static int FAST_FUNC read_u32(const char *line, void *arg) +{ + *(uint32_t*)arg = bb_strtou32(line, NULL, 10); + return errno == 0; +} + +static int FAST_FUNC read_staticlease(const char *const_line, void *arg) +{ + char *line; + char *mac_string; + char *ip_string; + struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */ + uint32_t nip; + + /* Read mac */ + line = (char *) const_line; + mac_string = strtok_r(line, " \t", &line); + if (!mac_string || !ether_aton_r(mac_string, &mac_bytes)) + return 0; + + /* Read ip */ + ip_string = strtok_r(NULL, " \t", &line); + if (!ip_string || !udhcp_str2nip(ip_string, &nip)) + return 0; + + add_static_lease(arg, (uint8_t*) &mac_bytes, nip); + + log_static_leases(arg); + + return 1; +} + +struct config_keyword { + const char *keyword; + int (*handler)(const char *line, void *var) FAST_FUNC; + unsigned ofs; + const char *def; +}; + +#define OFS(field) offsetof(struct server_config_t, field) + +static const struct config_keyword keywords[] = { + /* keyword handler variable address default */ + {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, + {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, + {"interface" , read_str , OFS(interface ), "eth0"}, + /* Avoid "max_leases value not sane" warning by setting default + * to default_end_ip - default_start_ip + 1: */ + {"max_leases" , read_u32 , OFS(max_leases ), "235"}, + {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, + {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, + {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, + {"offer_time" , read_u32 , OFS(offer_time ), "60"}, + {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, + {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, + {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, + {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, + /* keywords with no defaults must be last! */ + {"option" , udhcp_str2optset, OFS(options ), ""}, + {"opt" , udhcp_str2optset, OFS(options ), ""}, + {"notify_file" , read_str , OFS(notify_file ), NULL}, + {"sname" , read_str , OFS(sname ), NULL}, + {"boot_file" , read_str , OFS(boot_file ), NULL}, + {"static_lease" , read_staticlease, OFS(static_leases), ""}, +}; +enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; + +static NOINLINE void read_config(const char *file) +{ + parser_t *parser; + const struct config_keyword *k; + unsigned i; + char *token[2]; + + for (i = 0; i < KWS_WITH_DEFAULTS; i++) + keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); + + parser = config_open(file); + while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { + for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { + if (strcasecmp(token[0], k->keyword) == 0) { + if (!k->handler(token[1], (char*)&server_config + k->ofs)) { + bb_error_msg("can't parse line %u in %s", + parser->lineno, file); + /* reset back to the default value */ + k->handler(k->def, (char*)&server_config + k->ofs); + } + break; + } + } + } + config_close(parser); + + server_config.start_ip = ntohl(server_config.start_ip); + server_config.end_ip = ntohl(server_config.end_ip); +} + +static void write_leases(void) +{ + int fd; + unsigned i; + leasetime_t curr; + int64_t written_at; + + fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); + if (fd < 0) + return; + + curr = written_at = time(NULL); + + written_at = SWAP_BE64(written_at); + full_write(fd, &written_at, sizeof(written_at)); + + for (i = 0; i < server_config.max_leases; i++) { + leasetime_t tmp_time; + + if (g_leases[i].lease_nip == 0) + continue; + + /* Screw with the time in the struct, for easier writing */ + tmp_time = g_leases[i].expires; + + g_leases[i].expires -= curr; + if ((signed_leasetime_t) g_leases[i].expires < 0) + g_leases[i].expires = 0; + g_leases[i].expires = htonl(g_leases[i].expires); + + /* No error check. If the file gets truncated, + * we lose some leases on restart. Oh well. */ + full_write(fd, &g_leases[i], sizeof(g_leases[i])); + + /* Then restore it when done */ + g_leases[i].expires = tmp_time; + } + close(fd); + + if (server_config.notify_file) { + char *argv[3]; + argv[0] = server_config.notify_file; + argv[1] = server_config.lease_file; + argv[2] = NULL; + spawn_and_wait(argv); + } +} + +static NOINLINE void read_leases(const char *file) +{ + struct dyn_lease lease; + int64_t written_at, time_passed; + int fd; +#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 + unsigned i = 0; +#endif + + fd = open_or_warn(file, O_RDONLY); + if (fd < 0) + return; + + if (full_read(fd, &written_at, sizeof(written_at)) != sizeof(written_at)) + goto ret; + written_at = SWAP_BE64(written_at); + + time_passed = time(NULL) - written_at; + /* Strange written_at, or lease file from old version of udhcpd + * which had no "written_at" field? */ + if ((uint64_t)time_passed > 12 * 60 * 60) + goto ret; + + while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { + uint32_t y = ntohl(lease.lease_nip); + if (y >= server_config.start_ip && y <= server_config.end_ip) { + signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; + uint32_t static_nip; + + if (expires <= 0) + /* We keep expired leases: add_lease() will add + * a lease with 0 seconds remaining. + * Fewer IP address changes this way for mass reboot scenario. + */ + expires = 0; + + /* Check if there is a different static lease for this IP or MAC */ + static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); + if (static_nip) { + /* NB: we do not add lease even if static_nip == lease.lease_nip. + */ + continue; + } + if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) + continue; + + /* NB: add_lease takes "relative time", IOW, + * lease duration, not lease deadline. */ + if (add_lease(lease.lease_mac, lease.lease_nip, + expires, + lease.hostname, sizeof(lease.hostname) + ) == 0 + ) { + bb_error_msg("too many leases while loading %s", file); + break; + } +#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 + i++; +#endif + } + } + log1("read %d leases", i); + ret: + close(fd); +} /* Send a packet to a specific mac address and ip address by creating our own ip packet */ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) @@ -60,11 +562,11 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) || dhcp_pkt->ciaddr == 0 ) { - log1("Broadcasting packet to client"); + log1("broadcasting packet to client"); ciaddr = INADDR_BROADCAST; chaddr = MAC_BCAST_ADDR; } else { - log1("Unicasting packet to client ciaddr"); + log1("unicasting packet to client ciaddr"); ciaddr = dhcp_pkt->ciaddr; chaddr = dhcp_pkt->chaddr; } @@ -78,7 +580,7 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc /* Send a packet to gateway_nip using the kernel ip stack */ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) { - log1("Forwarding packet to relay"); + log1("forwarding packet to relay"); udhcp_send_kernel_packet(dhcp_pkt, server_config.server_nip, SERVER_PORT, @@ -148,7 +650,8 @@ static uint32_t select_lease_time(struct dhcp_packet *packet) static NOINLINE void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease, - uint8_t *requested_ip_opt) + uint8_t *requested_ip_opt, + unsigned arpping_ms) { struct dhcp_packet packet; uint32_t lease_time_sec; @@ -187,7 +690,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, } else { /* Otherwise, find a free IP */ - packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); + packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms); } if (!packet.yiaddr) { @@ -212,7 +715,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, add_server_options(&packet); addr.s_addr = packet.yiaddr; - bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); + bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); /* send_packet emits error message itself if it detects failure */ send_packet(&packet, /*force_bcast:*/ 0); } @@ -224,7 +727,7 @@ static NOINLINE void send_NAK(struct dhcp_packet *oldpacket) init_packet(&packet, oldpacket, DHCPNAK); - log1("Sending NAK"); + log1("sending %s", "NAK"); send_packet(&packet, /*force_bcast:*/ 1); } @@ -245,7 +748,7 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) add_server_options(&packet); addr.s_addr = yiaddr; - bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); + bb_error_msg("sending ACK to %s", inet_ntoa(addr)); send_packet(&packet, /*force_bcast:*/ 0); p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); @@ -288,12 +791,6 @@ static NOINLINE void send_inform(struct dhcp_packet *oldpacket) send_packet(&packet, /*force_bcast:*/ 0); } - -/* globals */ -struct dyn_lease *g_leases; -/* struct server_config_t server_config is in bb_common_bufsiz1 */ - - int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int udhcpd_main(int argc UNUSED_PARAM, char **argv) { @@ -304,19 +801,22 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) unsigned opt; struct option_set *option; char *str_I = str_I; + const char *str_a = "2000"; + unsigned arpping_ms; IF_FEATURE_UDHCP_PORT(char *str_P;) -#if ENABLE_FEATURE_UDHCP_PORT - SERVER_PORT = 67; - CLIENT_PORT = 68; -#endif + setup_common_bufsiz(); + + IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) + IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 opt_complementary = "vv"; #endif - opt = getopt32(argv, "fSI:v" + opt = getopt32(argv, "fSI:va:" IF_FEATURE_UDHCP_PORT("P:") , &str_I + , &str_a IF_FEATURE_UDHCP_PORT(, &str_P) IF_UDHCP_VERBOSE(, &dhcp_verbose) ); @@ -336,11 +836,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) free(lsa); } #if ENABLE_FEATURE_UDHCP_PORT - if (opt & 16) { /* -P */ + if (opt & 32) { /* -P */ SERVER_PORT = xatou16(str_P); CLIENT_PORT = SERVER_PORT + 1; } #endif + arpping_ms = xatou(str_a); + /* Would rather not do read_config before daemonization - * otherwise NOMMU machines will parse config twice */ read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); @@ -354,7 +856,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) write_pidfile(server_config.pidfile); /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ - bb_info_msg("%s (v"BB_VER") started", applet_name); + bb_error_msg("started, v"BB_VER); option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); server_config.max_lease_sec = DEFAULT_LEASE_TIME; @@ -406,7 +908,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) max_sock = udhcp_sp_fd_set(&rfds, server_socket); if (server_config.auto_time) { - tv.tv_sec = timeout_end - monotonic_sec(); + /* cast to signed is essential if tv_sec is wider than int */ + tv.tv_sec = (int)(timeout_end - monotonic_sec()); tv.tv_usec = 0; } retval = 0; @@ -419,18 +922,18 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) goto continue_with_autotime; } if (retval < 0 && errno != EINTR) { - log1("Error on select"); + log1("error on select"); continue; } switch (udhcp_sp_read(&rfds)) { case SIGUSR1: - bb_info_msg("Received SIGUSR1"); + bb_error_msg("received %s", "SIGUSR1"); write_leases(); /* why not just reset the timeout, eh */ goto continue_with_autotime; case SIGTERM: - bb_info_msg("Received SIGTERM"); + bb_error_msg("received %s", "SIGTERM"); write_leases(); goto ret0; case 0: /* no signal: read a packet */ @@ -443,7 +946,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (bytes < 0) { /* bytes can also be -2 ("bad packet data") */ if (bytes == -1 && errno != EINTR) { - log1("Read error: %s, reopening socket", strerror(errno)); + log1("read error: %s, reopening socket", strerror(errno)); close(server_socket); server_socket = -1; } @@ -478,7 +981,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* Look for a static/dynamic lease */ static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); if (static_lease_nip) { - bb_info_msg("Found static lease: %x", static_lease_nip); + bb_error_msg("found static lease: %x", static_lease_nip); memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); fake_lease.lease_nip = static_lease_nip; fake_lease.expires = 0; @@ -496,13 +999,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) switch (state[0]) { case DHCPDISCOVER: - log1("Received DISCOVER"); + log1("received %s", "DISCOVER"); - send_offer(&packet, static_lease_nip, lease, requested_ip_opt); + send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); break; case DHCPREQUEST: - log1("Received REQUEST"); + log1("received %s", "REQUEST"); /* RFC 2131: o DHCPREQUEST generated during SELECTING state: @@ -627,7 +1130,7 @@ o DHCPREQUEST generated during REBINDING state: * chaddr must be filled in, * ciaddr must be 0 (we do not check this) */ - log1("Received DECLINE"); + log1("received %s", "DECLINE"); if (server_id_opt && requested_ip_opt && lease /* chaddr matches this lease */ @@ -647,7 +1150,7 @@ o DHCPREQUEST generated during REBINDING state: * chaddr must be filled in, * ciaddr must be filled in */ - log1("Received RELEASE"); + log1("received %s", "RELEASE"); if (server_id_opt && lease /* chaddr matches this lease */ && packet.ciaddr == lease->lease_nip @@ -657,7 +1160,7 @@ o DHCPREQUEST generated during REBINDING state: break; case DHCPINFORM: - log1("Received INFORM"); + log1("received %s", "INFORM"); send_inform(&packet); break; } |