#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);
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
#endif
#include "lib/util/debug.h"
+#include "lib/util/blocking.h"
#include "protocol/protocol.h"
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 */
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__ */
#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"
#include "protocol/protocol_util.h"
#include "common/db_hash.h"
-#include "common/system.h"
#include "common/system_socket.h"
#include "common/logging.h"
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')