From: Roy Marples Date: Thu, 1 Mar 2007 10:42:01 +0000 (+0000) Subject: Fix MTU length checking. X-Git-Tag: v3.2.3~302 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=644a9ea9af5a3ce488c990460f655595b7f09f4e;p=thirdparty%2Fdhcpcd.git Fix MTU length checking. We now request MTU from the DHCP server, and if given we set it. --- diff --git a/ChangeLog b/ChangeLog index 02df8f6a..7dba477d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +dhcpcd-3.0.15 +Fix MTU length checking. +We now request MTU from the DHCP server, and if given we set it. + dhcpcd-3.0.14 Don't crash with 0 or invalid length DHCP options, reported by Stefan de Konink. diff --git a/Makefile b/Makefile index 9925482e..3b48d27f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Should work for both GNU make and BSD make -VERSION = 3.0.14 +VERSION = 3.0.15 CFLAGS ?= -O2 -pipe diff --git a/client.c b/client.c index 08373dfd..d780358e 100644 --- a/client.c +++ b/client.c @@ -473,7 +473,7 @@ int dhcp_run (const options_t *options) if (type == DHCP_OFFER) { char *addr = strdup (inet_ntoa (dhcp->address)); - if (dhcp->servername) + if (dhcp->servername[0]) logger (LOG_INFO, "offered %s from %s `%s'", addr, inet_ntoa (dhcp->serveraddress), dhcp->servername); diff --git a/configure.c b/configure.c index 703e929d..21e07387 100644 --- a/configure.c +++ b/configure.c @@ -482,6 +482,9 @@ int configure (const options_t *options, interface_t *iface, return 0; } + if (dhcp->mtu) + set_mtu (iface->name, dhcp->mtu); + if (add_address (iface->name, dhcp->address, dhcp->netmask, dhcp->broadcast) < 0 && errno != EEXIST) return -1; diff --git a/dhcp.c b/dhcp.c index 3af0672c..a116ec1c 100644 --- a/dhcp.c +++ b/dhcp.c @@ -186,6 +186,7 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp, *p++ = DHCP_NISDOMAIN; *p++ = DHCP_NISSERVER; *p++ = DHCP_NTPSERVER; + *p++ = DHCP_MTU; /* These parameters were requested by dhcpcd-2.0 and earlier but we never did anything with them */ /* *p++ = DHCP_DEFAULTIPTTL; @@ -550,15 +551,27 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message) } } +#define LENGTH(_length) \ + if (length != _length) \ + LEN_ERR; #define MIN_LENGTH(_length) \ if (length < _length) \ LEN_ERR; #define MULT_LENGTH(_mult) \ if (length % _mult != 0) \ LEN_ERR; +#define GET_UINT8(_val) \ + LENGTH (sizeof (uint8_t)); \ + memcpy (&_val, p, sizeof (uint8_t)); +#define GET_UINT16(_val) \ + LENGTH (sizeof (uint16_t)); \ + memcpy (&_val, p, sizeof (uint16_t)); #define GET_UINT32(_val) \ - MIN_LENGTH (sizeof (uint32_t)); \ + LENGTH (sizeof (uint32_t)); \ memcpy (&_val, p, sizeof (uint32_t)); +#define GET_UINT16_H(_val) \ + GET_UINT16 (_val); \ + _val = ntohs (_val); #define GET_UINT32_H(_val) \ GET_UINT32 (_val); \ _val = ntohl (_val); @@ -587,13 +600,20 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message) GET_UINT32_H (dhcp->rebindtime); break; case DHCP_MTU: - GET_UINT32_H (dhcp->mtu); + GET_UINT16_H (dhcp->mtu); /* Minimum legal mtu is 68 */ - if (dhcp->mtu > 0 && dhcp->mtu < 68) - dhcp->mtu = 68; + if (dhcp->mtu < 68) + { + logger (LOG_ERR, "minimum legal MTU is 68"); + dhcp->mtu = 68; + } break; + #undef GET_UINT32_H #undef GET_UINT32 +#undef GET_UINT16_H +#undef GET_UINT16 +#undef GET_UINT8 #define GETSTR(_var) \ MIN_LENGTH (sizeof (char)); \ @@ -680,6 +700,7 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message) } break; +#undef LENGTH #undef MIN_LENGTH #undef MULT_LENGTH diff --git a/interface.c b/interface.c index 97f8f01d..7b314a7d 100644 --- a/interface.c +++ b/interface.c @@ -268,6 +268,31 @@ interface_t *read_interface (const char *ifname, int metric) return iface; } +int set_mtu (const char *ifname, short int mtu) +{ + 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)); + logger (LOG_DEBUG, "setting MTU to %d", mtu); + strcpy (ifr.ifr_name, ifname); + ifr.ifr_mtu = mtu; + r = ioctl (s, SIOCSIFMTU, &ifr); + close (s); + + if (r < 0) + logger (LOG_ERR, "ioctl SIOCSIFMTU: %s", strerror (errno)); + + return (r == 0 ? 0 : -1); +} + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) \ || defined(__APPLE__) static int do_address (const char *ifname, struct in_addr address, diff --git a/interface.h b/interface.h index b7fb5ae7..198c61d0 100644 --- a/interface.h +++ b/interface.h @@ -85,6 +85,7 @@ typedef struct interface_t void free_address (address_t *addresses); void free_route (route_t *routes); interface_t *read_interface (const char *ifname, int metric); +int set_mtu (const char *ifname, short int mtu); int add_address (const char *ifname, struct in_addr address, struct in_addr netmask, struct in_addr broadcast);