persistent: reduce indentation for the finishing moves in ctdb_persistent_callback
[sahlberg/ctdb.git] / common / system_linux.c
index 0d5ea631b9d1118e3ae6346dee04952205886b96..a498ab2d686999f6b596d526e2b3f8736f1ef64f 100644 (file)
 #include "system/filesys.h"
 #include "system/wait.h"
 #include "../include/ctdb_private.h"
-#include "lib/events/events.h"
+#include "lib/tevent/tevent.h"
 #include <netinet/if_ether.h>
 #include <netinet/ip6.h>
 #include <netinet/icmp6.h>
 #include <net/if_arp.h>
-
+#include <netpacket/packet.h>
 
 #ifndef ETHERTYPE_IP6
 #define ETHERTYPE_IP6 0x86dd
 #endif
 
-/*
-  uint16 checksum for n bytes
- */
-static uint32_t uint16_checksum(uint16_t *data, size_t n)
-{
-       uint32_t sum=0;
-       while (n>=2) {
-               sum += (uint32_t)ntohs(*data);
-               data++;
-               n -= 2;
-       }
-       if (n == 1) {
-               sum += (uint32_t)ntohs(*(uint8_t *)data);
-       }
-       return sum;
-}
-
 /*
   calculate the tcp checksum for tcp over ipv6
 */
@@ -88,7 +71,7 @@ static uint16_t tcp_checksum6(uint16_t *data, size_t n, struct ip6_hdr *ip6)
 int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
 {
        int s, ret;
-       struct sockaddr sa;
+       struct sockaddr_ll sall;
        struct ether_header *eh;
        struct arphdr *ah;
        struct ip6_hdr *ip6;
@@ -96,17 +79,27 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
        struct ifreq if_hwaddr;
        unsigned char buffer[78]; /* ipv6 neigh solicitation size */
        char *ptr;
+       char bdcast[] = {0xff,0xff,0xff,0xff,0xff,0xff};
+       struct ifreq ifr;
 
-       ZERO_STRUCT(sa);
+       ZERO_STRUCT(sall);
 
        switch (addr->ip.sin_family) {
        case AF_INET:
-               s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
+               s = socket(PF_PACKET, SOCK_RAW, htons(ETHERTYPE_ARP));
                if (s == -1){
                        DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
                        return -1;
                }
 
+               DEBUG(DEBUG_DEBUG, (__location__ " Created SOCKET FD:%d for sending arp\n", s));
+               strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+               if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+                       DEBUG(DEBUG_CRIT,(__location__ " interface '%s' not found\n", iface));
+                       close(s);
+                       return -1;
+               }
+
                /* get the mac address */
                strcpy(if_hwaddr.ifr_name, iface);
                ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
@@ -153,8 +146,12 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
                memcpy(ptr, &addr->ip.sin_addr, 4);       
                ptr+=4;
        
-               strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
-               ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+               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 ){
                        close(s);
                        DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
@@ -173,22 +170,30 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
                memcpy(ptr, &addr->ip.sin_addr, 4);       
                ptr+=4;
 
-               strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
-               ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+               ret = sendto(s, buffer, 64, 0, (struct sockaddr *)&sall, sizeof(sall));
                if (ret < 0 ){
                        DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+                       close(s);
                        return -1;
                }
 
                close(s);
                break;
        case AF_INET6:
-               s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_IP6));
+               s = socket(PF_PACKET, SOCK_RAW, htons(ETHERTYPE_ARP));
                if (s == -1){
                        DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
                        return -1;
                }
 
+               DEBUG(DEBUG_DEBUG, (__location__ " Created SOCKET FD:%d for sending arp\n", s));
+               strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+               if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+                       DEBUG(DEBUG_CRIT,(__location__ " interface '%s' not found\n", iface));
+                       close(s);
+                       return -1;
+               }
+
                /* get the mac address */
                strcpy(if_hwaddr.ifr_name, iface);
                ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
@@ -230,8 +235,12 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
 
                icmp6->icmp6_cksum = tcp_checksum6((uint16_t *)icmp6, ntohs(ip6->ip6_plen), ip6);
 
-               strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
-               ret = sendto(s, buffer, 78, 0, &sa, sizeof(sa));
+               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, 78, 0, (struct sockaddr *)&sall, sizeof(sall));
                if (ret < 0 ){
                        close(s);
                        DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
@@ -404,40 +413,6 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
        return 0;
 }
 
-
-/*
-  see if we currently have an interface with the given IP
-
-  we try to bind to it, and if that fails then we don't have that IP
-  on an interface
-
-  ifname, if non-NULL, will return the name of the interface this ip is tied to
- */
-bool ctdb_sys_have_ip(ctdb_sock_addr *_addr)
-{
-       int s;
-       int ret;
-       ctdb_sock_addr __addr = *_addr;
-       ctdb_sock_addr *addr = &__addr;
-
-       switch (addr->sa.sa_family) {
-       case AF_INET:
-               addr->ip.sin_port = 0;
-               break;
-       case AF_INET6:
-               addr->ip6.sin6_port = 0;
-               break;
-       }
-       s = socket(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
-       if (s == -1) {
-               return false;
-       }
-       ret = bind(s, (struct sockaddr *)addr, sizeof(ctdb_sock_addr));
-
-       close(s);
-       return ret == 0;
-}
-
 /* 
    This function is used to open a raw socket to capture from
  */
@@ -452,6 +427,8 @@ int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
                return -1;
        }
 
+       DEBUG(DEBUG_DEBUG, (__location__ " Created RAW SOCKET FD:%d for tcp tickle\n", s));
+
        set_nonblocking(s);
        set_close_on_exec(s);