From 4e1b9faba7503f99ee2fbcd7458f66ade42fa309 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 1 Sep 2011 09:31:39 +0200 Subject: tried to clean the git. deleted old unused files and folders. moved customdhcpcd and LogReceiver to the fbgui folder --- workspace/networkDiscovery/dhcpcd/interface.c | 1060 ------------------------- 1 file changed, 1060 deletions(-) delete mode 100644 workspace/networkDiscovery/dhcpcd/interface.c (limited to 'workspace/networkDiscovery/dhcpcd/interface.c') diff --git a/workspace/networkDiscovery/dhcpcd/interface.c b/workspace/networkDiscovery/dhcpcd/interface.c deleted file mode 100644 index d2ff8d6..0000000 --- a/workspace/networkDiscovery/dhcpcd/interface.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * dhcpcd - DHCP client daemon - * Copyright 2006-2008 Roy Marples - * All rights reserved - - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include - -/* Netlink suff */ -#ifdef __linux__ -#include /* Needed for 2.4 kernels */ -#include -#include -#include -#include -#else -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "common.h" -#include "dhcp.h" -#include "interface.h" -#include "logger.h" - -void free_address (struct address_head *addresses) -{ - address_t *p; - address_t *n; - - if (! addresses) - return; - - p = STAILQ_FIRST (addresses); - while (p) { - n = STAILQ_NEXT (p, entries); - free (p); - p = n; - } - free (addresses); -} - -void free_route (struct route_head *routes) -{ - route_t *p; - route_t *n; - - if (! routes) - return; - - p = STAILQ_FIRST (routes); - while (p) { - n = STAILQ_NEXT (p, entries); - free (p); - p = n; - } - free (routes); -} - -int inet_ntocidr (struct in_addr address) -{ - int cidr = 0; - uint32_t mask = htonl (address.s_addr); - - while (mask) { - cidr++; - mask <<= 1; - } - - return (cidr); -} - -int inet_cidrtoaddr (int cidr, struct in_addr *addr) { - int ocets; - - if (cidr < 0 || cidr > 32) { - errno = EINVAL; - return (-1); - } - ocets = (cidr + 7) / 8; - - memset (addr, 0, sizeof (*addr)); - if (ocets > 0) { - memset (&addr->s_addr, 255, (size_t) ocets - 1); - memset ((unsigned char *) &addr->s_addr + (ocets - 1), - (256 - (1 << (32 - cidr) % 8)), 1); - } - - return (0); -} - -uint32_t get_netmask (uint32_t addr) -{ - uint32_t dst; - - if (addr == 0) - return (0); - - dst = htonl (addr); - if (IN_CLASSA (dst)) - return (ntohl (IN_CLASSA_NET)); - if (IN_CLASSB (dst)) - return (ntohl (IN_CLASSB_NET)); - if (IN_CLASSC (dst)) - return (ntohl (IN_CLASSC_NET)); - - return (0); -} - -char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen) -{ - static char buffer[(HWADDR_LEN * 3) + 1]; - char *p = buffer; - size_t i; - - for (i = 0; i < hwlen && i < HWADDR_LEN; i++) { - if (i > 0) - *p ++= ':'; - p += snprintf (p, 3, "%.2x", hwaddr[i]); - } - - *p ++= '\0'; - - return (buffer); -} - -size_t hwaddr_aton (unsigned char *buffer, const char *addr) -{ - char c[3]; - const char *p = addr; - unsigned char *bp = buffer; - size_t len = 0; - - c[2] = '\0'; - while (*p) { - c[0] = *p++; - c[1] = *p++; - /* Ensure that next data is EOL or a seperator with data */ - if (! (*p == '\0' || (*p == ':' && *(p + 1) != '\0'))) { - errno = EINVAL; - return (0); - } - /* Ensure that digits are hex */ - if (isxdigit ((int) c[0]) == 0 || isxdigit ((int) c[1]) == 0) { - errno = EINVAL; - return (0); - } - p++; - if (bp) - *bp++ = (unsigned char) strtol (c, NULL, 16); - else - len++; - } - - if (bp) - return (bp - buffer); - return (len); -} - -static int _do_interface (const char *ifname, - _unused unsigned char *hwaddr, _unused size_t *hwlen, - struct in_addr *addr, - bool flush, bool get) -{ - int s; - struct ifconf ifc; - int retval = 0; - int len = 10 * sizeof (struct ifreq); - int lastlen = 0; - char *p; - - if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return -1; - } - - /* Not all implementations return the needed buffer size for - * SIOGIFCONF so we loop like so for all until it works */ - memset (&ifc, 0, sizeof (ifc)); - for (;;) { - ifc.ifc_len = len; - ifc.ifc_buf = xmalloc ((size_t) len); - if (ioctl (s, SIOCGIFCONF, &ifc) == -1) { - if (errno != EINVAL || lastlen != 0) { - logger (LOG_ERR, "ioctl SIOCGIFCONF: %s", - strerror (errno)); - close (s); - free (ifc.ifc_buf); - return -1; - } - } else { - if (ifc.ifc_len == lastlen) - break; - lastlen = ifc.ifc_len; - } - - free (ifc.ifc_buf); - ifc.ifc_buf = NULL; - len *= 2; - } - - for (p = ifc.ifc_buf; p < ifc.ifc_buf + ifc.ifc_len;) { - union { - char *buffer; - struct ifreq *ifr; - } ifreqs; - struct sockaddr_in address; - struct ifreq *ifr; - - /* Cast the ifc buffer to an ifreq cleanly */ - ifreqs.buffer = p; - ifr = ifreqs.ifr; - -#ifdef __linux__ - p += sizeof (*ifr); -#else - p += offsetof (struct ifreq, ifr_ifru) + ifr->ifr_addr.sa_len; -#endif - - if (strcmp (ifname, ifr->ifr_name) != 0) - continue; - -#ifdef AF_LINK - if (hwaddr && hwlen && ifr->ifr_addr.sa_family == AF_LINK) { - struct sockaddr_dl sdl; - - memcpy (&sdl, &ifr->ifr_addr, sizeof (sdl)); - *hwlen = sdl.sdl_alen; - memcpy (hwaddr, sdl.sdl_data + sdl.sdl_nlen, - (size_t) sdl.sdl_alen); - retval = 1; - break; - } -#endif - - if (ifr->ifr_addr.sa_family == AF_INET) { - memcpy (&address, &ifr->ifr_addr, sizeof (address)); - if (flush) { - struct sockaddr_in netmask; - - if (ioctl (s, SIOCGIFNETMASK, ifr) == -1) { - logger (LOG_ERR, - "ioctl SIOCGIFNETMASK: %s", - strerror (errno)); - continue; - } - memcpy (&netmask, &ifr->ifr_addr, - sizeof (netmask)); - - if (del_address (ifname, - address.sin_addr, - netmask.sin_addr) == -1) - retval = -1; - } else if (get) { - addr->s_addr = address.sin_addr.s_addr; - retval = 1; - break; - } else if (address.sin_addr.s_addr == addr->s_addr) { - retval = 1; - break; - } - } - - } - - close (s); - free (ifc.ifc_buf); - return retval; -} - -interface_t *read_interface (const char *ifname, _unused int metric) -{ - int s; - struct ifreq ifr; - interface_t *iface = NULL; - unsigned char *hwaddr = NULL; - size_t hwlen = 0; - sa_family_t family = 0; - unsigned short mtu; -#ifdef __linux__ - char *p; -#endif - - if (! ifname) - return NULL; - - memset (&ifr, 0, sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - - if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return NULL; - } - -#ifdef __linux__ - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl (s, SIOCGIFHWADDR, &ifr) == -1) { - logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror (errno)); - goto exit; - } - - switch (ifr.ifr_hwaddr.sa_family) { - case ARPHRD_ETHER: - case ARPHRD_IEEE802: - hwlen = ETHER_ADDR_LEN; - break; - case ARPHRD_IEEE1394: - hwlen = EUI64_ADDR_LEN; - case ARPHRD_INFINIBAND: - hwlen = INFINIBAND_ADDR_LEN; - break; - default: - logger (LOG_ERR, - "interface is not Ethernet, FireWire, " \ - "InfiniBand or Token Ring"); - goto exit; - } - - hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN); - memcpy (hwaddr, ifr.ifr_hwaddr.sa_data, hwlen); - family = ifr.ifr_hwaddr.sa_family; -#else - ifr.ifr_metric = metric; - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl (s, SIOCSIFMETRIC, &ifr) == -1) { - logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno)); - goto exit; - } - - hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN); - if (_do_interface (ifname, hwaddr, &hwlen, NULL, false, false) != 1) { - logger (LOG_ERR, "could not find interface %s", ifname); - goto exit; - } - - family = ARPHRD_ETHER; -#endif - - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl (s, SIOCGIFMTU, &ifr) == -1) { - logger (LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror (errno)); - goto exit; - } - - 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; - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl (s, SIOCSIFMTU, &ifr) == -1) { - logger (LOG_ERR, "ioctl SIOCSIFMTU,: %s", - strerror (errno)); - goto exit; - } - } - mtu = ifr.ifr_mtu; - - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); -#ifdef __linux__ - /* We can only bring the real interface up */ - if ((p = strchr (ifr.ifr_name, ':'))) - *p = '\0'; -#endif - if (ioctl (s, SIOCGIFFLAGS, &ifr) == -1) { - logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno)); - goto exit; - } - - if (! (ifr.ifr_flags & IFF_UP) || ! (ifr.ifr_flags & IFF_RUNNING)) { - ifr.ifr_flags |= IFF_UP | IFF_RUNNING; - if (ioctl (s, SIOCSIFFLAGS, &ifr) != 0) { - logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s", - strerror (errno)); - goto exit; - } - } - - iface = xzalloc (sizeof (*iface)); - strlcpy (iface->name, ifname, IF_NAMESIZE); -#ifdef ENABLE_INFO - snprintf (iface->infofile, PATH_MAX, INFOFILE, ifname); -#endif - memcpy (&iface->hwaddr, hwaddr, hwlen); - iface->hwlen = hwlen; - - iface->family = family; - iface->arpable = ! (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)); - iface->mtu = iface->previous_mtu = mtu; - - logger (LOG_INFO, "hardware address = %s", - hwaddr_ntoa (iface->hwaddr, iface->hwlen)); - - /* 0 is a valid fd, so init to -1 */ - iface->fd = -1; -#ifdef __linux__ - iface->listen_fd = -1; -#endif - -exit: - close (s); - free (hwaddr); - return iface; -} - -int get_mtu (const char *ifname) -{ - struct ifreq ifr; - int r; - int s; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return (-1); - } - - memset (&ifr, 0, sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - r = ioctl (s, SIOCGIFMTU, &ifr); - close (s); - - if (r == -1) { - 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; - int r; - int s; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return (-1); - } - - memset (&ifr, 0, sizeof (ifr)); - logger (LOG_DEBUG, "setting MTU to %d", mtu); - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - r = ioctl (s, SIOCSIFMTU, &ifr); - close (s); - - if (r == -1) - logger (LOG_ERR, "ioctl SIOCSIFMTU: %s", strerror (errno)); - - return (r == 0 ? 0 : -1); -} - -static void log_route (struct in_addr destination, - struct in_addr netmask, - struct in_addr gateway, - _unused int metric, - int change, int del) -{ - char *dstd = xstrdup (inet_ntoa (destination)); - -#ifdef __linux__ -#define METRIC " metric %d" -#else -#define METRIC "" -#endif - - if (gateway.s_addr == destination.s_addr || - gateway.s_addr == INADDR_ANY) - logger (LOG_INFO, "%s route to %s/%d" METRIC, - change ? "changing" : del ? "removing" : "adding", - dstd, inet_ntocidr (netmask) -#ifdef __linux__ - , metric -#endif - ); - else if (destination.s_addr == INADDR_ANY) - logger (LOG_INFO, "%s default route via %s" METRIC, - change ? "changing" : del ? "removing" : "adding", - inet_ntoa (gateway) - -#ifdef __linux__ - , metric -#endif - ); - else - logger (LOG_INFO, "%s route to %s/%d via %s" METRIC, - change ? "changing" : del ? "removing" : "adding", - dstd, inet_ntocidr (netmask), inet_ntoa (gateway) -#ifdef __linux__ - , metric -#endif - ); - - free (dstd); -} - -#if defined(BSD) || defined(__FreeBSD_kernel__) - -/* Darwin doesn't define this for some very odd reason */ -#ifndef SA_SIZE -# define SA_SIZE(sa) \ - ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ - sizeof(long) : \ - 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) -#endif - -static int do_address (const char *ifname, struct in_addr address, - struct in_addr netmask, struct in_addr broadcast, - int del) -{ - int s; - struct ifaliasreq ifa; - - if (! ifname) - return -1; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return -1; - } - - memset (&ifa, 0, sizeof (ifa)); - strlcpy (ifa.ifra_name, ifname, sizeof (ifa.ifra_name)); - -#define ADDADDR(_var, _addr) { \ - union { struct sockaddr *sa; struct sockaddr_in *sin; } _s; \ - _s.sa = &_var; \ - _s.sin->sin_family = AF_INET; \ - _s.sin->sin_len = sizeof (*_s.sin); \ - memcpy (&_s.sin->sin_addr, &_addr, sizeof (_s.sin->sin_addr)); \ -} - - ADDADDR (ifa.ifra_addr, address); - ADDADDR (ifa.ifra_mask, netmask); -if (! del) - ADDADDR (ifa.ifra_broadaddr, broadcast); - -#undef ADDADDR - - if (ioctl (s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa) == -1) { - logger (LOG_ERR, "ioctl %s: %s", - del ? "SIOCDIFADDR" : "SIOCAIFADDR", - strerror (errno)); - close (s); - return -1; - } - -close (s); -return 0; -} - -static int do_route (const char *ifname, - struct in_addr destination, - struct in_addr netmask, - struct in_addr gateway, - int metric, - int change, int del) -{ - int s; - static int seq; - union sockunion { - struct sockaddr sa; - struct sockaddr_in sin; -#ifdef INET6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_dl sdl; - struct sockaddr_storage ss; - } su; - struct rtm - { - struct rt_msghdr hdr; - char buffer[sizeof (su) * 3]; - } rtm; - char *bp = rtm.buffer; - size_t l; - - if (! ifname) - return -1; - - log_route (destination, netmask, gateway, metric, change, del); - - if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return -1; - } - - memset (&rtm, 0, sizeof (rtm)); - - rtm.hdr.rtm_version = RTM_VERSION; - rtm.hdr.rtm_seq = ++seq; - rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD; - rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC; - - /* This order is important */ - rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; - -#define ADDADDR(_addr) \ - memset (&su, 0, sizeof (su)); \ - su.sin.sin_family = AF_INET; \ - su.sin.sin_len = sizeof (su.sin); \ - memcpy (&su.sin.sin_addr, &_addr, sizeof (su.sin.sin_addr)); \ - l = SA_SIZE (&(su.sa)); \ - memcpy (bp, &(su), l); \ - bp += l; - - ADDADDR (destination); - - if (netmask.s_addr == INADDR_BROADCAST || - gateway.s_addr == INADDR_ANY) - { - /* Make us a link layer socket */ - unsigned char *hwaddr; - size_t hwlen = 0; - - if (netmask.s_addr == INADDR_BROADCAST) - rtm.hdr.rtm_flags |= RTF_HOST; - - hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN); - _do_interface (ifname, hwaddr, &hwlen, NULL, false, false); - memset (&su, 0, sizeof (su)); - su.sdl.sdl_len = sizeof (su.sdl); - su.sdl.sdl_family = AF_LINK; - su.sdl.sdl_nlen = strlen (ifname); - memcpy (&su.sdl.sdl_data, ifname, (size_t) su.sdl.sdl_nlen); - su.sdl.sdl_alen = hwlen; - memcpy (((unsigned char *) &su.sdl.sdl_data) + su.sdl.sdl_nlen, - hwaddr, (size_t) su.sdl.sdl_alen); - - l = SA_SIZE (&(su.sa)); - memcpy (bp, &su, l); - bp += l; - free (hwaddr); - } else { - rtm.hdr.rtm_flags |= RTF_GATEWAY; - ADDADDR (gateway); - } - - ADDADDR (netmask); -#undef ADDADDR - - rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; - if (write (s, &rtm, l) == -1) { - /* Don't report error about routes already existing */ - if (errno != EEXIST) - logger (LOG_ERR, "write: %s", strerror (errno)); - close (s); - return -1; - } - - close (s); - return 0; -} - -#elif __linux__ -/* This netlink stuff is overly compex IMO. - * The BSD implementation is much cleaner and a lot less code. - * send_netlink handles the actual transmission so we can work out - * if there was an error or not. */ -#define BUFFERLEN 256 -int send_netlink (struct nlmsghdr *hdr, netlink_callback callback, void *arg) -{ - int s; - pid_t mypid = getpid (); - struct sockaddr_nl nl; - struct iovec iov; - struct msghdr msg; - static unsigned int seq; - char *buffer; - ssize_t bytes; - union - { - char *buffer; - struct nlmsghdr *nlm; - } h; - - if ((s = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { - logger (LOG_ERR, "socket: %s", strerror (errno)); - return -1; - } - - memset (&nl, 0, sizeof (nl)); - nl.nl_family = AF_NETLINK; - if (bind (s, (struct sockaddr *) &nl, sizeof (nl)) == -1) { - logger (LOG_ERR, "bind: %s", strerror (errno)); - close (s); - return -1; - } - - memset (&iov, 0, sizeof (iov)); - iov.iov_base = hdr; - iov.iov_len = hdr->nlmsg_len; - - memset (&msg, 0, sizeof (msg)); - msg.msg_name = &nl; - msg.msg_namelen = sizeof (nl); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - /* Request a reply */ - hdr->nlmsg_flags |= NLM_F_ACK; - hdr->nlmsg_seq = ++seq; - - if (sendmsg (s, &msg, 0) == -1) { - logger (LOG_ERR, "write: %s", strerror (errno)); - close (s); - return -1; - } - - buffer = xzalloc (sizeof (char) * BUFFERLEN); - iov.iov_base = buffer; - - for (;;) { - iov.iov_len = BUFFERLEN; - bytes = recvmsg (s, &msg, 0); - - if (bytes == -1) { - if (errno != EINTR) - logger (LOG_ERR, "recvmsg: %s", - strerror (errno)); - continue; - } - - if (bytes == 0) { - logger (LOG_ERR, "netlink: EOF"); - goto eexit; - } - - if (msg.msg_namelen != sizeof (nl)) { - logger (LOG_ERR, - "netlink: sender address length mismatch"); - goto eexit; - } - - for (h.buffer = buffer; bytes >= (signed) sizeof (*h.nlm); ) { - int len = h.nlm->nlmsg_len; - int l = len - sizeof (*h.nlm); - struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm); - - if (l < 0 || len > bytes) { - if (msg.msg_flags & MSG_TRUNC) - logger (LOG_ERR, "netlink: truncated message"); - else - logger (LOG_ERR, "netlink: malformed message"); - goto eexit; - } - - /* Ensure it's our message */ - if (nl.nl_pid != 0 || - (pid_t) h.nlm->nlmsg_pid != mypid || - h.nlm->nlmsg_seq != seq) - { - /* Next Message */ - bytes -= NLMSG_ALIGN (len); - h.buffer += NLMSG_ALIGN (len); - continue; - } - - /* We get an NLMSG_ERROR back with a code of zero for success */ - if (h.nlm->nlmsg_type != NLMSG_ERROR) { - logger (LOG_ERR, "netlink: unexpected reply %d", - h.nlm->nlmsg_type); - goto eexit; - } - - if ((unsigned) l < sizeof (*err)) { - logger (LOG_ERR, "netlink: error truncated"); - goto eexit; - } - - if (err->error == 0) { - int retval = 0; - - close (s); - if (callback) { - if ((retval = callback (hdr, arg)) == -1) - logger (LOG_ERR, "netlink: callback failed"); - } - free (buffer); - return (retval); - } - - errno = -err->error; - /* Don't report on something already existing */ - if (errno != EEXIST) - logger (LOG_ERR, "netlink: %s", - strerror (errno)); - goto eexit; - } - } - -eexit: - close (s); - free (buffer); - return -1; -} - -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((ptrdiff_t) (nmsg)) + NLMSG_ALIGN ((nmsg)->nlmsg_len))) - -static int add_attr_l(struct nlmsghdr *n, unsigned int maxlen, int type, - const void *data, int alen) -{ - int len = RTA_LENGTH(alen); - struct rtattr *rta; - - if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen) { - logger (LOG_ERR, "add_attr_l: message exceeded bound of %d\n", - maxlen); - return -1; - } - - rta = NLMSG_TAIL (n); - rta->rta_type = type; - rta->rta_len = len; - memcpy (RTA_DATA (rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len); - - return 0; -} - -static int add_attr_32(struct nlmsghdr *n, unsigned int maxlen, int type, - uint32_t data) -{ - int len = RTA_LENGTH (sizeof (data)); - struct rtattr *rta; - - if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen) { - logger (LOG_ERR, "add_attr32: message exceeded bound of %d\n", - maxlen); - return -1; - } - - rta = NLMSG_TAIL (n); - rta->rta_type = type; - rta->rta_len = len; - memcpy (RTA_DATA (rta), &data, sizeof (data)); - n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len; - - return 0; -} - -struct nlma -{ - struct nlmsghdr hdr; - struct ifaddrmsg ifa; - char buffer[64]; -}; - -struct nlmr -{ - struct nlmsghdr hdr; - struct rtmsg rt; - char buffer[256]; -}; - -static int do_address(const char *ifname, - struct in_addr address, struct in_addr netmask, - struct in_addr broadcast, int del) -{ - struct nlma *nlm; - int retval; - - if (!ifname) - return -1; - - nlm = xzalloc (sizeof (*nlm)); - nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg)); - nlm->hdr.nlmsg_flags = NLM_F_REQUEST; - if (! del) - nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR; - if (! (nlm->ifa.ifa_index = if_nametoindex (ifname))) { - logger (LOG_ERR, "if_nametoindex: no index for interface `%s'", - ifname); - free (nlm); - return -1; - } - nlm->ifa.ifa_family = AF_INET; - - nlm->ifa.ifa_prefixlen = inet_ntocidr (netmask); - - /* This creates the aliased interface */ - add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LABEL, - ifname, strlen (ifname) + 1); - - add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_LOCAL, - &address.s_addr, sizeof (address.s_addr)); - if (! del) - add_attr_l (&nlm->hdr, sizeof (*nlm), IFA_BROADCAST, - &broadcast.s_addr, sizeof (broadcast.s_addr)); - - retval = send_netlink (&nlm->hdr, NULL, NULL); - free (nlm); - return retval; -} - -static int do_route (const char *ifname, - struct in_addr destination, - struct in_addr netmask, - struct in_addr gateway, - int metric, int change, int del) -{ - struct nlmr *nlm; - unsigned int ifindex; - int retval; - - if (! ifname) - return -1; - - log_route (destination, netmask, gateway, metric, change, del); - - if (! (ifindex = if_nametoindex (ifname))) { - logger (LOG_ERR, "if_nametoindex: no index for interface `%s'", - ifname); - return -1; - } - - nlm = xzalloc (sizeof (*nlm)); - nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); - if (change) - nlm->hdr.nlmsg_flags = NLM_F_REPLACE; - else if (! del) - nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL; - nlm->hdr.nlmsg_flags |= NLM_F_REQUEST; - nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE; - nlm->rt.rtm_family = AF_INET; - nlm->rt.rtm_table = RT_TABLE_MAIN; - - if (del) - nlm->rt.rtm_scope = RT_SCOPE_NOWHERE; - else { - nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; - nlm->rt.rtm_protocol = RTPROT_BOOT; - if (netmask.s_addr == INADDR_BROADCAST || - gateway.s_addr == INADDR_ANY) - nlm->rt.rtm_scope = RT_SCOPE_LINK; - else - nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE; - nlm->rt.rtm_type = RTN_UNICAST; - } - - nlm->rt.rtm_dst_len = inet_ntocidr (netmask); - add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_DST, - &destination.s_addr, sizeof (destination.s_addr)); - if (netmask.s_addr != INADDR_BROADCAST && - destination.s_addr != gateway.s_addr) - add_attr_l (&nlm->hdr, sizeof (*nlm), RTA_GATEWAY, - &gateway.s_addr, sizeof (gateway.s_addr)); - - add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_OIF, ifindex); - add_attr_32 (&nlm->hdr, sizeof (*nlm), RTA_PRIORITY, metric); - - retval = send_netlink (&nlm->hdr, NULL, NULL); - free (nlm); - return retval; -} - -#else - #error "Platform not supported!" - #error "We currently support BPF and Linux sockets." - #error "Other platforms may work using BPF. If yours does, please let me know" - #error "so I can add it to our list." -#endif - -int add_address (const char *ifname, struct in_addr address, - struct in_addr netmask, struct in_addr broadcast) -{ - logger (LOG_INFO, "adding IP address %s/%d", - inet_ntoa (address), inet_ntocidr (netmask)); - - return (do_address (ifname, address, netmask, broadcast, 0)); -} - -int del_address (const char *ifname, - struct in_addr address, struct in_addr netmask) -{ - struct in_addr t; - - logger (LOG_INFO, "removing IP address %s/%d", - inet_ntoa (address), inet_ntocidr (netmask)); - - memset (&t, 0, sizeof (t)); - return (do_address (ifname, address, netmask, t, 1)); -} - -int add_route (const char *ifname, struct in_addr destination, - struct in_addr netmask, struct in_addr gateway, int metric) -{ - return (do_route (ifname, destination, netmask, gateway, metric, 0, 0)); -} - -int change_route (const char *ifname, struct in_addr destination, - struct in_addr netmask, struct in_addr gateway, int metric) -{ - return (do_route (ifname, destination, netmask, gateway, metric, 1, 0)); -} - -int del_route (const char *ifname, struct in_addr destination, - struct in_addr netmask, struct in_addr gateway, int metric) -{ - return (do_route (ifname, destination, netmask, gateway, metric, 0, 1)); -} - - -int flush_addresses (const char *ifname) -{ - return (_do_interface (ifname, NULL, NULL, NULL, true, false)); -} - -in_addr_t get_address (const char *ifname) -{ - struct in_addr address; - if (_do_interface (ifname, NULL, NULL, &address, false, true) > 0) - return (address.s_addr); - return (0); -} - -int has_address (const char *ifname, struct in_addr address) -{ - return (_do_interface (ifname, NULL, NULL, &address, false, false)); -} -- cgit v1.2.3-55-g7522