Mercurial > hg > dhcpcd
changeset 73:6e7ab19c2475 draft
RFC 2131 is full of confusion regarding MTU it seems as the effective minimum MTU is really 576 or DHCP requests stop working.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Fri, 02 Mar 2007 12:11:46 +0000 |
| parents | 9bf434f2313a |
| children | 5d21af7476c7 |
| files | ChangeLog Makefile dhcp.c dhcp.h interface.c interface.h |
| diffstat | 6 files changed, 66 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Mar 01 10:42:01 2007 +0000 +++ b/ChangeLog Fri Mar 02 12:11:46 2007 +0000 @@ -1,3 +1,7 @@ +dhcpcd-3.0.16 +RFC 2131 is full of confusion regarding MTU it seems as the effective minimum +MTU is really 576 or DHCP requests stop working. + dhcpcd-3.0.15 Fix MTU length checking. We now request MTU from the DHCP server, and if given we set it.
--- a/Makefile Thu Mar 01 10:42:01 2007 +0000 +++ b/Makefile Fri Mar 02 12:11:46 2007 +0000 @@ -1,6 +1,6 @@ # Should work for both GNU make and BSD make -VERSION = 3.0.15 +VERSION = 3.0.16 CFLAGS ?= -O2 -pipe
--- a/dhcp.c Thu Mar 01 10:42:01 2007 +0000 +++ b/dhcp.c Fri Mar 02 12:11:46 2007 +0000 @@ -123,7 +123,13 @@ { *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; } @@ -601,11 +607,12 @@ 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;
--- a/dhcp.h Thu Mar 01 10:42:01 2007 +0000 +++ b/dhcp.h Fri Mar 02 12:11:46 2007 +0000 @@ -33,6 +33,7 @@ /* Max MTU - defines dhcp option length */ #define MTU_MAX 1500 +#define MTU_MIN 576 /* UDP port numbers for DHCP */ #define DHCP_SERVER_PORT 67 @@ -163,7 +164,6 @@ #define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN - DHCP_UDP_LEN \ - DHCP_RESERVE_LEN) - typedef struct dhcpmessage_t { unsigned char op; /* message type */
--- a/interface.c Thu Mar 01 10:42:01 2007 +0000 +++ b/interface.c Fri Mar 02 12:11:46 2007 +0000 @@ -55,6 +55,7 @@ #include <unistd.h> #include "common.h" +#include "dhcp.h" #include "interface.h" #include "logger.h" #include "pathnames.h" @@ -231,6 +232,26 @@ #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) { logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno)); @@ -268,6 +289,32 @@ 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;
--- a/interface.h Thu Mar 01 10:42:01 2007 +0000 +++ b/interface.h Fri Mar 02 12:11:46 2007 +0000 @@ -85,6 +85,7 @@ 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,
