[PATCH 2/6] Add totemip_iface_check based on totemip_getifaddrs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Also Linux and BSD/Darwin specific bits are no longer needed, so they
are gone.

Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx>
---
 exec/totemip.c |  324 +++++++++++++-------------------------------------------
 1 files changed, 74 insertions(+), 250 deletions(-)

diff --git a/exec/totemip.c b/exec/totemip.c
index a0c166b..93f933d 100644
--- a/exec/totemip.c
+++ b/exec/totemip.c
@@ -427,256 +427,6 @@ int totemip_iface_check(struct totem_ip_address *bindnet,
 }
 #endif
 
-#if defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN)
-int totemip_iface_check(struct totem_ip_address *bindnet,
-	struct totem_ip_address *boundto,
-	int *interface_up,
-	int *interface_num,
-	int mask_high_bit)
-{
-#define NEXT_IFR(a)	((struct ifreq *)((u_char *)&(a)->ifr_addr +\
-	((a)->ifr_addr.sa_len ? (a)->ifr_addr.sa_len : sizeof((a)->ifr_addr))))
-
-	struct sockaddr_in *intf_addr_mask;
-	struct sockaddr_storage bindnet_ss;
-	struct sockaddr_in *intf_addr_sin;
-	struct sockaddr_in *bindnet_sin = (struct sockaddr_in *)&bindnet_ss;
-	struct ifaddrs *ifap, *ifa;
-	int res = -1;
-	int addrlen;
-
-	*interface_up = 0;
-	*interface_num = 0;
-
-	totemip_totemip_to_sockaddr_convert(bindnet,
-		0, &bindnet_ss, &addrlen);
-
-	if (getifaddrs(&ifap) != 0)
-		return -1;
-
-	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-		intf_addr_sin	= (struct sockaddr_in *)ifa->ifa_addr;
-		intf_addr_mask	= (struct sockaddr_in *)ifa->ifa_netmask;
-
-		if (intf_addr_sin->sin_family != AF_INET)
-			continue;
-
-		if ( bindnet_sin->sin_family == AF_INET &&
-			 (intf_addr_sin->sin_addr.s_addr & intf_addr_mask->sin_addr.s_addr) ==
-			 (bindnet_sin->sin_addr.s_addr & intf_addr_mask->sin_addr.s_addr)) {
-
-			totemip_copy(boundto, bindnet);
-			memcpy(boundto->addr, &intf_addr_sin->sin_addr, sizeof(intf_addr_sin->sin_addr));
-
-			/* Get interface infos
-			 */
-			*interface_up = ifa->ifa_flags & IFF_UP;
-			*interface_num = if_nametoindex(ifa->ifa_name);
-
-			/*
-			 * Handle case, when nodeid is set to 0 or not set.
-			 */
-			if (bindnet->family == AF_INET && bindnet->nodeid == 0) {
-				unsigned int nodeid = 0;
-				memcpy (&nodeid, boundto->addr, sizeof (int));
-#if _BYTE_ORDER == _BIG_ENDIAN
-				nodeid = swab32 (nodeid);
-#endif
-				/*
-				 * Mask 32nd bit off to workaround bugs in other peoples code
-				 * (if configuration requests it).
-				 */
-				if (mask_high_bit) {
-					nodeid &= 0x7FFFFFFF;
-				}
-				boundto->nodeid = nodeid;
-			}
-			res = 0;
-			break; /* for */
-		}
-	}
-
-	freeifaddrs(ifap);
-
-	return (res);
-}
-#elif defined(COROSYNC_LINUX)
-
-static void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
-{
-        while (RTA_OK(rta, len)) {
-                if (rta->rta_type <= max)
-                        tb[rta->rta_type] = rta;
-                rta = RTA_NEXT(rta,len);
-        }
-}
-
-int totemip_iface_check(struct totem_ip_address *bindnet,
-			struct totem_ip_address *boundto,
-			int *interface_up,
-			int *interface_num,
-			int mask_high_bit)
-{
-	int fd;
-	int res = -1;
-	struct {
-                struct nlmsghdr nlh;
-                struct rtgenmsg g;
-        } req;
-        struct sockaddr_nl nladdr;
-	struct totem_ip_address ipaddr;
-	static char rcvbuf[NETLINK_BUFSIZE];
-
-	*interface_up = 0;
-	*interface_num = 0;
-	memset(&ipaddr, 0, sizeof(ipaddr));
-
-	/* Make sure we preserve these */
-	ipaddr.family = bindnet->family;
-	ipaddr.nodeid = bindnet->nodeid;
-
-	/* Ask netlink for a list of interface addresses */
-	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-	if (fd <0)
-		return -1;
-
-        setsockopt(fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf));
-
-        memset(&nladdr, 0, sizeof(nladdr));
-        nladdr.nl_family = AF_NETLINK;
-
-        memset(&req, 0, sizeof(req));
-        req.nlh.nlmsg_len = sizeof(req);
-        req.nlh.nlmsg_type = RTM_GETADDR;
-        req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
-        req.nlh.nlmsg_pid = 0;
-        req.nlh.nlmsg_seq = 1;
-        req.g.rtgen_family = bindnet->family;
-
-        if (sendto(fd, (void *)&req, sizeof(req), 0,
-		   (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0)  {
-		close(fd);
-		return -1;
-	}
-
-	/* Look through the return buffer for our address */
-	while (1)
-	{
-		int status;
-		struct nlmsghdr *h;
-		struct iovec iov = { rcvbuf, sizeof(rcvbuf) };
-		struct msghdr msg = {
-			(void*)&nladdr, sizeof(nladdr),
-			&iov,   1,
-			NULL,   0,
-			0
-		};
-
-		status = recvmsg(fd, &msg, 0);
-		if (!status) {
-			close(fd);
-			return -1;
-		}
-
-		h = (struct nlmsghdr *)rcvbuf;
-		if (h->nlmsg_type == NLMSG_DONE)
-			break;
-
-		if (h->nlmsg_type == NLMSG_ERROR) {
-			close(fd);
-			return -1;
-		}
-
-		while (NLMSG_OK(h, status)) {
-			if (h->nlmsg_type == RTM_NEWADDR) {
-				struct ifaddrmsg *ifa = NLMSG_DATA(h);
-				struct rtattr *tb[IFA_MAX+1];
-				int len = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa));
-				int found_if = 0;
-
-				memset(tb, 0, sizeof(tb));
-
-				parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
-
-				memcpy(ipaddr.addr, RTA_DATA(tb[IFA_ADDRESS]), TOTEMIP_ADDRLEN);
-				if (totemip_equal(&ipaddr, bindnet)) {
-					found_if = 1;
-				}
-
-				/* If the address we have is an IPv4 network address, then
-				   substitute the actual IP address of this interface */
-				if (!found_if && tb[IFA_LOCAL] && ifa->ifa_family == AF_INET) {
-					uint32_t network;
-					uint32_t addr;
-					uint32_t netmask = htonl(~((1<<(32-ifa->ifa_prefixlen))-1));
-
-					memcpy(&network, RTA_DATA(tb[IFA_LOCAL]), sizeof(uint32_t));
-					memcpy(&addr, bindnet->addr, sizeof(uint32_t));
-
-					if ((addr & netmask) == (network & netmask)) {
-						memcpy(ipaddr.addr, RTA_DATA(tb[IFA_ADDRESS]), TOTEMIP_ADDRLEN);
-						found_if = 1;
-					}
-				}
-
-				if (found_if) {
-
-					/* Found it - check I/F is UP */
-					struct ifreq ifr;
-					int ioctl_fd; /* Can't do ioctls on netlink FDs */
-
-					ioctl_fd = socket(AF_INET, SOCK_STREAM, 0);
-					if (ioctl_fd < 0) {
-						close(fd);
-						return -1;
-					}
-					memset(&ifr, 0, sizeof(ifr));
-					ifr.ifr_ifindex = ifa->ifa_index;
-
-					/* SIOCGIFFLAGS needs an interface name */
-					status = ioctl(ioctl_fd, SIOCGIFNAME, &ifr);
-					status = ioctl(ioctl_fd, SIOCGIFFLAGS, &ifr);
-					close(ioctl_fd);
-					if (status) {
-						res = -1;
-						goto finished;
-					}
-
-					if (ifr.ifr_flags & IFF_UP)
-						*interface_up = 1;
-
-					*interface_num = ifa->ifa_index;
-					/*
-					 * Mask 32nd bit off to workaround bugs in other peoples code
-					 * (if configuration requests it).
-					 */
-					if (ipaddr.family == AF_INET && ipaddr.nodeid == 0) {
-						unsigned int nodeid = 0;
-						memcpy (&nodeid, ipaddr.addr, sizeof (int));
-#if __BYTE_ORDER == __BIG_ENDIAN
-                                                nodeid = swab32 (nodeid);
-#endif
-						if (mask_high_bit) {
-							nodeid &= 0x7FFFFFFF;
-						}
-						ipaddr.nodeid = nodeid;
-					}
-					totemip_copy (boundto, &ipaddr);
-					res = 0;
-					goto finished;
-				}
-			}
-
-			h = NLMSG_NEXT(h, status);
-		}
-	}
-	res = -1; /* address not found */
-finished:
-	close(fd);
-	return res;
-}
-#endif /* COROSYNC_LINUX */
-
 #ifdef HAVE_GETIFADDRS
 int totemip_getifaddrs(struct list_head *addrs)
 {
@@ -758,3 +508,77 @@ void totemip_freeifaddrs(struct list_head *addrs)
 	}
 	list_init(addrs);
 }
+
+int totemip_iface_check(struct totem_ip_address *bindnet,
+			struct totem_ip_address *boundto,
+			int *interface_up,
+			int *interface_num,
+			int mask_high_bit)
+{
+	struct list_head addrs;
+	struct list_head *list;
+	struct totem_ip_if_address *if_addr;
+	struct totem_ip_address bn_netaddr, if_netaddr;
+	socklen_t addr_len;
+	socklen_t si;
+	int res = -1;
+
+	if (totemip_getifaddrs(&addrs) == -1) {
+		return (-1);
+	}
+
+	for (list = addrs.next; list != &addrs; list = list->next) {
+		if_addr = list_entry(list, struct totem_ip_if_address, list);
+
+		if (bindnet->family != if_addr->ip_addr.family)
+			continue ;
+
+		addr_len = 0;
+
+		switch (bindnet->family) {
+		case AF_INET:
+			addr_len = sizeof(struct in_addr);
+			break;
+		case AF_INET6:
+			addr_len = sizeof(struct in6_addr);
+			break;
+		}
+
+		if (addr_len == 0)
+			continue ;
+
+		totemip_copy(&bn_netaddr, bindnet);
+		totemip_copy(&if_netaddr, &if_addr->ip_addr);
+
+		for (si = 0; si < addr_len; si++) {
+			bn_netaddr.addr[si] = bn_netaddr.addr[si] & if_addr->mask_addr.addr[si];
+			if_netaddr.addr[si] = if_netaddr.addr[si] & if_addr->mask_addr.addr[si];
+		}
+
+		if (totemip_equal(&bn_netaddr, &if_netaddr)) {
+			totemip_copy(boundto, &if_addr->ip_addr);
+			boundto->nodeid = bindnet->nodeid;
+			*interface_up = if_addr->interface_up;
+			*interface_num = if_addr->interface_num;
+
+			if (boundto->family == AF_INET && boundto->nodeid == 0) {
+				unsigned int nodeid = 0;
+				memcpy (&nodeid, boundto->addr, sizeof (int));
+#if __BYTE_ORDER == __BIG_ENDIAN
+                                nodeid = swab32 (nodeid);
+#endif
+				if (mask_high_bit) {
+					nodeid &= 0x7FFFFFFF;
+				}
+				boundto->nodeid = nodeid;
+			}
+
+			res = 0;
+			goto finished;
+		}
+	}
+
+finished:
+	totemip_freeifaddrs(&addrs);
+	return (res);
+}
-- 
1.7.1

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux