summaryrefslogtreecommitdiff
path: root/ctdb/common
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2008-06-04 15:13:00 +1000
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2008-06-04 15:13:00 +1000
commit7d39ac131b520f309bc7b6ff05eac7be58a32f86 (patch)
tree0f51fb02d4bee59d811d13447c037f7ba71d6942 /ctdb/common
parent1c88f422d54798d22d1f933d04e82dc97cfdfdaf (diff)
downloadsamba-7d39ac131b520f309bc7b6ff05eac7be58a32f86.tar.gz
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)
Diffstat (limited to 'ctdb/common')
-rw-r--r--ctdb/common/ctdb_util.c19
-rw-r--r--ctdb/common/system_aix.c2
-rw-r--r--ctdb/common/system_linux.c160
3 files changed, 101 insertions, 80 deletions
diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index cb535115b42..a92a53f1957 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/common/ctdb_util.c
@@ -371,6 +371,25 @@ bool parse_ip_port(const char *addr, ctdb_sock_addr *saddr)
}
/*
+ parse an ip
+ */
+bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
+{
+ char *p;
+ bool ret;
+
+ /* now is this a ipv4 or ipv6 address ?*/
+ p = index(addr, ':');
+ if (p == NULL) {
+ ret = parse_ipv4(addr, 0, saddr);
+ } else {
+ ret = parse_ipv6(addr, 0, saddr);
+ }
+
+ return ret;
+}
+
+/*
parse a ip/mask pair
*/
bool parse_ip_mask(const char *s, struct sockaddr_in *ip, unsigned *mask)
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;
diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
index fb50c6b29b2..32db545b09f 100644
--- a/ctdb/common/system_linux.c
+++ b/ctdb/common/system_linux.c
@@ -36,7 +36,7 @@
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)
{
int s, ret;
struct sockaddr sa;
@@ -48,92 +48,94 @@ int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface)
ZERO_STRUCT(sa);
- /* for now, we only handle AF_INET addresses */
- if (saddr->sin_family != AF_INET) {
- DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address (family is %u)\n", saddr->sin_family));
- return -1;
- }
+ switch (addr->ip.sin_family) {
+ case AF_INET:
+ s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
+ if (s == -1){
+ DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
+ return -1;
+ }
- s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
- if (s == -1){
- DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
- return -1;
- }
+ /* get the mac address */
+ strcpy(if_hwaddr.ifr_name, iface);
+ ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
+ if ( ret < 0 ) {
+ close(s);
+ DEBUG(DEBUG_CRIT,(__location__ " ioctl failed\n"));
+ return -1;
+ }
+ if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) {
+ DEBUG(DEBUG_DEBUG,("Ignoring loopback arp request\n"));
+ close(s);
+ return 0;
+ }
+ if (if_hwaddr.ifr_hwaddr.sa_family != AF_LOCAL) {
+ close(s);
+ errno = EINVAL;
+ DEBUG(DEBUG_CRIT,(__location__ " not an ethernet address family (0x%x)\n",
+ if_hwaddr.ifr_hwaddr.sa_family));
+ return -1;
+ }
- /* get the mac address */
- strcpy(if_hwaddr.ifr_name, iface);
- ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
- if ( ret < 0 ) {
- close(s);
- DEBUG(DEBUG_CRIT,(__location__ " ioctl failed\n"));
- return -1;
- }
- if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) {
- DEBUG(DEBUG_DEBUG,("Ignoring loopback arp request\n"));
- close(s);
- return 0;
- }
- if (if_hwaddr.ifr_hwaddr.sa_family != AF_LOCAL) {
- close(s);
- errno = EINVAL;
- DEBUG(DEBUG_CRIT,(__location__ " not an ethernet address family (0x%x)\n",
- if_hwaddr.ifr_hwaddr.sa_family));
- return -1;
- }
+ memset(buffer, 0 , 64);
+ eh = (struct ether_header *)buffer;
+ memset(eh->ether_dhost, 0xff, ETH_ALEN);
+ memcpy(eh->ether_shost, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+ eh->ether_type = htons(ETHERTYPE_ARP);
+
+ ah = (struct arphdr *)&buffer[sizeof(struct ether_header)];
+ ah->ar_hrd = htons(ARPHRD_ETHER);
+ ah->ar_pro = htons(ETH_P_IP);
+ ah->ar_hln = ETH_ALEN;
+ ah->ar_pln = 4;
+
+ /* send a gratious arp */
+ ah->ar_op = htons(ARPOP_REQUEST);
+ ptr = (char *)&ah[1];
+ memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+ ptr+=ETH_ALEN;
+ memcpy(ptr, &addr->ip.sin_addr, 4);
+ ptr+=4;
+ memset(ptr, 0, ETH_ALEN);
+ ptr+=ETH_ALEN;
+ 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));
+ if (ret < 0 ){
+ close(s);
+ DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+ return -1;
+ }
+
+ /* send unsolicited arp reply broadcast */
+ ah->ar_op = htons(ARPOP_REPLY);
+ ptr = (char *)&ah[1];
+ memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+ ptr+=ETH_ALEN;
+ memcpy(ptr, &addr->ip.sin_addr, 4);
+ ptr+=4;
+ memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+ ptr+=ETH_ALEN;
+ 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));
+ if (ret < 0 ){
+ DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+ return -1;
+ }
- memset(buffer, 0 , 64);
- eh = (struct ether_header *)buffer;
- memset(eh->ether_dhost, 0xff, ETH_ALEN);
- memcpy(eh->ether_shost, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
- eh->ether_type = htons(ETHERTYPE_ARP);
-
- ah = (struct arphdr *)&buffer[sizeof(struct ether_header)];
- ah->ar_hrd = htons(ARPHRD_ETHER);
- ah->ar_pro = htons(ETH_P_IP);
- ah->ar_hln = ETH_ALEN;
- ah->ar_pln = 4;
-
- /* send a gratious arp */
- ah->ar_op = htons(ARPOP_REQUEST);
- ptr = (char *)&ah[1];
- memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
- ptr+=ETH_ALEN;
- memcpy(ptr, &saddr->sin_addr, 4);
- ptr+=4;
- memset(ptr, 0, ETH_ALEN);
- ptr+=ETH_ALEN;
- memcpy(ptr, &saddr->sin_addr, 4);
- ptr+=4;
-
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
- if (ret < 0 ){
close(s);
- DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
- return -1;
- }
-
- /* send unsolicited arp reply broadcast */
- ah->ar_op = htons(ARPOP_REPLY);
- ptr = (char *)&ah[1];
- memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
- ptr+=ETH_ALEN;
- memcpy(ptr, &saddr->sin_addr, 4);
- ptr+=4;
- memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
- ptr+=ETH_ALEN;
- memcpy(ptr, &saddr->sin_addr, 4);
- ptr+=4;
-
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
- if (ret < 0 ){
- DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+ break;
+ default:
+ DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address (family is %u)\n", addr->ip.sin_family));
return -1;
}
- close(s);
return 0;
}