*/
-#include "includes.h"
+#include "replace.h"
#include "system/network.h"
#include "system/filesys.h"
#include "system/wait.h"
-#include "../include/ctdb_private.h"
+
+#include "lib/util/debug.h"
+
+#include "protocol/protocol.h"
+
#include <netinet/if_ether.h>
#include <netinet/ip6.h>
#include <net/if_arp.h>
#include <sys/kinfo.h>
#include <pcap.h>
+#include "common/logging.h"
+#include "common/system.h"
#if 0
int s, ret;
uint32_t one = 1;
- s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+ s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == -1) {
DEBUG(DEBUG_CRIT,(" failed to open raw socket (%s)\n",
strerror(errno)));
}
#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
*/
- s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+ s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == -1) {
DEBUG(DEBUG_CRIT,(" failed to open raw socket (%s)\n",
strerror(errno)));
return 0;
}
-
-/*
- see if we currently have an interface with the given IP
-
- we try to bind to it, and if that fails then we don't have that IP
- on an interface
- */
-bool ctdb_sys_have_ip(struct sockaddr_in ip)
-{
- int s;
- int ret;
-
- ip.sin_port = 0;
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s == -1) {
- return false;
- }
- ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
- close(s);
- return ret == 0;
-}
-
-
-
-
/* This function is used to open a raw socket to capture from
*/
int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
*/
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
{
- /* We dont do grat arp on aix yet */
- return 0;
+ /* FIXME AIX: We don't do gratuitous arp yet */
+ return -1;
}
}
int ctdb_sys_read_tcp_packet(int s, void *private_data,
- struct sockaddr_in *src, struct sockaddr_in *dst,
+ ctdb_sock_addr *src, ctdb_sock_addr *dst,
uint32_t *ack_seq, uint32_t *seq)
{
int ret;
struct ether_header *eth;
struct ip *ip;
+ struct ip6_hdr *ip6;
struct tcphdr *tcp;
struct ctdb_killtcp_connection *conn;
struct pcap_pkthdr pkthdr;
/* Ethernet */
eth = (struct ether_header *)buffer;
- /* We are only interested in IP packets */
- if (eth->ether_type != htons(ETHERTYPE_IP)) {
- return -1;
- }
+ /* we want either IPv4 or IPv6 */
+ if (eth->ether_type == htons(ETHERTYPE_IP)) {
+ /* IP */
+ ip = (struct ip *)(eth+1);
- /* IP */
- ip = (struct ip *)(eth+1);
+ /* We only want IPv4 packets */
+ if (ip->ip_v != 4) {
+ return -1;
+ }
+ /* Dont look at fragments */
+ if ((ntohs(ip->ip_off)&0x1fff) != 0) {
+ return -1;
+ }
+ /* we only want TCP */
+ if (ip->ip_p != IPPROTO_TCP) {
+ return -1;
+ }
- /* We only want IPv4 packets */
- if (ip->ip_v != 4) {
- return -1;
- }
- /* Dont look at fragments */
- if ((ntohs(ip->ip_off)&0x1fff) != 0) {
- return -1;
- }
- /* we only want TCP */
- if (ip->ip_p != IPPROTO_TCP) {
- return -1;
- }
+ /* make sure its not a short packet */
+ if (offsetof(struct tcphdr, th_ack) + 4 +
+ (ip->ip_hl*4) > ret) {
+ return -1;
+ }
+ /* TCP */
+ tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
+
+ /* tell the caller which one we've found */
+ src->ip.sin_family = AF_INET;
+ src->ip.sin_addr.s_addr = ip->ip_src.s_addr;
+ src->ip.sin_port = tcp->th_sport;
+ dst->ip.sin_family = AF_INET;
+ dst->ip.sin_addr.s_addr = ip->ip_dst.s_addr;
+ dst->ip.sin_port = tcp->th_dport;
+ *ack_seq = tcp->th_ack;
+ *seq = tcp->th_seq;
- /* make sure its not a short packet */
- if (offsetof(struct tcphdr, th_ack) + 4 +
- (ip->ip_hl*4) > ret) {
- return -1;
+
+ return 0;
+#ifndef ETHERTYPE_IP6
+#define ETHERTYPE_IP6 0x86dd
+#endif
+ } else if (eth->ether_type == htons(ETHERTYPE_IP6)) {
+ /* IP6 */
+ ip6 = (struct ip6_hdr *)(eth+1);
+
+ /* we only want TCP */
+ if (ip6->ip6_nxt != IPPROTO_TCP) {
+ return -1;
+ }
+
+ /* TCP */
+ tcp = (struct tcphdr *)(ip6+1);
+
+ /* tell the caller which one we've found */
+ src->ip6.sin6_family = AF_INET6;
+ src->ip6.sin6_port = tcp->th_sport;
+ src->ip6.sin6_addr = ip6->ip6_src;
+
+ dst->ip6.sin6_family = AF_INET6;
+ dst->ip6.sin6_port = tcp->th_dport;
+ dst->ip6.sin6_addr = ip6->ip6_dst;
+
+ *ack_seq = tcp->th_ack;
+ *seq = tcp->th_seq;
+
+ return 0;
}
- /* TCP */
- tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
-
- /* tell the caller which one we've found */
- src->sin_addr.s_addr = ip->ip_src.s_addr;
- src->sin_port = tcp->th_sport;
- dst->sin_addr.s_addr = ip->ip_dst.s_addr;
- dst->sin_port = tcp->th_dport;
- *ack_seq = tcp->th_ack;
- *seq = tcp->th_seq;
- return 0;
+ return -1;
}
+bool ctdb_sys_check_iface_exists(const char *iface)
+{
+ /* FIXME AIX: Interface always considered present */
+ return true;
+}
+int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
+{
+ struct peercred_struct cr;
+ socklen_t crl = sizeof(struct peercred_struct);
+ int ret;
+ if ((ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl) == 0)) {
+ *peer_pid = cr.pid;
+ }
+ return ret;
+}