summaryrefslogtreecommitdiff
path: root/ctdb/common/system_socket.c
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2018-08-10 17:04:32 +1000
committerAmitay Isaacs <amitay@samba.org>2018-08-30 04:48:57 +0200
commit2ebb25dfc890923180ecb06d6e17ddb2948e7d2b (patch)
tree1e2de35c441a79782928b03092d0dc31232ef828 /ctdb/common/system_socket.c
parent172b87cb1be460a06b7bea0b598a5bf159d3faab (diff)
downloadsamba-2ebb25dfc890923180ecb06d6e17ddb2948e7d2b.tar.gz
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 <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb/common/system_socket.c')
-rw-r--r--ctdb/common/system_socket.c119
1 files changed, 42 insertions, 77 deletions
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 ){