ctdb-common: Move capture_socket functions to ctdb_socket.[ch]
authorMartin Schwenke <martin@meltin.net>
Thu, 28 Jun 2018 11:12:04 +0000 (21:12 +1000)
committerMartin Schwenke <martins@samba.org>
Mon, 2 Jul 2018 06:51:21 +0000 (08:51 +0200)
The system_<os>.c files contain a lot of duplication, making
maintenance difficult.  These functions are being merged into
system_socket.c and system.c.

Bring across ctdb_sys_open_capture_socket(),
ctdb_sys_close_capture_socket() and ctdb_sys_read_tcp_packet().

Remove empty system_<os>.c files.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/common/system.h
ctdb/common/system_aix.c [deleted file]
ctdb/common/system_freebsd.c [deleted file]
ctdb/common/system_gnu.c [deleted file]
ctdb/common/system_kfreebsd.c [deleted file]
ctdb/common/system_linux.c [deleted file]
ctdb/common/system_socket.c
ctdb/common/system_socket.h
ctdb/tools/ctdb.c
ctdb/tools/ctdb_killtcp.c
ctdb/wscript

index 5507c0527fe4bd329d4f788bd6731934ad3c1e15..8d558e2f7ad231a6bcff93adc91b2904fb030d20 100644 (file)
 
 #include <talloc.h>
 
-/* From system_<os>.c */
-
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data);
-int ctdb_sys_close_capture_socket(void *private_data);
-int ctdb_sys_read_tcp_packet(int s, void *private_data,
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window);
-
 /* From system_util.c */
 
 bool set_scheduler(void);
diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c
deleted file mode 100644 (file)
index 08ee103..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/* 
-   ctdb system specific code to manage raw sockets on aix
-
-   Copyright (C) Ronnie Sahlberg  2007
-   Copyright (C) Andrew Tridgell  2007
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "replace.h"
-#include "system/network.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-
-#include "lib/util/debug.h"
-#include "lib/util/blocking.h"
-
-#include "protocol/protocol.h"
-
-#include <netinet/if_ether.h>
-#include <netinet/ip6.h>
-#include <net/if_arp.h>
-#include <sys/ndd_var.h>
-#include <sys/kinfo.h>
-#include <pcap.h>
-
-#include "common/logging.h"
-#include "common/system.h"
-#include "common/system_socket.h"
-
-
-#if 0
-This function is no longer used and its code should be moved into
-send tcp packet   after that function has been enhanced to do ipv6 as well.
-
-/* This function is used to open a raw socket to send tickles from
- */
-int ctdb_sys_open_sending_socket(void)
-{
-       int s, ret;
-       uint32_t one = 1;
-
-       s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-       if (s == -1) {
-               DEBUG(DEBUG_CRIT,(" failed to open raw socket (%s)\n",
-                        strerror(errno)));
-               return -1;
-       }
-
-       ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one));
-       if (ret != 0) {
-               DEBUG(DEBUG_CRIT, (" failed to setup IP headers (%s)\n",
-                        strerror(errno)));
-               close(s);
-               return -1;
-       }
-
-       set_blocking(s, false);
-       set_close_on_exec(s);
-
-       return s;
-}
-#endif
-
-/* This function is used to open a raw socket to capture from
- */
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
-{
-       pcap_t *pt;
-
-       pt=pcap_open_live(iface, 100, 0, 0, NULL);
-       if (pt == NULL) {
-               DEBUG(DEBUG_CRIT,("Failed to open capture device %s\n", iface));
-               return -1;
-       }
-       *((pcap_t **)private_data) = pt;
-
-       return pcap_fileno(pt);
-}
-
-
-/* This function is used to close the capture socket
- */
-int ctdb_sys_close_capture_socket(void *private_data)
-{
-       pcap_t *pt = (pcap_t *)private_data;
-       pcap_close(pt);
-       return 0;
-}
-
-/*
-  get ethernet MAC address on AIX
- */
-static int aix_get_mac_addr(const char *device_name, uint8_t mac[6])
-{
-        size_t ksize;
-        struct kinfo_ndd *ndd;
-       int count, i;
-
-        ksize = getkerninfo(KINFO_NDD, 0, 0, 0);
-        if (ksize == 0) {
-               errno = ENOSYS;
-               return -1;
-        }
-
-        ndd = (struct kinfo_ndd *)malloc(ksize);
-        if (ndd == NULL) {
-               errno = ENOMEM;
-               return -1;
-        }
-
-        if (getkerninfo(KINFO_NDD, ndd, &ksize, 0) == -1) {
-               errno = ENOSYS;
-               return -1;
-        }
-
-       count= ksize/sizeof(struct kinfo_ndd);
-       for (i=0;i<count;i++) {
-               if ( (ndd[i].ndd_type != NDD_ETHER) 
-               &&   (ndd[i].ndd_type != NDD_ISO88023) ) {
-                       continue;
-               }
-               if (ndd[i].ndd_addrlen != 6) {
-                       continue;
-               }
-               if (!(ndd[i].ndd_flags&NDD_UP)) {
-                       continue;
-               }
-               if ( strcmp(device_name, ndd[i].ndd_name)
-               &&   strcmp(device_name, ndd[i].ndd_alias) ) {
-                       continue;
-               }
-                memcpy(mac, ndd[i].ndd_addr, 6);
-               free(ndd);
-               return 0;
-        }
-       free(ndd);
-       errno = ENOENT;
-       return -1;
-}
-
-int ctdb_sys_read_tcp_packet(int s, void *private_data,
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window)
-{
-       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;
-       const u_char *buffer;
-       pcap_t *pt = (pcap_t *)private_data;
-
-       buffer=pcap_next(pt, &pkthdr);
-       if (buffer==NULL) {
-               return -1;
-       }
-
-       ZERO_STRUCTP(src);
-       ZERO_STRUCTP(dst);
-
-       /* Ethernet */
-       eth = (struct ether_header *)buffer;
-
-       /* we want either IPv4 or IPv6 */
-       if (eth->ether_type == htons(ETHERTYPE_IP)) {
-               /* 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;
-               }
-
-               /* 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;
-               if (window != NULL) {
-                       *window = tcp->th_win;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->th_flags & TH_RST;
-               }
-
-               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;
-               if (window != NULL) {
-                       *window = tcp->th_win;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->th_flags & TH_RST;
-               }
-
-               return 0;
-       }
-
-       return -1;
-}
diff --git a/ctdb/common/system_freebsd.c b/ctdb/common/system_freebsd.c
deleted file mode 100644 (file)
index 5ed6d19..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* 
-   ctdb system specific code to manage raw sockets on freebsd
-
-   Copyright (C) Ronnie Sahlberg  2007
-   Copyright (C) Andrew Tridgell  2007
-   Copyright (C) Marc Dequènes (Duck) 2009
-   Copyright (C) Volker Lendecke 2012
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-
-  This file is a copy of 'common/system_linux.c' adapted for Hurd^W kFreeBSD
-  needs, and inspired by 'common/system_aix.c' for the pcap usage.
-*/
-
-#include "replace.h"
-#include "system/network.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-
-#include "lib/util/debug.h"
-#include "lib/util/blocking.h"
-
-#include "protocol/protocol.h"
-
-#include <net/ethernet.h>
-#include <netinet/ip6.h>
-#include <net/if_arp.h>
-#include <pcap.h>
-
-#include "common/logging.h"
-#include "common/system.h"
-#include "common/system_socket.h"
-
-#ifndef ETHERTYPE_IP6
-#define ETHERTYPE_IP6 0x86dd
-#endif
-
-/* 
-   This function is used to open a raw socket to capture from
- */
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
-{
-       pcap_t *pt;
-
-       pt=pcap_open_live(iface, 100, 0, 0, NULL);
-       if (pt == NULL) {
-               DEBUG(DEBUG_CRIT,("Failed to open capture device %s\n", iface));
-               return -1;
-       }
-       *((pcap_t **)private_data) = pt;
-
-       return pcap_fileno(pt);
-}
-
-/* This function is used to close the capture socket
- */
-int ctdb_sys_close_capture_socket(void *private_data)
-{
-       pcap_t *pt = (pcap_t *)private_data;
-       pcap_close(pt);
-       return 0;
-}
-
-
-/*
-  called when the raw socket becomes readable
- */
-int ctdb_sys_read_tcp_packet(int s, void *private_data, 
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window)
-{
-       int ret;
-#define RCVPKTSIZE 100
-       char pkt[RCVPKTSIZE];
-       struct ether_header *eth;
-       struct ip *ip;
-       struct ip6_hdr *ip6;
-       struct tcphdr *tcp;
-
-       ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
-       if (ret < sizeof(*eth)+sizeof(*ip)) {
-               return -1;
-       }
-
-       ZERO_STRUCTP(src);
-       ZERO_STRUCTP(dst);
-
-       /* Ethernet */
-       eth = (struct ether_header *)pkt;
-
-       /* we want either IPv4 or IPv6 */
-       if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
-               /* 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;
-               }
-
-               /* make sure its not a short packet */
-               if (offsetof(struct tcphdr, th_ack) + 4 + 
-                   (ip->ip_hl*4) + sizeof(*eth) > 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;
-               if (window != NULL) {
-                       *window = tcp->th_win;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->th_flags & TH_RST;
-               }
-
-               return 0;
-       } else if (ntohs(eth->ether_type) == 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;
-               if (window != NULL) {
-                       *window = tcp->th_win;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->th_flags & TH_RST;
-               }
-
-               return 0;
-       }
-
-       return -1;
-}
diff --git a/ctdb/common/system_gnu.c b/ctdb/common/system_gnu.c
deleted file mode 100644 (file)
index 2b81bd9..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/* 
-   ctdb system specific code to manage raw sockets on linux
-
-   Copyright (C) Ronnie Sahlberg  2007
-   Copyright (C) Andrew Tridgell  2007
-   Copyright (C) Marc Dequènes (Duck) 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-
-  This file is a copy of 'common/system_linux.c' adapted for Hurd needs,
-  and inspired by 'common/system_aix.c' for the pcap usage.
-*/
-
-#include "replace.h"
-#include "system/network.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-
-#include "lib/util/debug.h"
-#include "lib/util/blocking.h"
-
-#include "protocol/protocol.h"
-
-#include <net/ethernet.h>
-#include <netinet/ip6.h>
-#include <net/if_arp.h>
-#include <pcap.h>
-
-#include "common/logging.h"
-#include "common/system.h"
-#include "common/system_socket.h"
-
-#ifndef ETHERTYPE_IP6
-#define ETHERTYPE_IP6 0x86dd
-#endif
-
-/* 
-   This function is used to open a raw socket to capture from
- */
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
-{
-       pcap_t *pt;
-
-       pt=pcap_open_live(iface, 100, 0, 0, NULL);
-       if (pt == NULL) {
-               DEBUG(DEBUG_CRIT,("Failed to open capture device %s\n", iface));
-               return -1;
-       }
-       *((pcap_t **)private_data) = pt;
-
-       return pcap_fileno(pt);
-}
-
-/* This function is used to close the capture socket
- */
-int ctdb_sys_close_capture_socket(void *private_data)
-{
-       pcap_t *pt = (pcap_t *)private_data;
-       pcap_close(pt);
-       return 0;
-}
-
-
-/*
-  called when the raw socket becomes readable
- */
-int ctdb_sys_read_tcp_packet(int s, void *private_data,
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window)
-{
-       int ret;
-#define RCVPKTSIZE 100
-       char pkt[RCVPKTSIZE];
-       struct ether_header *eth;
-       struct iphdr *ip;
-       struct ip6_hdr *ip6;
-       struct tcphdr *tcp;
-
-       ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
-       if (ret < sizeof(*eth)+sizeof(*ip)) {
-               return -1;
-       }
-
-       ZERO_STRUCTP(src);
-       ZERO_STRUCTP(dst);
-
-       /* Ethernet */
-       eth = (struct ether_header *)pkt;
-
-       /* we want either IPv4 or IPv6 */
-       if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
-               /* IP */
-               ip = (struct iphdr *)(eth+1);
-
-               /* We only want IPv4 packets */
-               if (ip->version != 4) {
-                       return -1;
-               }
-               /* Dont look at fragments */
-               if ((ntohs(ip->frag_off)&0x1fff) != 0) {
-                       return -1;
-               }
-               /* we only want TCP */
-               if (ip->protocol != IPPROTO_TCP) {
-                       return -1;
-               }
-
-               /* make sure its not a short packet */
-               if (offsetof(struct tcphdr, ack_seq) + 4 + 
-                   (ip->ihl*4) + sizeof(*eth) > ret) {
-                       return -1;
-               }
-               /* TCP */
-               tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
-
-               /* tell the caller which one we've found */
-               src->ip.sin_family      = AF_INET;
-               src->ip.sin_addr.s_addr = ip->saddr;
-               src->ip.sin_port        = tcp->source;
-               dst->ip.sin_family      = AF_INET;
-               dst->ip.sin_addr.s_addr = ip->daddr;
-               dst->ip.sin_port        = tcp->dest;
-               *ack_seq                = tcp->ack_seq;
-               *seq                    = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       } else if (ntohs(eth->ether_type) == 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->source;
-               src->ip6.sin6_addr   = ip6->ip6_src;
-
-               dst->ip6.sin6_family = AF_INET6;
-               dst->ip6.sin6_port   = tcp->dest;
-               dst->ip6.sin6_addr   = ip6->ip6_dst;
-
-               *ack_seq             = tcp->ack_seq;
-               *seq                 = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       }
-
-       return -1;
-}
diff --git a/ctdb/common/system_kfreebsd.c b/ctdb/common/system_kfreebsd.c
deleted file mode 100644 (file)
index 700dde1..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* 
-   ctdb system specific code to manage raw sockets on linux
-
-   Copyright (C) Ronnie Sahlberg  2007
-   Copyright (C) Andrew Tridgell  2007
-   Copyright (C) Marc Dequènes (Duck) 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-
-  This file is a copy of 'common/system_linux.c' adapted for Hurd^W kFreeBSD
-  needs, and inspired by 'common/system_aix.c' for the pcap usage.
-*/
-
-#include "replace.h"
-#include "system/network.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-
-#include "lib/util/debug.h"
-#include "lib/util/blocking.h"
-
-#include "protocol/protocol.h"
-
-#include <net/ethernet.h>
-#include <netinet/ip6.h>
-#include <net/if_arp.h>
-#include <pcap.h>
-
-#include "common/logging.h"
-#include "common/system.h"
-#include "common/system_socket.h"
-
-/* 
-   This function is used to open a raw socket to capture from
- */
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
-{
-       pcap_t *pt;
-
-       pt=pcap_open_live(iface, 100, 0, 0, NULL);
-       if (pt == NULL) {
-               DEBUG(DEBUG_CRIT,("Failed to open capture device %s\n", iface));
-               return -1;
-       }
-       *((pcap_t **)private_data) = pt;
-
-       return pcap_fileno(pt);
-}
-
-/* This function is used to close the capture socket
- */
-int ctdb_sys_close_capture_socket(void *private_data)
-{
-       pcap_t *pt = (pcap_t *)private_data;
-       pcap_close(pt);
-       return 0;
-}
-
-
-/*
-  called when the raw socket becomes readable
- */
-int ctdb_sys_read_tcp_packet(int s, void *private_data,
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window)
-{
-       int ret;
-#define RCVPKTSIZE 100
-       char pkt[RCVPKTSIZE];
-       struct ether_header *eth;
-       struct iphdr *ip;
-       struct ip6_hdr *ip6;
-       struct tcphdr *tcp;
-
-       ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
-       if (ret < sizeof(*eth)+sizeof(*ip)) {
-               return -1;
-       }
-
-       ZERO_STRUCTP(src);
-       ZERO_STRUCTP(dst);
-
-       /* Ethernet */
-       eth = (struct ether_header *)pkt;
-
-       /* we want either IPv4 or IPv6 */
-       if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
-               /* IP */
-               ip = (struct iphdr *)(eth+1);
-
-               /* We only want IPv4 packets */
-               if (ip->version != 4) {
-                       return -1;
-               }
-               /* Dont look at fragments */
-               if ((ntohs(ip->frag_off)&0x1fff) != 0) {
-                       return -1;
-               }
-               /* we only want TCP */
-               if (ip->protocol != IPPROTO_TCP) {
-                       return -1;
-               }
-
-               /* make sure its not a short packet */
-               if (offsetof(struct tcphdr, ack_seq) + 4 + 
-                   (ip->ihl*4) + sizeof(*eth) > ret) {
-                       return -1;
-               }
-               /* TCP */
-               tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
-
-               /* tell the caller which one we've found */
-               src->ip.sin_family      = AF_INET;
-               src->ip.sin_addr.s_addr = ip->saddr;
-               src->ip.sin_port        = tcp->source;
-               dst->ip.sin_family      = AF_INET;
-               dst->ip.sin_addr.s_addr = ip->daddr;
-               dst->ip.sin_port        = tcp->dest;
-               *ack_seq                = tcp->ack_seq;
-               *seq                    = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       } else if (ntohs(eth->ether_type) == 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->source;
-               src->ip6.sin6_addr   = ip6->ip6_src;
-
-               dst->ip6.sin6_family = AF_INET6;
-               dst->ip6.sin6_port   = tcp->dest;
-               dst->ip6.sin6_addr   = ip6->ip6_dst;
-
-               *ack_seq             = tcp->ack_seq;
-               *seq                 = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       }
-
-       return -1;
-}
diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
deleted file mode 100644 (file)
index c8b0720..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* 
-   ctdb system specific code to manage raw sockets on linux
-
-   Copyright (C) Ronnie Sahlberg  2007
-   Copyright (C) Andrew Tridgell  2007
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "replace.h"
-#include "system/network.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-
-#include "lib/util/debug.h"
-#include "lib/util/blocking.h"
-
-#include "protocol/protocol.h"
-
-#include <netinet/if_ether.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <net/if_arp.h>
-#include <netpacket/packet.h>
-#include <sys/prctl.h>
-
-#include "common/logging.h"
-#include "common/system.h"
-#include "common/system_socket.h"
-
-#ifndef ETHERTYPE_IP6
-#define ETHERTYPE_IP6 0x86dd
-#endif
-
-/* 
-   This function is used to open a raw socket to capture from
- */
-int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
-{
-       int s, ret;
-
-       /* Open a socket to capture all traffic */
-       s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
-       if (s == -1) {
-               DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
-               return -1;
-       }
-
-       DEBUG(DEBUG_DEBUG, (__location__ " Created RAW SOCKET FD:%d for tcp tickle\n", s));
-
-       ret = set_blocking(s, false);
-       if (ret != 0) {
-               DEBUG(DEBUG_ERR,
-                     (__location__
-                      " failed to set socket non-blocking (%s)\n",
-                      strerror(errno)));
-               close(s);
-               return -1;
-       }
-
-       set_close_on_exec(s);
-
-       return s;
-}
-
-/* 
-   This function is used to do any additional cleanup required when closing
-   a capture socket.
-   Note that the socket itself is closed automatically in the caller.
- */
-int ctdb_sys_close_capture_socket(void *private_data)
-{
-       return 0;
-}
-
-
-/*
-  called when the raw socket becomes readable
- */
-int ctdb_sys_read_tcp_packet(int s, void *private_data,
-                            ctdb_sock_addr *src, ctdb_sock_addr *dst,
-                            uint32_t *ack_seq, uint32_t *seq,
-                            int *rst, uint16_t *window)
-{
-       int ret;
-#define RCVPKTSIZE 100
-       char pkt[RCVPKTSIZE];
-       struct ether_header *eth;
-       struct iphdr *ip;
-       struct ip6_hdr *ip6;
-       struct tcphdr *tcp;
-
-       ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
-       if (ret < sizeof(*eth)+sizeof(*ip)) {
-               return -1;
-       }
-
-       ZERO_STRUCTP(src);
-       ZERO_STRUCTP(dst);
-
-       /* Ethernet */
-       eth = (struct ether_header *)pkt;
-
-       /* we want either IPv4 or IPv6 */
-       if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
-               /* IP */
-               ip = (struct iphdr *)(eth+1);
-
-               /* We only want IPv4 packets */
-               if (ip->version != 4) {
-                       return -1;
-               }
-               /* Dont look at fragments */
-               if ((ntohs(ip->frag_off)&0x1fff) != 0) {
-                       return -1;
-               }
-               /* we only want TCP */
-               if (ip->protocol != IPPROTO_TCP) {
-                       return -1;
-               }
-
-               /* make sure its not a short packet */
-               if (offsetof(struct tcphdr, ack_seq) + 4 + 
-                   (ip->ihl*4) + sizeof(*eth) > ret) {
-                       return -1;
-               }
-               /* TCP */
-               tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
-
-               /* tell the caller which one we've found */
-               src->ip.sin_family      = AF_INET;
-               src->ip.sin_addr.s_addr = ip->saddr;
-               src->ip.sin_port        = tcp->source;
-               dst->ip.sin_family      = AF_INET;
-               dst->ip.sin_addr.s_addr = ip->daddr;
-               dst->ip.sin_port        = tcp->dest;
-               *ack_seq                = tcp->ack_seq;
-               *seq                    = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       } else if (ntohs(eth->ether_type) == 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->source;
-               src->ip6.sin6_addr   = ip6->ip6_src;
-
-               dst->ip6.sin6_family = AF_INET6;
-               dst->ip6.sin6_port   = tcp->dest;
-               dst->ip6.sin6_addr   = ip6->ip6_dst;
-
-               *ack_seq             = tcp->ack_seq;
-               *seq                 = tcp->seq;
-               if (window != NULL) {
-                       *window = tcp->window;
-               }
-               if (rst != NULL) {
-                       *rst = tcp->rst;
-               }
-
-               return 0;
-       }
-
-       return -1;
-}
index ea371281efe0eb8a7f6069f28df4525c141e53ec..d8627fd61fc07342eaf047760ebfe8bd7def7bf6 100644 (file)
@@ -55,6 +55,7 @@
 #endif
 
 #include "lib/util/debug.h"
+#include "lib/util/blocking.h"
 
 #include "protocol/protocol.h"
 
@@ -677,3 +678,297 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
 
        return 0;
 }
+
+/*
+ * Packet capture
+ *
+ * If AF_PACKET is available then use a raw socket otherwise use pcap.
+ * wscript has checked to make sure that pcap is available if needed.
+ */
+
+#ifdef HAVE_AF_PACKET
+
+/*
+ * This function is used to open a raw socket to capture from
+ */
+int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
+{
+       int s, ret;
+
+       /* Open a socket to capture all traffic */
+       s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+       if (s == -1) {
+               DBG_ERR("Failed to open raw socket\n");
+               return -1;
+       }
+
+       DBG_DEBUG("Created RAW SOCKET FD:%d for tcp tickle\n", s);
+
+       ret = set_blocking(s, false);
+       if (ret != 0) {
+               DBG_ERR("Failed to set socket non-blocking (%s)\n",
+                       strerror(errno));
+               close(s);
+               return -1;
+       }
+
+       set_close_on_exec(s);
+
+       return s;
+}
+
+/*
+ * This function is used to do any additional cleanup required when closing
+ * a capture socket.
+ * Note that the socket itself is closed automatically in the caller.
+ */
+int ctdb_sys_close_capture_socket(void *private_data)
+{
+       return 0;
+}
+
+
+/*
+ * called when the raw socket becomes readable
+ */
+int ctdb_sys_read_tcp_packet(int s, void *private_data,
+                            ctdb_sock_addr *src,
+                            ctdb_sock_addr *dst,
+                            uint32_t *ack_seq,
+                            uint32_t *seq,
+                            int *rst,
+                            uint16_t *window)
+{
+       int ret;
+#define RCVPKTSIZE 100
+       char pkt[RCVPKTSIZE];
+       struct ether_header *eth;
+       struct iphdr *ip;
+       struct ip6_hdr *ip6;
+       struct tcphdr *tcp;
+
+       ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
+       if (ret < sizeof(*eth)+sizeof(*ip)) {
+               return -1;
+       }
+
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
+       /* Ethernet */
+       eth = (struct ether_header *)pkt;
+
+       /* we want either IPv4 or IPv6 */
+       if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
+               /* IP */
+               ip = (struct iphdr *)(eth+1);
+
+               /* We only want IPv4 packets */
+               if (ip->version != 4) {
+                       return -1;
+               }
+               /* Dont look at fragments */
+               if ((ntohs(ip->frag_off)&0x1fff) != 0) {
+                       return -1;
+               }
+               /* we only want TCP */
+               if (ip->protocol != IPPROTO_TCP) {
+                       return -1;
+               }
+
+               /* make sure its not a short packet */
+               if (offsetof(struct tcphdr, th_ack) + 4 +
+                   (ip->ihl*4) + sizeof(*eth) > ret) {
+                       return -1;
+               }
+               /* TCP */
+               tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
+
+               /* tell the caller which one we've found */
+               src->ip.sin_family      = AF_INET;
+               src->ip.sin_addr.s_addr = ip->saddr;
+               src->ip.sin_port        = tcp->th_sport;
+               dst->ip.sin_family      = AF_INET;
+               dst->ip.sin_addr.s_addr = ip->daddr;
+               dst->ip.sin_port        = tcp->th_dport;
+               *ack_seq                = tcp->th_ack;
+               *seq                    = tcp->th_seq;
+               if (window != NULL) {
+                       *window = tcp->th_win;
+               }
+               if (rst != NULL) {
+                       *rst = tcp->th_flags & TH_RST;
+               }
+
+               return 0;
+       } else if (ntohs(eth->ether_type) == 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;
+               if (window != NULL) {
+                       *window = tcp->th_win;
+               }
+               if (rst != NULL) {
+                       *rst = tcp->th_flags & TH_RST;
+               }
+
+               return 0;
+       }
+
+       return -1;
+}
+
+#else /* HAVE_AF_PACKET */
+
+#include <pcap.h>
+
+int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
+{
+       pcap_t *pt;
+
+       pt=pcap_open_live(iface, 100, 0, 0, NULL);
+       if (pt == NULL) {
+               DBG_ERR("Failed to open capture device %s\n", iface);
+               return -1;
+       }
+       *((pcap_t **)private_data) = pt;
+
+       return pcap_fileno(pt);
+}
+
+int ctdb_sys_close_capture_socket(void *private_data)
+{
+       pcap_t *pt = (pcap_t *)private_data;
+       pcap_close(pt);
+       return 0;
+}
+
+int ctdb_sys_read_tcp_packet(int s,
+                            void *private_data,
+                            ctdb_sock_addr *src,
+                            ctdb_sock_addr *dst,
+                            uint32_t *ack_seq,
+                            uint32_t *seq,
+                            int *rst,
+                            uint16_t *window)
+{
+       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;
+       const u_char *buffer;
+       pcap_t *pt = (pcap_t *)private_data;
+
+       buffer=pcap_next(pt, &pkthdr);
+       if (buffer==NULL) {
+               return -1;
+       }
+
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
+       /* Ethernet */
+       eth = (struct ether_header *)buffer;
+
+       /* we want either IPv4 or IPv6 */
+       if (eth->ether_type == htons(ETHERTYPE_IP)) {
+               /* 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;
+               }
+
+               /* 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;
+               if (window != NULL) {
+                       *window = tcp->th_win;
+               }
+               if (rst != NULL) {
+                       *rst = tcp->th_flags & TH_RST;
+               }
+
+               return 0;
+       } 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;
+               if (window != NULL) {
+                       *window = tcp->th_win;
+               }
+               if (rst != NULL) {
+                       *rst = tcp->th_flags & TH_RST;
+               }
+
+               return 0;
+       }
+
+       return -1;
+}
+
+#endif /* HAVE_AF_PACKET */
index 5f49bb985bd80fff4a158d3941d95d63476b4c9d..eb2c6f7b6ae8e660a7457cf2639a1222f5bf70f6 100644 (file)
@@ -37,4 +37,15 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
                      uint32_t ack,
                      int rst);
 
+int ctdb_sys_open_capture_socket(const char *iface, void **private_data);
+int ctdb_sys_close_capture_socket(void *private_data);
+int ctdb_sys_read_tcp_packet(int s,
+                            void *private_data,
+                            ctdb_sock_addr *src,
+                            ctdb_sock_addr *dst,
+                            uint32_t *ack_seq,
+                            uint32_t *seq,
+                            int *rst,
+                            uint16_t *window);
+
 #endif /* __CTDB_SYSTEM_SOCKET_H__ */
index 981293554b06c5018116c87ebac6a50f1044fc15..7881268a9af4d6b2dc7afb655e1567f301866e82 100644 (file)
@@ -40,7 +40,6 @@
 #include "protocol/protocol.h"
 #include "protocol/protocol_api.h"
 #include "protocol/protocol_util.h"
-#include "common/system.h"
 #include "common/system_socket.h"
 #include "client/client.h"
 #include "client/client_sync.h"
index d7cd51a7cb3196cfaf55024611507f074ad40b4f..f352c9bdae6164602d21516f9607966118be0b9b 100644 (file)
@@ -30,7 +30,6 @@
 #include "protocol/protocol_util.h"
 
 #include "common/db_hash.h"
-#include "common/system.h"
 #include "common/system_socket.h"
 #include "common/logging.h"
 
index ec828389c9e7dc8c925e315b4b4d90ac1a49869f..fb3f277da018482b8b68faa3904407c6508fda6f 100644 (file)
@@ -380,23 +380,9 @@ def build(bld):
                             deps='replace talloc tevent tdb')
         ib_deps = ' ctdb-ib rdmacm ibverbs'
 
-    if sys.platform.startswith('linux'):
-        CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_linux.c')
-    elif sys.platform.startswith('aix'):
-        CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_aix.c')
-    elif sys.platform.startswith('freebsd'):
-        CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_freebsd.c')
-    elif sys.platform.startswith('gnukfreebsd'):
-        CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_kfreebsd.c')
-    elif sys.platform == 'gnu':
-        CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_gnu.c')
-    else:
-        Logs.error("Platform %s not supported" % sys.platform)
-
     bld.SAMBA_SUBSYSTEM('ctdb-system',
                         source=bld.SUBDIR('common',
-                                          'system_socket.c system.c') +
-                               CTDB_SYSTEM_SRC,
+                                          'system_socket.c system.c'),
                         includes='include',
                         deps='replace talloc tevent tdb pcap samba-util')