* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+//usage:#define udhcpd_trivial_usage
+//usage: "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]"
+//usage:#define udhcpd_full_usage "\n\n"
+//usage: "DHCP server\n"
+//usage: "\n -f Run in foreground"
+//usage: "\n -S Log to syslog too"
+//usage: "\n -I ADDR Local address"
+//usage: IF_FEATURE_UDHCP_PORT(
+//usage: "\n -P N Use port N (default 67)"
+//usage: )
+
#include <syslog.h>
#include "common.h"
#include "dhcpc.h"
unsigned num_ips;
unsigned opt;
struct option_set *option;
+ char *str_I = str_I;
IF_FEATURE_UDHCP_PORT(char *str_P;)
#if ENABLE_FEATURE_UDHCP_PORT
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
opt_complementary = "vv";
#endif
- opt = getopt32(argv, "fSv"
- IF_FEATURE_UDHCP_PORT("P:", &str_P)
-#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
- , &dhcp_verbose
-#endif
+ opt = getopt32(argv, "fSI:v"
+ IF_FEATURE_UDHCP_PORT("P:")
+ , &str_I
+ IF_FEATURE_UDHCP_PORT(, &str_P)
+ IF_UDHCP_VERBOSE(, &dhcp_verbose)
);
if (!(opt & 1)) { /* no -f */
bb_daemonize_or_rexec(0, argv);
openlog(applet_name, LOG_PID, LOG_DAEMON);
logmode |= LOGMODE_SYSLOG;
}
+ if (opt & 4) { /* -I */
+ len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET);
+ server_config.server_nip = lsa->u.sin.sin_addr.s_addr;
+ free(lsa);
+ }
#if ENABLE_FEATURE_UDHCP_PORT
- if (opt & 8) { /* -P */
+ if (opt & 16) { /* -P */
SERVER_PORT = xatou16(str_P);
CLIENT_PORT = SERVER_PORT + 1;
}
if (udhcp_read_interface(server_config.interface,
&server_config.ifindex,
- &server_config.server_nip,
+ (server_config.server_nip == 0 ? &server_config.server_nip : NULL),
server_config.server_mac)
) {
retval = 1;
/* Setup the signal pipe */
udhcp_sp_setup();
+ continue_with_autotime:
timeout_end = monotonic_sec() + server_config.auto_time;
while (1) { /* loop until universe collapses */
fd_set rfds;
}
if (retval == 0) {
write_leases();
- timeout_end = monotonic_sec() + server_config.auto_time;
- continue;
+ goto continue_with_autotime;
}
if (retval < 0 && errno != EINTR) {
log1("Error on select");
bb_info_msg("Received SIGUSR1");
write_leases();
/* why not just reset the timeout, eh */
- timeout_end = monotonic_sec() + server_config.auto_time;
- continue;
+ goto continue_with_autotime;
case SIGTERM:
bb_info_msg("Received SIGTERM");
+ write_leases();
goto ret0;
case 0: /* no signal: read a packet */
break;
/* Get SERVER_ID if present */
server_id_opt = udhcp_get_option(&packet, DHCP_SERVER_ID);
if (server_id_opt) {
- uint32_t server_id_net;
- move_from_unaligned32(server_id_net, server_id_opt);
- if (server_id_net != server_config.server_nip) {
+ uint32_t server_id_network_order;
+ move_from_unaligned32(server_id_network_order, server_id_opt);
+ if (server_id_network_order != server_config.server_nip) {
/* client talks to somebody else */
log1("server ID doesn't match, ignoring");
continue;
send_ACK(&packet, lease->lease_nip);
break;
}
- if (server_id_opt) {
- /* client was talking specifically to us.
- * "No, we don't have this IP for you". */
+ /* No lease for this MAC, or lease IP != requested IP */
+
+ if (server_id_opt /* client is in SELECTING state */
+ || requested_ip_opt /* client is in INIT-REBOOT state */
+ ) {
+ /* "No, we don't have this IP for you" */
send_NAK(&packet);
- }
+ } /* else: client is in RENEWING or REBINDING, do not answer */
+
break;
case DHCPDECLINE: