close(s);
return ret == 0;
}
+
+
+/* find which interface an ip address is currently assigned to */
+char *ctdb_sys_find_ifname(ctdb_sock_addr *addr)
+{
+ int s;
+ int size;
+ struct ifconf ifc;
+ char *ptr;
+
+ s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+ if (s == -1) {
+ DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket (%s)\n",
+ strerror(errno)));
+ return NULL;
+ }
+
+
+ size = sizeof(struct ifreq);
+ ifc.ifc_buf = NULL;
+ ifc.ifc_len = size;
+
+ while(ifc.ifc_len > (size - sizeof(struct ifreq))) {
+ size *= 2;
+
+ free(ifc.ifc_buf);
+ ifc.ifc_len = size;
+ ifc.ifc_buf = malloc(size);
+ memset(ifc.ifc_buf, 0, size);
+ if (ioctl(s, SIOCGIFCONF, (caddr_t)&ifc) < 0) {
+ DEBUG(DEBUG_CRIT,("Failed to read ifc buffer from socket\n"));
+ free(ifc.ifc_buf);
+ close(s);
+ return NULL;
+ }
+ }
+
+ for (ptr =(char *)ifc.ifc_buf; ptr < ((char *)ifc.ifc_buf) + ifc.ifc_len; ) {
+ char *ifname;
+ struct ifreq *ifr;
+
+ ifr = (struct ifreq *)ptr;
+
+#ifdef HAVE_SOCKADDR_LEN
+ if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
+ ptr += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
+ } else {
+ ptr += sizeof(ifr->ifr_name) + sizeof(struct sockaddr);
+ }
+#else
+ ptr += sizeof(struct ifreq);
+#endif
+
+ if (ifr->ifr_addr.sa_family != addr->sa.sa_family) {
+ continue;
+ }
+
+ switch (addr->sa.sa_family) {
+ case AF_INET:
+
+
+ if (memcmp(&addr->ip.sin_addr, &((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr, sizeof(addr->ip.sin_addr))) {
+ continue;
+ }
+ break;
+ case AF_INET6:
+ if (memcmp(&addr->ip6.sin6_addr, &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr, sizeof(addr->ip6.sin6_addr))) {
+ continue;
+ }
+ break;
+ }
+
+ ifname = strdup(ifr->ifr_name);
+ free(ifc.ifc_buf);
+ close(s);
+ return ifname;
+ }
+
+
+ free(ifc.ifc_buf);
+ close(s);
+
+ return NULL;
+}
uint32_t uint16_checksum(uint16_t *data, size_t n);
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface);
bool ctdb_sys_have_ip(ctdb_sock_addr *addr);
+char *ctdb_sys_find_ifname(ctdb_sock_addr *addr);
int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
const ctdb_sock_addr *src,
uint32_t seq, uint32_t ack, int rst);
return 0;
}
+/*
+ add a public ip address to a node
+ */
+static int control_ipiface(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ ctdb_sock_addr addr;
+
+ if (argc != 1) {
+ usage();
+ }
+
+ if (!parse_ip(argv[0], NULL, 0, &addr)) {
+ printf("Badly formed ip : %s\n", argv[0]);
+ return -1;
+ }
+
+ printf("IP on interface %s\n", ctdb_sys_find_ifname(&addr));
+
+ return 0;
+}
+
static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
{ "readkey", control_readkey, true, false, "read the content off a database key", "<tdb-file> <key>" },
{ "writekey", control_writekey, true, false, "write to a database key", "<tdb-file> <key> <value>" },
{ "checktcpport", control_chktcpport, false, true, "check if a service is bound to a specific tcp port or not", "<port>" },
+ { "ipiface", control_ipiface, true, true, "Find which interface an ip address is hsoted on", "<ip>" },
};
/*