summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2009-05-21 14:10:45 +1000
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2009-05-21 14:10:45 +1000
commit9921e1ec214fb21c77e7ab28793682cebb1f5e3c (patch)
tree54503267ec9e96390d984d2cb316c448583d5d4c /ctdb
parent26e1486db7cafa86d9deceb225820631dfeb2a92 (diff)
downloadsamba-9921e1ec214fb21c77e7ab28793682cebb1f5e3c.tar.gz
samba-9921e1ec214fb21c77e7ab28793682cebb1f5e3c.tar.xz
samba-9921e1ec214fb21c77e7ab28793682cebb1f5e3c.zip
change the socket we use for sending grautious ARPs from AF_INET/SOCK_PACKET to AF_PACKET/SOCK_RAW
(This used to be ctdb commit 2c4c20d7803f4449f8d463314c40d4734ec80e2f)
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/common/system_linux.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
index a771e3ba04..7a580cc584 100644
--- a/ctdb/common/system_linux.c
+++ b/ctdb/common/system_linux.c
@@ -28,7 +28,7 @@
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <net/if_arp.h>
-
+#include <netpacket/packet.h>
#ifndef ETHERTYPE_IP6
#define ETHERTYPE_IP6 0x86dd
@@ -71,7 +71,7 @@ static uint16_t tcp_checksum6(uint16_t *data, size_t n, struct ip6_hdr *ip6)
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
{
int s, ret;
- struct sockaddr sa;
+ struct sockaddr_ll sall;
struct ether_header *eh;
struct arphdr *ah;
struct ip6_hdr *ip6;
@@ -79,17 +79,25 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
struct ifreq if_hwaddr;
unsigned char buffer[78]; /* ipv6 neigh solicitation size */
char *ptr;
+ char bdcast[] = {0xff,0xff,0xff,0xff,0xff,0xff};
+ struct ifreq ifr;
- ZERO_STRUCT(sa);
+ ZERO_STRUCT(sall);
switch (addr->ip.sin_family) {
case AF_INET:
- s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
+ s = socket(PF_PACKET, SOCK_RAW, htons(ETHERTYPE_ARP));
if (s == -1){
DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
return -1;
}
+ strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+ if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+ DEBUG(DEBUG_CRIT,(__location__ " interface '%s' not found\n", iface));
+ return -1;
+ }
+
/* get the mac address */
strcpy(if_hwaddr.ifr_name, iface);
ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
@@ -136,8 +144,12 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
memcpy(ptr, &addr->ip.sin_addr, 4);
ptr+=4;
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+ sall.sll_family = AF_PACKET;
+ sall.sll_halen = 6;
+ memcpy(&sall.sll_addr[0], bdcast, sall.sll_halen);
+ sall.sll_protocol = htons(ETH_P_ALL);
+ sall.sll_ifindex = ifr.ifr_ifindex;
+ ret = sendto(s, buffer, 64, 0, (struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
close(s);
DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
@@ -156,8 +168,7 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
memcpy(ptr, &addr->ip.sin_addr, 4);
ptr+=4;
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+ ret = sendto(s, buffer, 64, 0, (struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
return -1;
@@ -166,12 +177,18 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
close(s);
break;
case AF_INET6:
- s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_IP6));
+ s = socket(PF_PACKET, SOCK_RAW, htons(ETHERTYPE_ARP));
if (s == -1){
DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
return -1;
}
+ strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+ if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+ DEBUG(DEBUG_CRIT,(__location__ " interface '%s' not found\n", iface));
+ return -1;
+ }
+
/* get the mac address */
strcpy(if_hwaddr.ifr_name, iface);
ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
@@ -213,8 +230,12 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
icmp6->icmp6_cksum = tcp_checksum6((uint16_t *)icmp6, ntohs(ip6->ip6_plen), ip6);
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- ret = sendto(s, buffer, 78, 0, &sa, sizeof(sa));
+ sall.sll_family = AF_PACKET;
+ sall.sll_halen = 6;
+ memcpy(&sall.sll_addr[0], bdcast, sall.sll_halen);
+ sall.sll_protocol = htons(ETH_P_ALL);
+ sall.sll_ifindex = ifr.ifr_ifindex;
+ ret = sendto(s, buffer, 78, 0, (struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
close(s);
DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));