public inbox for b.a.t.m.a.n@lists.open-mesh.org
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: Sven Eckelmann <sven@narfation.org>
Subject: [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions
Date: Sun, 22 Sep 2013 16:42:24 +0200	[thread overview]
Message-ID: <1379860946-32669-2-git-send-email-sven@narfation.org> (raw)
In-Reply-To: <1379860946-32669-1-git-send-email-sven@narfation.org>

The first implementation of the IP translation functions in
cb75e019e74fc11f9547dadd51abbf3c9df2c5e7 ("batctl: Allow to use IPv4 addresses
for ping/traceroute") had is focus on implementing it only for IPv4. This is a
limitation when other layer 3 protocols are used.

For example, a port to IPv6 would either have to copy the functionality or do a
major refactoring when implementing the it resolv functionality. This is not
necessary when the functions already expect different layer 3 protocols in the
first place and make it easy to find the right place to modify them.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 functions.c | 86 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 63 insertions(+), 23 deletions(-)

diff --git a/functions.c b/functions.c
index 1a33d6d..e4aeb72 100644
--- a/functions.c
+++ b/functions.c
@@ -416,49 +416,68 @@ out:
 	return mac_result;
 }
 
-static uint32_t resolve_ipv4(const char *asc)
+static int resolve_l3addr(int ai_family, const char *asc, void *l3addr)
 {
 	int ret;
 	struct addrinfo hints;
 	struct addrinfo *res;
 	struct sockaddr_in *inet4;
-	uint32_t addr = 0;
 
 	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
+	hints.ai_family = ai_family;
 	ret = getaddrinfo(asc, NULL, &hints, &res);
 	if (ret)
-		return 0;
+		return -EADDRNOTAVAIL;
 
 	if (res) {
-		inet4 = (struct sockaddr_in *)res->ai_addr;
-		addr = inet4->sin_addr.s_addr;
+		switch (ai_family) {
+		case AF_INET:
+			inet4 = (struct sockaddr_in *)res->ai_addr;
+			memcpy(l3addr, &inet4->sin_addr.s_addr,
+			       sizeof(inet4->sin_addr.s_addr));
+			break;
+		default:
+			ret = -EINVAL;
+		}
 	}
 
 	freeaddrinfo(res);
-	return addr;
+	return ret;
 }
 
-static void request_arp(uint32_t ipv4_addr)
+static void request_mac_resolve(int ai_family, const void *l3addr)
 {
+	const struct sockaddr *sockaddr;
 	struct sockaddr_in inet4;
+	size_t sockaddr_len;
 	int sock;
 	char t = 0;
 
-	memset(&inet4, 0, sizeof(inet4));
-	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	sock = socket(ai_family, SOCK_DGRAM, IPPROTO_UDP);
 	if (sock < 0)
 		return;
 
-	inet4.sin_family = AF_INET;
-	inet4.sin_port = htons(9);
-	inet4.sin_addr.s_addr = ipv4_addr;
-	sendto(sock, &t, sizeof(t), 0, (const struct sockaddr *)&inet4,
-	       sizeof(inet4));
+	switch (ai_family) {
+	case AF_INET:
+		memset(&inet4, 0, sizeof(inet4));
+		inet4.sin_family = ai_family;
+		inet4.sin_port = htons(9);
+		memcpy(&inet4.sin_addr.s_addr, l3addr,
+		       sizeof(inet4.sin_addr.s_addr));
+		sockaddr = (const struct sockaddr *)&inet4;
+		sockaddr_len = sizeof(inet4);
+		break;
+	default:
+		close(sock);
+		return;
+	}
+
+	sendto(sock, &t, sizeof(t), 0, sockaddr, sockaddr_len);
 	close(sock);
 }
 
-static struct ether_addr *resolve_mac_from_arp(uint32_t ipv4_addr)
+static struct ether_addr *resolve_mac_from_cache(int ai_family,
+						 const void *l3addr)
 {
 	struct ether_addr mac_empty;
 	struct ether_addr *mac_result = NULL, *mac_tmp = NULL;
@@ -471,7 +490,12 @@ static struct ether_addr *resolve_mac_from_arp(uint32_t ipv4_addr)
 	size_t column;
 	char *token, *input, *saveptr;
 	int line_invalid;
+	uint32_t ipv4_addr;
 
+	if (ai_family != AF_INET)
+		return NULL;
+
+	memcpy(&ipv4_addr, l3addr, sizeof(ipv4_addr));
 	memset(&mac_empty, 0, sizeof(mac_empty));
 
 	f = fopen("/proc/net/arp", "r");
@@ -527,20 +551,30 @@ static struct ether_addr *resolve_mac_from_arp(uint32_t ipv4_addr)
 	return mac_result;
 }
 
-static struct ether_addr *resolve_mac_from_ipv4(const char *asc)
+static struct ether_addr *resolve_mac_from_addr(int ai_family, const char *asc)
 {
-	uint32_t ipv4_addr;
+	uint8_t ipv4_addr[4];
+	void *l3addr;
+	int ret;
 	int retries = 5;
 	struct ether_addr *mac_result = NULL;
 
-	ipv4_addr = resolve_ipv4(asc);
-	if (!ipv4_addr)
+	switch (ai_family) {
+	case AF_INET:
+		l3addr = ipv4_addr;
+		break;
+	default:
+		return NULL;
+	}
+
+	ret = resolve_l3addr(ai_family, asc, l3addr);
+	if (ret < 0)
 		return NULL;
 
 	while (retries-- && !mac_result) {
-		mac_result = resolve_mac_from_arp(ipv4_addr);
+		mac_result = resolve_mac_from_cache(ai_family, l3addr);
 		if (!mac_result) {
-			request_arp(ipv4_addr);
+			request_mac_resolve(ai_family, l3addr);
 			usleep(200000);
 		}
 	}
@@ -551,12 +585,18 @@ static struct ether_addr *resolve_mac_from_ipv4(const char *asc)
 struct ether_addr *resolve_mac(const char *asc)
 {
 	struct ether_addr *mac_result = NULL;
+	static const int ai_families[] = {AF_INET};
+	size_t i;
 
 	mac_result = ether_aton(asc);
 	if (mac_result)
 		goto out;
 
-	mac_result = resolve_mac_from_ipv4(asc);
+	for (i = 0; i < sizeof(ai_families) / sizeof(*ai_families); i++) {
+		mac_result = resolve_mac_from_addr(ai_families[i], asc);
+		if (mac_result)
+			goto out;
+	}
 
 out:
 	return mac_result;
-- 
1.8.4.rc3


  reply	other threads:[~2013-09-22 14:42 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-22 14:42 [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes Sven Eckelmann
2013-09-22 14:42 ` Sven Eckelmann [this message]
2013-09-24 12:09   ` [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions Marek Lindner
2013-09-22 14:42 ` [B.A.T.M.A.N.] [PATCH 3/4] batctl: Replace /proc/net/arp based resolver with rtnl Sven Eckelmann
2013-09-22 17:09   ` [B.A.T.M.A.N.] [PATCHv2 " Sven Eckelmann
2013-09-24 12:11     ` Marek Lindner
2013-09-22 14:43 ` [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver Sven Eckelmann
2013-09-24 12:15   ` Marek Lindner
2013-09-24 15:20   ` Antonio Quartulli
2013-09-24 18:28     ` Sven Eckelmann
2013-09-23  7:03 ` [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes Antonio Quartulli
2013-09-23  8:18   ` Sven Eckelmann
2013-09-23  8:20     ` Antonio Quartulli
2013-09-24 12:06 ` Marek Lindner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1379860946-32669-2-git-send-email-sven@narfation.org \
    --to=sven@narfation.org \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox