ctdb-common: Protocol argument must be in host order for socket() call
[samba.git] / ctdb / common / system_aix.c
index b08692d177463eecad8dd1d53a64c56f2152b4ef..2d35a229aade570aff6f65e92b4f08aa268fca88 100644 (file)
 */
 
 
-#include "includes.h"
+#include "replace.h"
 #include "system/network.h"
 #include "system/filesys.h"
 #include "system/wait.h"
-#include "../include/ctdb_private.h"
+
+#include "lib/util/debug.h"
+
+#include "protocol/protocol.h"
+
 #include <netinet/if_ether.h>
 #include <netinet/ip6.h>
 #include <net/if_arp.h>
@@ -31,6 +35,8 @@
 #include <sys/kinfo.h>
 #include <pcap.h>
 
+#include "common/logging.h"
+#include "common/system.h"
 
 
 #if 0
@@ -44,7 +50,7 @@ int ctdb_sys_open_sending_socket(void)
        int s, ret;
        uint32_t one = 1;
 
-       s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+       s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (s == -1) {
                DEBUG(DEBUG_CRIT,(" failed to open raw socket (%s)\n",
                         strerror(errno)));
@@ -66,23 +72,6 @@ int ctdb_sys_open_sending_socket(void)
 }
 #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;
-}
-
 /*
   simple TCP checksum - assumes data is multiple of 2 bytes long
  */
@@ -138,7 +127,7 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
 
 
 
-       s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+       s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (s == -1) {
                DEBUG(DEBUG_CRIT,(" failed to open raw socket (%s)\n",
                         strerror(errno)));
@@ -187,31 +176,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
- */
-bool ctdb_sys_have_ip(struct sockaddr_in ip)
-{
-       int s;
-       int ret;
-       
-       ip.sin_port = 0;
-       s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (s == -1) {
-               return false;
-       }
-       ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
-       close(s);
-       return ret == 0;
-}
-
-
-
-
 /* This function is used to open a raw socket to capture from
  */
 int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
@@ -248,8 +212,8 @@ int ctdb_sys_close_capture_socket(void *private_data)
  */
 int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
 {
-       /* We dont do grat arp on aix yet */
-       return 0;
+       /* FIXME AIX: We don't do gratuitous arp yet */
+       return -1;
 }
 
 
@@ -306,12 +270,13 @@ static int aix_get_mac_addr(const char *device_name, uint8_t mac[6])
 }
 
 int ctdb_sys_read_tcp_packet(int s, void *private_data, 
-                       struct sockaddr_in *src, struct sockaddr_in *dst,
+                       ctdb_sock_addr *src, ctdb_sock_addr *dst,
                        uint32_t *ack_seq, uint32_t *seq)
 {
        int ret;
        struct ether_header *eth;
        struct ip *ip;
+       struct ip6_hdr *ip6;
        struct tcphdr *tcp;
        struct ctdb_killtcp_connection *conn;
        struct pcap_pkthdr pkthdr;
@@ -326,45 +291,91 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
        /* Ethernet */
        eth = (struct ether_header *)buffer;
 
-       /* We are only interested in IP packets */
-       if (eth->ether_type != htons(ETHERTYPE_IP)) {
-               return -1;
-       }
+       /* we want either IPv4 or IPv6 */
+       if (eth->ether_type == htons(ETHERTYPE_IP)) {
+               /* IP */
+               ip = (struct ip *)(eth+1);
 
-       /* IP */
-       ip = (struct ip *)(eth+1);
+               /* We only want IPv4 packets */
+               if (ip->ip_v != 4) {
+                       return -1;
+               }
+               /* Dont look at fragments */
+               if ((ntohs(ip->ip_off)&0x1fff) != 0) {
+                       return -1;
+               }
+               /* we only want TCP */
+               if (ip->ip_p != IPPROTO_TCP) {
+                       return -1;
+               }
 
-       /* We only want IPv4 packets */
-       if (ip->ip_v != 4) {
-               return -1;
-       }
-       /* Dont look at fragments */
-       if ((ntohs(ip->ip_off)&0x1fff) != 0) {
-               return -1;
-       }
-       /* we only want TCP */
-       if (ip->ip_p != IPPROTO_TCP) {
-               return -1;
-       }
+               /* make sure its not a short packet */
+               if (offsetof(struct tcphdr, th_ack) + 4 + 
+                   (ip->ip_hl*4) > ret) {
+                       return -1;
+               }
+               /* TCP */
+               tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
+       
+               /* tell the caller which one we've found */
+               src->ip.sin_family      = AF_INET;
+               src->ip.sin_addr.s_addr = ip->ip_src.s_addr;
+               src->ip.sin_port        = tcp->th_sport;
+               dst->ip.sin_family      = AF_INET;
+               dst->ip.sin_addr.s_addr = ip->ip_dst.s_addr;
+               dst->ip.sin_port        = tcp->th_dport;
+               *ack_seq                = tcp->th_ack;
+               *seq                    = tcp->th_seq;
 
-       /* make sure its not a short packet */
-       if (offsetof(struct tcphdr, th_ack) + 4 + 
-           (ip->ip_hl*4) > ret) {
-               return -1;
+
+               return 0;
+#ifndef ETHERTYPE_IP6
+#define ETHERTYPE_IP6 0x86dd
+#endif
+       } else if (eth->ether_type == htons(ETHERTYPE_IP6)) {
+                       /* IP6 */
+               ip6 = (struct ip6_hdr *)(eth+1);
+
+               /* we only want TCP */
+               if (ip6->ip6_nxt != IPPROTO_TCP) {
+                       return -1;
+               }
+
+               /* TCP */
+               tcp = (struct tcphdr *)(ip6+1);
+
+               /* tell the caller which one we've found */
+               src->ip6.sin6_family = AF_INET6;
+               src->ip6.sin6_port   = tcp->th_sport;
+               src->ip6.sin6_addr   = ip6->ip6_src;
+
+               dst->ip6.sin6_family = AF_INET6;
+               dst->ip6.sin6_port   = tcp->th_dport;
+               dst->ip6.sin6_addr   = ip6->ip6_dst;
+
+               *ack_seq             = tcp->th_ack;
+               *seq                 = tcp->th_seq;
+
+               return 0;
        }
-       /* TCP */
-       tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
-       
-       /* tell the caller which one we've found */
-       src->sin_addr.s_addr = ip->ip_src.s_addr;
-       src->sin_port        = tcp->th_sport;
-       dst->sin_addr.s_addr = ip->ip_dst.s_addr;
-       dst->sin_port        = tcp->th_dport;
-       *ack_seq             = tcp->th_ack;
-       *seq                 = tcp->th_seq;
 
-       return 0;
+       return -1;
 }
 
 
+bool ctdb_sys_check_iface_exists(const char *iface)
+{
+       /* FIXME AIX: Interface always considered present */
+       return true;
+}
 
+int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
+{
+       struct peercred_struct cr;
+       socklen_t crl = sizeof(struct peercred_struct);
+       int ret;
+       if ((ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl) == 0)) {
+               *peer_pid = cr.pid;
+       }
+       return ret;
+}