Mercurial > hg > dhcpcd
changeset 9:35e4fcebda6b draft
Linux systems without glibc-2.3 don't have getifaddrs, so we define our own.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sun, 03 Dec 2006 10:28:57 +0000 |
| parents | 62a033e6d41d |
| children | 62175745d80a |
| files | ChangeLog Makefile interface.c |
| diffstat | 3 files changed, 114 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Dec 01 20:08:33 2006 +0000 +++ b/ChangeLog Sun Dec 03 10:28:57 2006 +0000 @@ -1,8 +1,10 @@ +dhcpcd-3.0.2 +Linux systems without glibc-2.3 don't have getifaddrs, so we define our own. Changed the default timeout to 20 seconds, allowing hme Sparc drivers to work. Set the rfds correctly so we can get a reply after re-sending a request. Set the seconds elasped and maximum message size correctly in DHCP messages. Now compiles on Linux 2.4 kernels. -xmalloc dhcp objects so we can swap pointer around easily. +xmalloc dhcp objects so we can swap the pointers around easily. dhcpcd-3.0.1 Quote all vars in the info file.
--- a/Makefile Fri Dec 01 20:08:33 2006 +0000 +++ b/Makefile Sun Dec 03 10:28:57 2006 +0000 @@ -1,6 +1,6 @@ # Should work for both GNU make and BSD mke -VERSION = 3.0.2_pre1 +VERSION = 3.0.2 INSTALL ?= install CFLAGS ?= -Wall -O2 -pedantic -std=gnu99
--- a/interface.c Fri Dec 01 20:08:33 2006 +0000 +++ b/interface.c Sun Dec 03 10:28:57 2006 +0000 @@ -29,19 +29,26 @@ /* Netlink suff */ #ifdef __linux__ #include <asm/types.h> /* Needed for 2.4 kernels */ +#include <features.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <netinet/ether.h> #include <netpacket/packet.h> +/* Only glibc-2.3 ships with ifaddrs.h */ +#if defined (__GLIBC__) && defined (__GLIBC_PREREQ) && __GLIBC_PREREQ (2,3) +#define HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif #else #include <net/if_dl.h> #include <net/if_types.h> #include <net/route.h> #include <netinet/in.h> -#endif /* __linux__ */ +#define HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif #include <errno.h> -#include <ifaddrs.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -84,6 +91,8 @@ } } + + interface_t *read_interface (const char *ifname, int metric) { if (! ifname) @@ -94,6 +103,7 @@ interface_t *iface; unsigned char hwaddr[ETHER_ADDR_LEN]; +#ifndef __linux__ struct ifaddrs *ifap; struct ifaddrs *p; @@ -104,25 +114,16 @@ { if (strcmp (p->ifa_name, ifname) != 0) continue; -#ifdef __linux__ - struct sockaddr_ll *sll = (struct sockaddr_ll*) p->ifa_addr; - if (p->ifa_addr->sa_family != AF_PACKET - || sll->sll_hatype != ARPHRD_ETHER) -#else - struct sockaddr_dl *sdl = (struct sockaddr_dl *) p->ifa_addr; + + struct sockaddr_dl *sdl = (struct sockaddr_dl *) p->ifa_addr; if (p->ifa_addr->sa_family != AF_LINK || sdl->sdl_type != IFT_ETHER) -#endif { logger (LOG_ERR, "not Ethernet"); freeifaddrs (ifap); return NULL; } -#ifdef __linux__ - memcpy (hwaddr, sll->sll_addr, ETHER_ADDR_LEN); -#else memcpy (hwaddr, sdl->sdl_data + sdl->sdl_nlen, ETHER_ADDR_LEN); -#endif break; } freeifaddrs (ifap); @@ -132,18 +133,33 @@ logger (LOG_ERR, "could not find interface %s", ifname); return NULL; } +#endif memset (&ifr, 0, sizeof (struct ifreq)); strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { logger (LOG_ERR, "socket: %s", strerror (errno)); return NULL; } -#ifndef __linux__ +#ifdef __linux__ + if (ioctl (s, SIOCGIFHWADDR, &ifr) <0) + { + logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror(errno)); + close (s); + return NULL; + } + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) + { + logger (LOG_ERR, "interface is not Ethernet"); + close (s); + return NULL; + } + memcpy (&hwaddr, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); +#else ifr.ifr_metric = metric; - if (ioctl(s, SIOCSIFMETRIC, &ifr) < 0) + if (ioctl (s, SIOCSIFMETRIC, &ifr) < 0) { logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno)); close (s); @@ -637,32 +653,6 @@ return (do_address (ifname, address, t, t, 1)); } -/* This should work on all platforms */ -int flush_addresses (const char *ifname) -{ - if (! ifname) - return -1; - - struct ifaddrs *ifap; - struct ifaddrs *p; - - if (getifaddrs (&ifap) != 0) - return -1; - - for (p = ifap; p; p = p->ifa_next) - { - if (strcmp (p->ifa_name, ifname) != 0) - continue; - - struct sockaddr_in *sin = (struct sockaddr_in*) p->ifa_addr; - if (sin->sin_family == AF_INET) - del_address (ifname, sin->sin_addr); - } - freeifaddrs (ifap); - - return 0; -} - int add_route (const char *ifname, struct in_addr destination, struct in_addr netmask, struct in_addr gateway, int metric) { @@ -681,3 +671,81 @@ return (do_route (ifname, destination, netmask, gateway, metric, 0, 1)); } +#ifdef HAVE_IFADDRS_H +int flush_addresses (const char *ifname) +{ + if (! ifname) + return -1; + + struct ifaddrs *ifap; + struct ifaddrs *p; + + if (getifaddrs (&ifap) != 0) + return -1; + + int retval = 0; + for (p = ifap; p; p = p->ifa_next) + { + if (strcmp (p->ifa_name, ifname) != 0) + continue; + + struct sockaddr_in *sin = (struct sockaddr_in*) p->ifa_addr; + if (sin->sin_family == AF_INET) + if (del_address (ifname, sin->sin_addr) < 0) + retval = -1; + } + freeifaddrs (ifap); + + return retval; +} +#else +int flush_addresses (const char *ifname) +{ + int s; + if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + logger (LOG_ERR, "socket: %s", strerror (errno)); + return -1; + } + + struct ifconf ifc; + memset (&ifc, 0, sizeof (struct ifconf)); + ifc.ifc_buf = NULL; + if (ioctl (s, SIOCGIFCONF, &ifc) < 0) + { + logger (LOG_ERR, "ioctl SIOCGIFCONF: %s", strerror (errno)); + close (s); + } + + void *ifrs = xmalloc (ifc.ifc_len); + ifc.ifc_buf = ifrs; + if (ioctl (s, SIOCGIFCONF, &ifc) < 0) + { + logger (LOG_ERR, "ioctl SIOCGIFCONF: %s", strerror (errno)); + close (s); + free (ifrs); + return -1; + } + + close (s); + + int nifs = ifc.ifc_len / sizeof (struct ifreq); + struct ifreq *ifr = ifrs; + int retval = 0; + int i; + for (i = 0; i < nifs; i++) + { + if (ifr->ifr_addr.sa_family != AF_INET + || strcmp (ifname, ifr->ifr_name) != 0) + continue; + + struct sockaddr_in *in = (struct sockaddr_in *) &ifr->ifr_addr; + if (del_address (ifname, in->sin_addr) < 0) + retval = -1; + ifr++; + } + + free (ifrs); + return retval; +} +#endif
