{
*p++ = DHCP_MAXMESSAGESIZE;
*p++ = 2;
- sz = htons (sizeof (dhcpmessage_t));
+ sz = get_mtu (iface->name);
+ if (sz < MTU_MIN)
+ {
+ if (set_mtu (iface->name, MTU_MIN) == 0)
+ sz = MTU_MIN;
+ }
+ sz = htons (sz);
memcpy (p, &sz, 2);
p += 2;
}
break;
case DHCP_MTU:
GET_UINT16_H (dhcp->mtu);
- /* Minimum legal mtu is 68 */
- if (dhcp->mtu < 68)
+ /* Minimum legal mtu is 68 accoridng to RFC 2132.
+ In practise it's 576 (minimum maximum message size) */
+ if (dhcp->mtu < MTU_MIN)
{
- logger (LOG_ERR, "minimum legal MTU is 68");
- dhcp->mtu = 68;
+ logger (LOG_ERR, "given MTU %d is too low, minium is %d", dhcp->mtu, MTU_MIN);
+ dhcp->mtu = MTU_MIN;
}
break;
/* Max MTU - defines dhcp option length */
#define MTU_MAX 1500
+#define MTU_MIN 576
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67
#define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN - DHCP_UDP_LEN \
- DHCP_RESERVE_LEN)
-
typedef struct dhcpmessage_t
{
unsigned char op; /* message type */
#include <unistd.h>
#include "common.h"
+#include "dhcp.h"
#include "interface.h"
#include "logger.h"
#include "pathnames.h"
}
#endif
+ strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl(s, SIOCGIFMTU, &ifr) < 0)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
+ close (s);
+ return NULL;
+ }
+ if (ifr.ifr_mtu < MTU_MIN)
+ {
+ logger (LOG_DEBUG, "MTU of %d is too low, setting to %d", ifr.ifr_mtu, MTU_MIN);
+ ifr.ifr_mtu = MTU_MIN;
+ strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
+ {
+ logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s", strerror (errno));
+ close (s);
+ return NULL;
+ }
+ }
+
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
{
return iface;
}
+int get_mtu (const char *ifname)
+{
+ struct ifreq ifr;
+ int r;
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ logger (LOG_ERR, "socket: %s", strerror (errno));
+ return (-1);
+ }
+
+ memset (&ifr, 0, sizeof (struct ifreq));
+ strcpy (ifr.ifr_name, ifname);
+ r = ioctl (s, SIOCGIFMTU, &ifr);
+ close (s);
+
+ if (r < 0)
+ {
+ logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno));
+ return (-1);
+ }
+
+ return (ifr.ifr_mtu);
+}
+
int set_mtu (const char *ifname, short int mtu)
{
struct ifreq ifr;
void free_address (address_t *addresses);
void free_route (route_t *routes);
interface_t *read_interface (const char *ifname, int metric);
+int get_mtu (const char *ifname);
int set_mtu (const char *ifname, short int mtu);
int add_address (const char *ifname, struct in_addr address,