From a8211f9d1f939f093be9aa041696f91b8d4479a9 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sat, 14 Jul 2007 10:27:34 +1000 Subject: add an initial system_aix.c to manage raw sockets under aix (This used to be ctdb commit 277527befedd6f5dfde1c51698245197afd83d99) --- ctdb/common/system_aix.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 ctdb/common/system_aix.c (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c new file mode 100644 index 00000000000..872c4cbb73b --- /dev/null +++ b/ctdb/common/system_aix.c @@ -0,0 +1,344 @@ +/* + 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 . +*/ + + +#include "includes.h" +#include "system/network.h" +#include "system/filesys.h" +#include "system/wait.h" +#include +#include "../include/ctdb_private.h" +#include +#include +#include + + + + +/* 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, htons(IPPROTO_RAW)); + if (s == -1) { + DEBUG(0,(" 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(0,(" failed to setup IP headers (%s)\n", + strerror(errno))); + close(s); + return -1; + } + + set_nonblocking(s); + set_close_on_exec(s); + + return s; +} + + +/* + 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 + */ +static uint16_t tcp_checksum(uint16_t *data, size_t n, struct ip *ip) +{ + uint32_t sum = uint16_checksum(data, n); + uint16_t sum2; + + sum += uint16_checksum((uint16_t *)&ip->ip_src, sizeof(ip->ip_src)); + sum += uint16_checksum((uint16_t *)&ip->ip_dst, sizeof(ip->ip_dst)); + sum += ip->ip_p + n; + sum = (sum & 0xFFFF) + (sum >> 16); + sum = (sum & 0xFFFF) + (sum >> 16); + sum2 = htons(sum); + sum2 = ~sum2; + if (sum2 == 0) { + return 0xFFFF; + } + return sum2; +} + +/* + Send tcp segment from the specified IP/port to the specified + destination IP/port. + + This is used to trigger the receiving host into sending its own ACK, + which should trigger early detection of TCP reset by the client + after IP takeover + + This can also be used to send RST segments (if rst is true) and also + if correct seq and ack numbers are provided. + */ +int ctdb_sys_send_tcp(int s, + const struct sockaddr_in *dest, + const struct sockaddr_in *src, + uint32_t seq, uint32_t ack, int rst) +{ + int ret; + struct { + struct ip ip; + struct tcphdr tcp; + } pkt; + + /* for now, we only handle AF_INET addresses */ + if (src->sin_family != AF_INET || dest->sin_family != AF_INET) { + DEBUG(0,(__location__ " not an ipv4 address\n")); + return -1; + } + + memset(&pkt, 0, sizeof(pkt)); + pkt.ip.ip_v = 4; + pkt.ip.ip_hl = sizeof(pkt.ip)/4; + pkt.ip.ip_len = htons(sizeof(pkt)); + pkt.ip.ip_ttl = 255; + pkt.ip.ip_p = IPPROTO_TCP; + pkt.ip.ip_src.s_addr = src->sin_addr.s_addr; + pkt.ip.ip_dst.s_addr = dest->sin_addr.s_addr; + pkt.ip.ip_sum = 0; + + pkt.tcp.th_sport = src->sin_port; + pkt.tcp.th_dport = dest->sin_port; + pkt.tcp.th_seq = seq; + pkt.tcp.th_ack = ack; + pkt.tcp.th_flags = TH_ACK; + if (rst) { + pkt.tcp.th_flags = TH_RST; + } + pkt.tcp.th_off = sizeof(pkt.tcp)/4; + pkt.tcp.th_win = htons(1234); + pkt.tcp.th_sum = tcp_checksum((uint16_t *)&pkt.tcp, sizeof(pkt.tcp), &pkt.ip); + + ret = sendto(s, &pkt, sizeof(pkt), 0, (struct sockaddr *)dest, sizeof(*dest)); + if (ret != sizeof(pkt)) { + DEBUG(0,(__location__ " failed sendto (%s)\n", strerror(errno))); + return -1; + } + + 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(const char *ip) +{ + struct sockaddr_in sin; + int s; + int ret; + + sin.sin_port = 0; + inet_aton(ip, &sin.sin_addr); + sin.sin_family = AF_INET; + s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == -1) { + return false; + } + ret = bind(s, (struct sockaddr *)&sin, sizeof(sin)); + 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) +{ + pcap_t *pt; + + pt=pcap_open_live(iface, 100, 0, 0, NULL); + if (pt == NULL) { + DEBUG(0,("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; +} + + + +/* + send gratuitous arp reply after we have taken over an ip address + + saddr is the address we are trying to claim + iface is the interface name we will be using to claim the address + */ +int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface) +{ + /* We dont do grat arp on aix yet */ + 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;iether_type != htons(ETHERTYPE_IP)) { + return -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; + } + + /* 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->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; +} + + + -- cgit From 4ac749bfa48d691f88b1f4db24a00bc079a02034 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 10 Sep 2007 07:20:44 +1000 Subject: change the signature to ctdb_sys_have_ip() to also return: a bool that specifies whether the ip was held by a loopback adaptor or not the name of the interface where the ip was held when we release an ip address from an interface, move the ip address over to the loopback interface when we release an ip address after we have move it onto loopback, use 60.nfs to kill off the server side (the local part) of the tcp connection so that the tcp connections dont survive a failover/failback 61.nfstickle, since we kill hte tcp connections when we release an ip address we no longer need to restart the nfs service in 61.nfstickle update ctdb_takeover to use the new signature for ctdb_sys_have_ip when we add a tcp connection to kill in ctdb_killtcp_add_connection() check if either the srouce or destination address match a known public address (This used to be ctdb commit f9fd2a4719c50f6b8e01d0a1b3a74b76b52ecaf3) --- ctdb/common/system_aix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 872c4cbb73b..0587e83f032 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -165,12 +165,16 @@ int ctdb_sys_send_tcp(int s, 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(const char *ip) +bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname) { struct sockaddr_in sin; int s; int ret; + if (is_loopback) { + DEBUG(0,(__location__ " NOT IMPLEMENTED YET: ctdb_sys_have_ip() does not yet support is_loopback on AIX. This needs to be implemented similar to system_linux.c\n")); + } + sin.sin_port = 0; inet_aton(ip, &sin.sin_addr); sin.sin_family = AF_INET; -- cgit From f3ae1cdb0262bacada40329d3a7c8f64411fc06a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Sep 2007 14:27:29 +1000 Subject: - use struct sockaddr_in more consistently instead of string addresses - allow for public_address lines with a defaulting interface (This used to be ctdb commit 29cb760f76e639a0f2ce1d553645a9dc26ee09e5) --- ctdb/common/system_aix.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 0587e83f032..5d5af103362 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -165,24 +165,21 @@ int ctdb_sys_send_tcp(int s, 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(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname) +bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname) { - struct sockaddr_in sin; int s; int ret; - + if (is_loopback) { DEBUG(0,(__location__ " NOT IMPLEMENTED YET: ctdb_sys_have_ip() does not yet support is_loopback on AIX. This needs to be implemented similar to system_linux.c\n")); } - sin.sin_port = 0; - inet_aton(ip, &sin.sin_addr); - sin.sin_family = AF_INET; + ip.sin_port = 0; s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == -1) { return false; } - ret = bind(s, (struct sockaddr *)&sin, sizeof(sin)); + ret = bind(s, (struct sockaddr *)&ip, sizeof(ip)); close(s); return ret == 0; } -- cgit From 3c0f61cb9279c5116e38a066be8db56d20bdf7db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Sep 2007 10:45:06 +1000 Subject: we don't need the is_loopback logic in ctdb any more (This used to be ctdb commit 4ecf29ade0099c7180932288191de9840c8d90a9) --- ctdb/common/system_aix.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 5d5af103362..f296e17d819 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -165,15 +165,11 @@ int ctdb_sys_send_tcp(int s, 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, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname) +bool ctdb_sys_have_ip(struct sockaddr_in ip) { int s; int ret; - if (is_loopback) { - DEBUG(0,(__location__ " NOT IMPLEMENTED YET: ctdb_sys_have_ip() does not yet support is_loopback on AIX. This needs to be implemented similar to system_linux.c\n")); - } - ip.sin_port = 0; s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == -1) { -- cgit From f6e53f433bf8e184ffc281f14c4eacda1ffc935c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Feb 2008 20:07:15 +1100 Subject: merge from ronnie (This used to be ctdb commit e7b57d38cf7255be823a223cf15b7526285b4f1c) --- ctdb/common/system_aix.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index f296e17d819..50f14180618 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -41,14 +41,14 @@ int ctdb_sys_open_sending_socket(void) s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW)); if (s == -1) { - DEBUG(0,(" failed to open raw socket (%s)\n", + 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(0,(" failed to setup IP headers (%s)\n", + DEBUG(DEBUG_CRIT, (" failed to setup IP headers (%s)\n", strerror(errno))); close(s); return -1; @@ -123,7 +123,7 @@ int ctdb_sys_send_tcp(int s, /* for now, we only handle AF_INET addresses */ if (src->sin_family != AF_INET || dest->sin_family != AF_INET) { - DEBUG(0,(__location__ " not an ipv4 address\n")); + DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address\n")); return -1; } @@ -151,7 +151,7 @@ int ctdb_sys_send_tcp(int s, ret = sendto(s, &pkt, sizeof(pkt), 0, (struct sockaddr *)dest, sizeof(*dest)); if (ret != sizeof(pkt)) { - DEBUG(0,(__location__ " failed sendto (%s)\n", strerror(errno))); + DEBUG(DEBUG_CRIT,(__location__ " failed sendto (%s)\n", strerror(errno))); return -1; } @@ -191,7 +191,7 @@ int ctdb_sys_open_capture_socket(const char *iface, void **private_data) pt=pcap_open_live(iface, 100, 0, 0, NULL); if (pt == NULL) { - DEBUG(0,("Failed to open capture device %s\n", iface)); + DEBUG(DEBUG_CRIT,("Failed to open capture device %s\n", iface)); return -1; } *((pcap_t **)private_data) = pt; -- cgit From 909ff219e0c1de995feb18547d18864d02695161 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 14 May 2008 15:47:47 +1000 Subject: Start implementing support for ipv6. This enhances the framework for sending tcp tickles to be able to send ipv6 tickles as well. Since we can not use one single RAW socket to send both handcrafted ipv4 and ipv6 packets, instead of always opening TWO sockets, one ipv4 and one ipv6 we get rid of the helper ctdb_sys_open_sending_socket() and just open (and close) a raw socket of the appropriate type inside ctdb_sys_send_tcp(). We know which type of socket v4/v6 to use based on the sin_family of the destination address. Since ctdb_sys_send_tcp() opens its own socket we no longer nede to pass a socket descriptor as a parameter. Get rid of this redundant parameter and fixup all callers. (This used to be ctdb commit 406a2a1e364cf71eb15e5aeec3b87c62f825da92) --- ctdb/common/system_aix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 50f14180618..d455ac73dd7 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -31,6 +31,9 @@ +#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 */ @@ -59,7 +62,7 @@ int ctdb_sys_open_sending_socket(void) return s; } - +#endif /* uint16 checksum for n bytes -- cgit From 7d39ac131b520f309bc7b6ff05eac7be58a32f86 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 4 Jun 2008 15:13:00 +1000 Subject: convert handling of gratious arps and their controls and helpers to use the ctdb_sock_addr structure so tehy work for both ipv4 and ipv6 (This used to be ctdb commit 86d6f53512d358ff68b58dac737ffa7576c3cce6) --- ctdb/common/system_aix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index d455ac73dd7..8742a393c9d 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -220,7 +220,7 @@ int ctdb_sys_close_capture_socket(void *private_data) saddr is the address we are trying to claim iface is the interface name we will be using to claim the address */ -int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface) +int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) { /* We dont do grat arp on aix yet */ return 0; -- cgit From 52f03be2d9e1c87f1ae3a02bf5aae447482c4364 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 9 Jul 2008 10:17:39 +1000 Subject: From Chris Cowan, patch to make aix compile again (This used to be ctdb commit 77255bb5523b8d132770a0a7d4ba29ec9e5043cc) --- ctdb/common/system_aix.c | 82 +++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 28 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 8742a393c9d..b08692d1774 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -23,8 +23,10 @@ #include "system/network.h" #include "system/filesys.h" #include "system/wait.h" -#include #include "../include/ctdb_private.h" +#include +#include +#include #include #include #include @@ -113,47 +115,71 @@ static uint16_t tcp_checksum(uint16_t *data, size_t n, struct ip *ip) This can also be used to send RST segments (if rst is true) and also if correct seq and ack numbers are provided. */ -int ctdb_sys_send_tcp(int s, - const struct sockaddr_in *dest, - const struct sockaddr_in *src, +int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, + const ctdb_sock_addr *src, uint32_t seq, uint32_t ack, int rst) { - int ret; + int s; + int ret; + uint32_t one = 1; + ctdb_sock_addr *tmpdest; + struct { struct ip ip; struct tcphdr tcp; - } pkt; + } ip4pkt; + /* for now, we only handle AF_INET addresses */ - if (src->sin_family != AF_INET || dest->sin_family != AF_INET) { + if (src->ip.sin_family != AF_INET || dest->ip.sin_family != AF_INET) { DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address\n")); return -1; } - memset(&pkt, 0, sizeof(pkt)); - pkt.ip.ip_v = 4; - pkt.ip.ip_hl = sizeof(pkt.ip)/4; - pkt.ip.ip_len = htons(sizeof(pkt)); - pkt.ip.ip_ttl = 255; - pkt.ip.ip_p = IPPROTO_TCP; - pkt.ip.ip_src.s_addr = src->sin_addr.s_addr; - pkt.ip.ip_dst.s_addr = dest->sin_addr.s_addr; - pkt.ip.ip_sum = 0; - - pkt.tcp.th_sport = src->sin_port; - pkt.tcp.th_dport = dest->sin_port; - pkt.tcp.th_seq = seq; - pkt.tcp.th_ack = ack; - pkt.tcp.th_flags = TH_ACK; + + + s = socket(AF_INET, SOCK_RAW, htons(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_nonblocking(s); + set_close_on_exec(s); + + memset(&ip4pkt, 0, sizeof(ip4pkt)); + ip4pkt.ip.ip_v = 4; + ip4pkt.ip.ip_hl = sizeof(ip4pkt.ip)/4; + ip4pkt.ip.ip_len = htons(sizeof(ip4pkt)); + ip4pkt.ip.ip_ttl = 255; + ip4pkt.ip.ip_p = IPPROTO_TCP; + ip4pkt.ip.ip_src.s_addr = src->ip.sin_addr.s_addr; + ip4pkt.ip.ip_dst.s_addr = dest->ip.sin_addr.s_addr; + ip4pkt.ip.ip_sum = 0; + + ip4pkt.tcp.th_sport = src->ip.sin_port; + ip4pkt.tcp.th_dport = dest->ip.sin_port; + ip4pkt.tcp.th_seq = seq; + ip4pkt.tcp.th_ack = ack; + ip4pkt.tcp.th_flags = TH_ACK; if (rst) { - pkt.tcp.th_flags = TH_RST; + ip4pkt.tcp.th_flags = TH_RST; } - pkt.tcp.th_off = sizeof(pkt.tcp)/4; - pkt.tcp.th_win = htons(1234); - pkt.tcp.th_sum = tcp_checksum((uint16_t *)&pkt.tcp, sizeof(pkt.tcp), &pkt.ip); + ip4pkt.tcp.th_off = sizeof(ip4pkt.tcp)/4; + ip4pkt.tcp.th_win = htons(1234); + ip4pkt.tcp.th_sum = tcp_checksum((uint16_t *)&ip4pkt.tcp, sizeof(ip4pkt.tcp), &ip4pkt.ip); - ret = sendto(s, &pkt, sizeof(pkt), 0, (struct sockaddr *)dest, sizeof(*dest)); - if (ret != sizeof(pkt)) { + ret = sendto(s, &ip4pkt, sizeof(ip4pkt), 0, (struct sockaddr *)dest, sizeof(*dest)); + if (ret != sizeof(ip4pkt)) { DEBUG(DEBUG_CRIT,(__location__ " failed sendto (%s)\n", strerror(errno))); return -1; } -- cgit From ef997d344f189891ec201a71e8f57bc1ca88992c Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 19 Aug 2008 14:58:29 +1000 Subject: initial ipv6 patch Signed-off-by: Ronnie Sahlberg (This used to be ctdb commit 1f131f21386f428bbbbb29098d56c2f64596583b) --- ctdb/common/system_aix.c | 85 ++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 38 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index b08692d1774..03d997ff6fc 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -194,17 +194,17 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, 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) +bool ctdb_sys_have_ip(ctdb_sock_addr *addr) { int s; int ret; - ip.sin_port = 0; - s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + addr->sa.sa_port = 0; + s = socket(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (s == -1) { return false; } - ret = bind(s, (struct sockaddr *)&ip, sizeof(ip)); + ret = bind(s, (struct sockaddr *)addr, sizeof(ctdb_sock_addr)); close(s); return ret == 0; } @@ -306,7 +306,7 @@ 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; @@ -326,44 +326,53 @@ 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->sin_addr.s_addr = ip->ip_src.s_addr; + src->sin_port = tcp->th_sport; + dst->ip.sin_family = AF_INET; + 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; - /* 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_IP)) { +see system_linux.c for what should go in here + 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; } -- cgit From 7a78a78a1c0de5ef3f470326eee2c1ca7e57e607 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 8 Sep 2008 08:57:42 +1000 Subject: From C Cowan. Patch to make AIX compile with the new ipv6 additions. (This used to be ctdb commit e26ce5140ed005725f8b7ac8ba23a180fd7d5337) --- ctdb/common/system_aix.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 03d997ff6fc..8fe630d8a39 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -199,7 +199,7 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *addr) int s; int ret; - addr->sa.sa_port = 0; + addr->ip.sin_port = 0; s = socket(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (s == -1) { return false; @@ -312,6 +312,7 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data, 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; @@ -353,22 +354,44 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data, tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip); /* tell the caller which one we've found */ - src->ip.sin_family = AF_INET; - src->sin_addr.s_addr = ip->ip_src.s_addr; - src->sin_port = tcp->th_sport; - dst->ip.sin_family = AF_INET; - 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; + 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; return 0; #ifndef ETHERTYPE_IP6 #define ETHERTYPE_IP6 0x86dd #endif - } else if (eth->ether_type == htons(ETHERTYPE_IP)) { -see system_linux.c for what should go in here + } 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; } -- cgit From 8ec92c92e273b8cb1ac4beb75fc872337c76ac5e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 19 Jan 2009 19:08:37 +0100 Subject: ctdb_sys_have_ip: fix ipv6 support for aix, too. Michael Signed-off-by: Michael Adam (This used to be ctdb commit 8b5f1e80e3e2e9ca2198e1baee8af36aa5d6c5b5) --- ctdb/common/system_aix.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 8fe630d8a39..d5ca4778646 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -194,12 +194,22 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, 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(ctdb_sock_addr *addr) +bool ctdb_sys_have_ip(ctdb_sock_addr *_addr) { int s; int ret; + ctdb_sock_addr __addr = *_addr; + ctdb_sock_addr *addr = &__addr; - addr->ip.sin_port = 0; + 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; -- cgit From 839dec1b1224313f2dc11c42bfb9c0e648944fe1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 28 Feb 2009 03:08:31 +0100 Subject: move common code of system_linux.c and system_aix.c into new system_common.c Michael (This used to be ctdb commit 124874847e5e03ce2a44bddfe778f01dfb0a7a03) --- ctdb/common/system_aix.c | 52 ------------------------------------------------ 1 file changed, 52 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index d5ca4778646..5fe54130d42 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -66,23 +66,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 */ @@ -187,41 +170,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(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 */ int ctdb_sys_open_capture_socket(const char *iface, void **private_data) -- cgit From 64378fea58c28ce9cf1ad6171e41bccb88c1bafc Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 6 Sep 2011 16:11:00 +1000 Subject: Check interfaces: when reading the public addresses file to create the vnn list check that the actual interface exist, print error and fail startup if the interface does not exist. (This used to be ctdb commit cd33bbe6454b7b0316bdfffbd06c67b29779e873) --- ctdb/common/system_aix.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 5fe54130d42..1404a829013 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -357,4 +357,8 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data, } +bool ctdb_sys_check_iface_exists(const char *iface) +{ + return true; +} -- cgit From bb3d6698e91a3971dd7e7470666864c8213cbaf7 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sat, 5 Nov 2011 19:04:40 +0100 Subject: Move platform-specific code to common/system_* This removes #ifdef AIX and ease the addition of new platforms. (This used to be ctdb commit 2fd1067a075fe0e4b2a36d4ea18af139d03f17bf) --- ctdb/common/system_aix.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 1404a829013..c17598a3af8 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -362,3 +362,14 @@ bool ctdb_sys_check_iface_exists(const char *iface) 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; +} + -- cgit From c3ee62439fe9db1560db29d13b7433bfadcda40d Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 6 Dec 2011 13:15:41 +1100 Subject: Return the peer_pid properly to the caller (This used to be ctdb commit 0f15a2c65db8f8b4ac0d5ad2755b9aa3c2a8b279) --- ctdb/common/system_aix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index c17598a3af8..388e943de0b 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -368,7 +368,7 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) socklen_t crl = sizeof(struct peercred_struct); int ret; if ((ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl) == 0)) { - peer_pid = cr.pid; + *peer_pid = cr.pid; } return ret; } -- cgit From 1011d10a515f165c29fb5470ad04acf856a6217a Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 6 Jun 2012 11:50:25 +1000 Subject: common: Add routines to get process and lock information Currently these functions are implemented only for Linux. Signed-off-by: Amitay Isaacs (This used to be ctdb commit be4051326b0c6a0fd301561af10fd15a0e90023b) --- ctdb/common/system_aix.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 388e943de0b..16b627ca479 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -373,3 +373,20 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) return ret; } +char *ctdb_get_process_name(pid_t pid) +{ + /* FIXME: not implemented */ + return NULL; +} + +bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info) +{ + /* FIXME: not implemented */ + return false; +} + +bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid) +{ + /* FIXME: not implemented */ + return false; +} -- cgit From 384b9b2a7b124436c16682903ad7c967e8891e84 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Mon, 14 Jan 2013 11:23:46 +0100 Subject: common: Detailed platform-specific FIXME Signed-off-by: Mathieu Parent (This used to be ctdb commit d202b2fdd4fd70172e5e44583627b57a1b7ad2ed) --- ctdb/common/system_aix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 16b627ca479..3f2e92aa6c6 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -359,6 +359,7 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data, bool ctdb_sys_check_iface_exists(const char *iface) { + /* FIXME AIX: Interface always considered present */ return true; } @@ -375,18 +376,18 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) char *ctdb_get_process_name(pid_t pid) { - /* FIXME: not implemented */ + /* FIXME AIX: get_process_name not implemented */ return NULL; } bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info) { - /* FIXME: not implemented */ + /* FIXME AIX: get_lock_info not implemented */ return false; } bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid) { - /* FIXME: not implemented */ + /* FIXME AIX: get_blocker_pid not implemented */ return false; } -- cgit From 264f847631eb140f134c58e595989eb5af4ae711 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Mon, 14 Jan 2013 17:48:01 +0100 Subject: common: Don't lie on unimplemented gratuitous arp Signed-off-by: Mathieu Parent (This used to be ctdb commit b054193d1d19a8eef998fa690899501f79badb8a) --- ctdb/common/system_aix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 3f2e92aa6c6..35363d330a3 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -206,8 +206,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 dont do gratuitous arp yet */ + return -1; } -- cgit From 500b26e48f97719f4ba1f92b6f86bb341c2e5525 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Tue, 9 Jul 2013 12:24:59 +1000 Subject: common/system: Add ctdb_set_process_name() function Signed-off-by: Amitay Isaacs (This used to be ctdb commit fc3689c977f48d7988eed0654fb8e5ce4b8bfc8b) --- ctdb/common/system_aix.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ctdb/common/system_aix.c') diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c index 35363d330a3..41f61aecb5d 100644 --- a/ctdb/common/system_aix.c +++ b/ctdb/common/system_aix.c @@ -380,6 +380,12 @@ char *ctdb_get_process_name(pid_t pid) return NULL; } +int ctdb_set_process_name(const char *name) +{ + /* FIXME AIX: set_process_name not implemented */ + return -ENOSYS; +} + bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info) { /* FIXME AIX: get_lock_info not implemented */ -- cgit