if (ifp == NULL)
return;
+ if (!if_valid_hwaddr(hwaddr, hwlen))
+ hwlen = 0;
+
if (hwlen > sizeof(ifp->hwaddr)) {
errno = ENOBUFS;
logerr("%s: %s", __func__, ifp->name);
}
}
+bool
+if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen)
+{
+ size_t i;
+ bool all_zeros, all_ones;
+
+ all_zeros = all_ones = true;
+ for (i = 0; i < hwlen; i++) {
+ if (hwaddr[i] != 0x00)
+ all_zeros = false;
+ if (hwaddr[i] != 0xff)
+ all_ones = false;
+ if (!all_zeros && !all_ones)
+ return true;
+ }
+ return false;
+}
+
struct if_head *
if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
{
ifp->index = if_nametoindex(ifp->name);
#endif
+ /* Ensure hardware address is valid. */
+ if (!if_valid_hwaddr(ifp->hwaddr, ifp->hwlen))
+ ifp->hwlen = 0;
+
/* We only work on ethernet by default */
if (ifp->family != ARPHRD_ETHER) {
if ((argc == 0 || argc == -1) &&
int if_setflag(struct interface *ifp, short flag);
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING))
+bool if_valid_hwaddr(const uint8_t *, size_t);
struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *);
struct interface *if_find(struct if_head *, const char *);
struct interface *if_findindex(struct if_head *, unsigned int);
{
struct rs_state *state;
struct nd_router_solicit *rs;
- struct nd_opt_hdr *nd;
state = RS_STATE(ifp);
free(state->rs);
- state->rslen = sizeof(*rs) + (size_t)ROUNDUP8(ifp->hwlen + 2);
+ state->rslen = sizeof(*rs);
+ if (ifp->hwlen != 0)
+ state->rslen += (size_t)ROUNDUP8(ifp->hwlen + 2);
state->rs = calloc(1, state->rslen);
if (state->rs == NULL)
return -1;
rs->nd_rs_code = 0;
rs->nd_rs_cksum = 0;
rs->nd_rs_reserved = 0;
- nd = (struct nd_opt_hdr *)(state->rs + sizeof(*rs));
- nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
- nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3);
- memcpy(nd + 1, ifp->hwaddr, ifp->hwlen);
+
+ if (ifp->hwlen != 0) {
+ struct nd_opt_hdr *nd;
+
+ nd = (struct nd_opt_hdr *)(state->rs + sizeof(*rs));
+ nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
+ nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3);
+ memcpy(nd + 1, ifp->hwaddr, ifp->hwlen);
+ }
return 0;
}