__CTASSERT(sizeof(struct ip) == 20);
__CTASSERT(sizeof(struct udphdr) == 8);
__CTASSERT(sizeof(struct bootp) == 300);
+#define IP_UDP_SIZE sizeof(struct ip) + sizeof(struct udphdr)
+#define BOOTP_MIN_MTU IP_UDP_SIZE + sizeof(struct bootp)
struct dhcp_op {
uint8_t value;
get_option_uint16(ifp->ctx, &mtu,
state->new, state->new_len, DHO_MTU) == -1)
return 0;
+ if (mtu < IPV4_MMTU)
+ return IPV4_MMTU;
return mtu;
}
uint8_t *auth, auth_len;
#endif
- if ((mtu = if_getmtu(ifp)) == -1)
+ /* We could take the DHCPv6 approach and work out the
+ * message length up front rather than this big hammer approach. */
+ if ((mtu = if_getmtu(ifp)) == -1) {
logerr("%s: if_getmtu", ifp->name);
- else if (mtu < MTU_MIN) {
- if (if_setmtu(ifp, MTU_MIN) == -1)
- logerr("%s: if_setmtu", ifp->name);
- mtu = MTU_MIN;
+ return -1;
+ }
+ if ((size_t)mtu < BOOTP_MIN_MTU) {
+ logerr("%s: interface mtu is too small (%d<%zu)",
+ ifp->name, mtu, BOOTP_MIN_MTU);
+ return -1;
}
- if (ifo->options & DHCPCD_BOOTP)
- bootp = calloc(1, sizeof (*bootp));
- else
+ if (ifo->options & DHCPCD_BOOTP) {
+ bootp = calloc(1, sizeof(*bootp));
+ } else {
/* Make the maximal message we could send */
- bootp = calloc(1, (size_t)(mtu - IP_UDP_SIZE));
+ bootp = calloc(1, (size_t)mtu - IP_UDP_SIZE);
+ }
if (bootp == NULL)
return -1;
return sizeof(*bootp);
p = bootp->vend;
- e = (uint8_t *)bootp + (mtu - IP_UDP_SIZE) - 1; /* -1 for DHO_END */
+ e = (uint8_t *)bootp + ((size_t)mtu - IP_UDP_SIZE - 1/* DHO_END */);
ul = htonl(MAGIC_COOKIE);
memcpy(p, &ul, sizeof(ul));
AREA_CHECK(2);
*p++ = DHO_MAXMESSAGESIZE;
*p++ = 2;
- sz = htons((uint16_t)(mtu - IP_UDP_SIZE));
+ sz = htons((uint16_t)((size_t)mtu - IP_UDP_SIZE));
memcpy(p, &sz, 2);
p += 2;
}
}
int
-if_domtu(const struct interface *ifp, short int mtu)
+if_getmtu(const struct interface *ifp)
{
- int r;
- struct ifreq ifr;
-
#ifdef __sun
- if (mtu == 0)
- return if_mtu_os(ifp);
-#endif
+ return if_mtu_os(ifp);
+#else
+ struct ifreq ifr = { .ifr_mtu = 0 };
- memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
- ifr.ifr_mtu = mtu;
- if (mtu != 0)
- r = if_ioctl(ifp->ctx, SIOCSIFMTU, &ifr, sizeof(ifr));
- else
- r = pioctl(ifp->ctx, SIOCGIFMTU, &ifr, sizeof(ifr));
-
- if (r == -1)
+ if (pioctl(ifp->ctx, SIOCGIFMTU, &ifr, sizeof(ifr)) == -1)
return -1;
return ifr.ifr_mtu;
+#endif
}
#ifdef ALIAS_ADDR
struct interface *if_findindex(struct if_head *, unsigned int);
struct interface *if_loopback(struct dhcpcd_ctx *);
void if_free(struct interface *);
-int if_domtu(const struct interface *, short int);
-#define if_getmtu(ifp) if_domtu((ifp), 0)
-#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
+int if_getmtu(const struct interface *);
int if_carrier(struct interface *, const void *);
bool if_roaming(struct interface *);