From: Martin Schwenke Date: Fri, 10 Aug 2018 07:04:32 +0000 (+1000) Subject: ctdb-common: Factor out common ARP code X-Git-Tag: tdb-1.3.17~1978 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ebb25dfc890923180ecb06d6e17ddb2948e7d2b;p=thirdparty%2Fsamba.git ctdb-common: Factor out common ARP code Finding the interface and the MAC address are obvious. Might as well set up the common parts of the destination address structure. Continue to open the socket and find the MAC address first. This might seem odd because marshalling and other subsequent steps may fail. However, in the future this code might be optimised to open a single socket to send ARPs for a list of addresses on each interface, so don't change the logic. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c index f9b61c59d80..77cf4196aa1 100644 --- a/ctdb/common/system_socket.c +++ b/ctdb/common/system_socket.c @@ -190,44 +190,50 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) char bdcast[] = {0xff,0xff,0xff,0xff,0xff,0xff}; struct ifreq ifr = {{{0}}}; - switch (addr->ip.sin_family) { - case AF_INET: - s = socket(AF_PACKET, SOCK_RAW, 0); - if (s == -1){ - DBG_ERR("Failed to open raw socket\n"); - return -1; - } + s = socket(AF_PACKET, SOCK_RAW, 0); + if (s == -1) { + DBG_ERR("Failed to open raw socket\n"); + return -1; + } + DBG_DEBUG("Created SOCKET FD:%d for sending arp\n", s); - DBG_DEBUG("Created SOCKET FD:%d for sending arp\n", s); - strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - DBG_ERR("Interface '%s' not found\n", iface); - close(s); - return -1; - } + /* Find interface */ + strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { + DBG_ERR("Interface '%s' not found\n", iface); + close(s); + return -1; + } - /* get the mac address */ - strlcpy(if_hwaddr.ifr_name, iface, sizeof(if_hwaddr.ifr_name)); - ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr); - if ( ret < 0 ) { - close(s); - DBG_ERR("ioctl failed\n"); - return -1; - } - if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) { - D_DEBUG("Ignoring loopback arp request\n"); - close(s); - return 0; - } - if (if_hwaddr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - close(s); - errno = EINVAL; - DBG_ERR("Not an ethernet address family (0x%x)\n", - if_hwaddr.ifr_hwaddr.sa_family); - return -1; - } + /* Get MAC address */ + strlcpy(if_hwaddr.ifr_name, iface, sizeof(if_hwaddr.ifr_name)); + ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr); + if ( ret < 0 ) { + close(s); + DBG_ERR("ioctl failed\n"); + return -1; + } + if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) { + D_DEBUG("Ignoring loopback arp request\n"); + close(s); + return 0; + } + if (if_hwaddr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + close(s); + errno = EINVAL; + DBG_ERR("Not an ethernet address family (0x%x)\n", + if_hwaddr.ifr_hwaddr.sa_family); + return -1; + } + /* Set up most of destination address structure */ + sall.sll_family = AF_PACKET; + sall.sll_halen = sizeof(struct ether_addr); + sall.sll_protocol = htons(ETH_P_ALL); + sall.sll_ifindex = ifr.ifr_ifindex; + switch (addr->ip.sin_family) { + case AF_INET: memset(buffer, 0 , 64); eh = (struct ether_header *)buffer; memset(eh->ether_dhost, 0xff, ETH_ALEN); @@ -252,11 +258,8 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) memcpy(ptr, &addr->ip.sin_addr, 4); ptr+=4; - sall.sll_family = AF_PACKET; - sall.sll_halen = 6; memcpy(&sall.sll_addr[0], bdcast, sall.sll_halen); - sall.sll_protocol = htons(ETH_P_ALL); - sall.sll_ifindex = ifr.ifr_ifindex; + ret = sendto(s,buffer, 64, 0, (struct sockaddr *)&sall, sizeof(sall)); if (ret < 0 ){ @@ -288,41 +291,6 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) close(s); break; case AF_INET6: - s = socket(AF_PACKET, SOCK_RAW, 0); - if (s == -1){ - DBG_ERR("Failed to open raw socket\n"); - return -1; - } - - DBG_DEBUG("Created SOCKET FD:%d for sending arp\n", s); - strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - DBG_ERR("Interface '%s' not found\n", iface); - close(s); - return -1; - } - - /* get the mac address */ - strlcpy(if_hwaddr.ifr_name, iface, sizeof(if_hwaddr.ifr_name)); - ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr); - if ( ret < 0 ) { - close(s); - DBG_ERR("ioctl failed\n"); - return -1; - } - if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) { - DBG_DEBUG("Ignoring loopback arp request\n"); - close(s); - return 0; - } - if (if_hwaddr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - close(s); - errno = EINVAL; - DBG_ERR("Not an ethernet address family (0x%x)\n", - if_hwaddr.ifr_hwaddr.sa_family); - return -1; - } - memset(buffer, 0 , sizeof(buffer)); eh = (struct ether_header *)buffer; /* @@ -367,11 +335,8 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) nd_na->nd_na_cksum = ip6_checksum((uint16_t *)nd_na, ntohs(ip6->ip6_plen), ip6); - sall.sll_family = AF_PACKET; - sall.sll_halen = 6; memcpy(&sall.sll_addr[0], &eh->ether_dhost[0], sall.sll_halen); - sall.sll_protocol = htons(ETH_P_ALL); - sall.sll_ifindex = ifr.ifr_ifindex; + ret = sendto(s, buffer, sizeof(buffer), 0, (struct sockaddr *)&sall, sizeof(sall)); if (ret < 0 ){