int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
struct timeval timeout,
uint32_t destnode,
- struct sockaddr_in *sin,
+ ctdb_sock_addr *addr,
const char *ifname)
{
TDB_DATA data;
int32_t res;
int ret, len;
- struct ctdb_control_ip_iface *gratious_arp;
+ struct ctdb_control_gratious_arp *gratious_arp;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
len = strlen(ifname)+1;
gratious_arp = talloc_size(tmp_ctx,
- offsetof(struct ctdb_control_ip_iface, iface) + len);
+ offsetof(struct ctdb_control_gratious_arp, iface) + len);
CTDB_NO_MEMORY(ctdb, gratious_arp);
- gratious_arp->sin = *sin;
+ gratious_arp->addr = *addr;
gratious_arp->len = len;
memcpy(&gratious_arp->iface[0], ifname, len);
- data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + len;
+ data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
data.dptr = (unsigned char *)gratious_arp;
ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
return ret;
}
+/*
+ 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
*/
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;
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;
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;
}
/*
struct holding a sockaddr_in and an interface name,
- used for send_gratious_arp and also add/remove public addresses
+ used to add/remove public addresses
*/
-//struct ctdb_control_gratious_arp {
struct ctdb_control_ip_iface {
struct sockaddr_in sin;
uint32_t mask;
char iface[1];
};
+/*
+ struct holding a ctdb_sock_addr and an interface name,
+ used for send_gratious_arp
+ */
+struct ctdb_control_gratious_arp {
+ ctdb_sock_addr addr;
+ uint32_t mask;
+ uint32_t len;
+ char iface[1];
+};
+
/*
struct for tcp_add and tcp_remove controls
*/
/* from takeover/system.c */
-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);
bool ctdb_sys_have_ip(struct sockaddr_in ip);
int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
const ctdb_sock_addr *src,
void ctdb_start_freeze(struct ctdb_context *ctdb);
bool parse_ip_port(const char *s, ctdb_sock_addr *saddr);
+bool parse_ip(const char *s, ctdb_sock_addr *saddr);
int ctdb_sys_open_capture_socket(const char *iface, void **private_data);
int ctdb_sys_close_capture_socket(void *private_data);
int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
struct timeval timeout,
uint32_t destnode,
- struct sockaddr_in *sin,
+ ctdb_sock_addr *addr,
const char *ifname);
int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
struct ctdb_takeover_arp {
struct ctdb_context *ctdb;
uint32_t count;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
struct ctdb_tcp_array *tcparray;
struct ctdb_vnn *vnn;
};
struct ctdb_tcp_array *tcparray;
- ret = ctdb_sys_send_arp(&arp->sin, arp->vnn->iface);
+ ret = ctdb_sys_send_arp(&arp->addr, arp->vnn->iface);
if (ret != 0) {
DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed (%s)\n", strerror(errno)));
}
struct takeover_callback_state *state =
talloc_get_type(private_data, struct takeover_callback_state);
struct ctdb_takeover_arp *arp;
- char *ip = inet_ntoa(state->sin->sin_addr);
struct ctdb_tcp_array *tcparray;
if (status != 0) {
+ char ip[128] = "";
+
+ switch(state->sin->sin_family){
+ case AF_INET:
+ if (inet_ntop(AF_INET, &state->sin->sin_addr, ip, sizeof(ip)) == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
+ }
+ break;
+ case AF_INET6:
+ if (inet_ntop(AF_INET6, &state->sin->sin_addr, ip, sizeof(ip)) == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
+ }
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " cant convert this address family to a string\n"));
+ break;
+ }
+
DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
ip, state->vnn->iface));
ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
if (!arp) goto failed;
arp->ctdb = ctdb;
- arp->sin = *state->sin;
+/* qqq convert state->sin from sockaddr_in to ctdb_sock_addr
+no need to cast then*/
+ arp->addr.ip = *((ctdb_addr_in *)state->sin);
arp->vnn = state->vnn;
tcparray = state->vnn->tcp_array;
struct control_gratious_arp {
struct ctdb_context *ctdb;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
const char *iface;
int count;
};
struct control_gratious_arp *arp = talloc_get_type(private_data,
struct control_gratious_arp);
- ret = ctdb_sys_send_arp(&arp->sin, arp->iface);
+ ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp failed (%s)\n", strerror(errno)));
}
*/
int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
{
- struct ctdb_control_ip_iface *gratious_arp = (struct ctdb_control_ip_iface *)indata.dptr;
+ struct ctdb_control_gratious_arp *gratious_arp = (struct ctdb_control_gratious_arp *)indata.dptr;
struct control_gratious_arp *arp;
-
/* verify the size of indata */
- if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
- DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
+ if (indata.dsize < offsetof(struct ctdb_control_gratious_arp, iface)) {
+ DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n", indata.dsize, offsetof(struct ctdb_control_gratious_arp, iface)));
return -1;
}
if (indata.dsize !=
- ( offsetof(struct ctdb_control_ip_iface, iface)
+ ( offsetof(struct ctdb_control_gratious_arp, iface)
+ gratious_arp->len ) ){
DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
"but should be %u bytes\n",
(unsigned)indata.dsize,
- (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+gratious_arp->len)));
+ (unsigned)(offsetof(struct ctdb_control_gratious_arp, iface)+gratious_arp->len)));
return -1;
}
CTDB_NO_MEMORY(ctdb, arp);
arp->ctdb = ctdb;
- arp->sin = gratious_arp->sin;
+ arp->addr = gratious_arp->addr;
arp->iface = talloc_strdup(arp, gratious_arp->iface);
CTDB_NO_MEMORY(ctdb, arp->iface);
arp->count = 0;
static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
{
int ret;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
if (argc < 2) {
usage();
}
- sin.sin_family = AF_INET;
- if (inet_aton(argv[0], &sin.sin_addr) == 0) {
- DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
+ if (!parse_ip(argv[0], &addr)) {
+ DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
return -1;
}
- ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &sin, argv[1]);
+ ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
if (ret != 0) {
DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
return ret;