* Copyright 2013 Kyungwan Han <asura321@gmail.com>
*
* Not in SUSv4.
-USE_DHCP(NEWTOY(dhcp, "V:H:F:x*r:O*A#<0T#<0t#<0s:p:i:SBRCaovqnbf", TOYFLAG_SBIN|TOYFLAG_ROOTONLY))
+USE_DHCP(NEWTOY(dhcp, "V:H:F:x*r:O*A#<0T#<0t#<0s:p:i:SBRCaovqnbfW", TOYFLAG_SBIN|TOYFLAG_ROOTONLY))
config DHCP
bool "dhcp"
default n
help
- usage: dhcp [-fbnqvoCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]
+ usage: dhcp [-fbnqvoCRBW] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]
[-H HOSTNAME] [-V VENDOR] [-x OPT:VAL] [-O OPT]
Configure network dynamicaly using DHCP.
-V VENDOR Vendor identifier (default 'toybox VERSION')
-C Don't send MAC as client identifier
-v Verbose
+ -W Workarround for buggy APs when DHCPDISCOVER/DHCPREQUEST set/unset BOOTP broadcast flag
Signals:
USR1 Renew current lease
#define STATE_RENEW_REQUESTED 5
#define STATE_RELEASED 6
-#define BOOTP_BROADCAST 0x8000
+#define BOOTP_BROADCAST_ON 0x8000
+#define BOOTP_BROADCAST_OFF 0x0000
#define DHCP_MAGIC 0x63825363
#define DHCP_REQUEST 1
static uint32_t xid;
static dhcpc_state_t *state;
static struct fd_pair sigfd;
+static int broadcast_flag;
uint8_t bmacaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int set = 1;
uint8_t infomode = LOG_CONSOLE;
// Handle the message specific settings
switch (msgtype) {
case DHCPDISCOVER: // Broadcast DISCOVER message to all servers
- state->pdhcp.flags = htons(BOOTP_BROADCAST); // Broadcast bit.
+ if ((flag_chk(FLAG_W) && !broadcast_flag))
+ state->pdhcp.flags = htons(BOOTP_BROADCAST_OFF); // Broadcast bit unset.
+ else
+ state->pdhcp.flags = htons(BOOTP_BROADCAST_ON); // Broadcast bit set.
if (flag_chk(FLAG_r)) {
inet_aton(TT.req_ip, &rqsd);
pend = dhcpc_addreqipaddr(&rqsd, pend);
if (flag_chk(FLAG_x)) pend = set_xopt(pend);
break;
case DHCPREQUEST: // Send REQUEST message to the server that sent the *first* OFFER
- state->pdhcp.flags = htons(BOOTP_BROADCAST); // Broadcast bit.
+ if ((flag_chk(FLAG_W) && !broadcast_flag) && server != INADDR_BROADCAST)
+ state->pdhcp.flags = htons(BOOTP_BROADCAST_OFF); // Broadcast bit unset.
+ else
+ state->pdhcp.flags = htons(BOOTP_BROADCAST_ON); // Broadcast bit set.
if (state->status == STATE_RENEWING) memcpy(&state->pdhcp.ciaddr, &state->ipaddr.s_addr, 4);
pend = dhcpc_addmaxsize(pend, htons(sizeof(dhcp_raw_t)));
rqsd.s_addr = htonl(server);
if (!packets) xid = getxid();
run_script(NULL, "deconfig");
infomsg(infomode, "Sending discover...");
+ broadcast_flag = (broadcast_flag + 1) % 2;
dhcpc_sendmsg(DHCPDISCOVER);
server = 0;
timeout = flag_get(FLAG_T, TT.timeout, 3);