diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2008-06-04 15:13:00 +1000 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2008-06-04 15:13:00 +1000 |
commit | 7d39ac131b520f309bc7b6ff05eac7be58a32f86 (patch) | |
tree | 0f51fb02d4bee59d811d13447c037f7ba71d6942 /ctdb/common | |
parent | 1c88f422d54798d22d1f933d04e82dc97cfdfdaf (diff) | |
download | samba-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.c | 19 | ||||
-rw-r--r-- | ctdb/common/system_aix.c | 2 | ||||
-rw-r--r-- | ctdb/common/system_linux.c | 160 |
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; } |