* [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions
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
2013-09-24 12:09 ` 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
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Sven Eckelmann @ 2013-09-22 14:42 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
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
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions
2013-09-22 14:42 ` [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions Sven Eckelmann
@ 2013-09-24 12:09 ` Marek Lindner
0 siblings, 0 replies; 14+ messages in thread
From: Marek Lindner @ 2013-09-24 12:09 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
On Sunday 22 September 2013 16:42:24 Sven Eckelmann wrote:
> 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(-)
Applied in revision daf6aa6.
Thanks,
Marek
^ permalink raw reply [flat|nested] 14+ messages in thread
* [B.A.T.M.A.N.] [PATCH 3/4] batctl: Replace /proc/net/arp based resolver with rtnl
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 ` [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions Sven Eckelmann
@ 2013-09-22 14:42 ` Sven Eckelmann
2013-09-22 17:09 ` [B.A.T.M.A.N.] [PATCHv2 " Sven Eckelmann
2013-09-22 14:43 ` [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver Sven Eckelmann
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Sven Eckelmann @ 2013-09-22 14:42 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
The /proc/net/arp based solution to resolve mac addresses from IP adresses is
limited to IPv4 addresses. The table for IPv6 addresses to MAC addresses is
only available through rtnetlink. rtnetlink also provides the IPv4 neighbor
table and should therefore should be prefered over the /proc/net/arp solution
to build an infrastructure for further work on the resolver.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
functions.c | 215 +++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 155 insertions(+), 60 deletions(-)
diff --git a/functions.c b/functions.c
index e4aeb72..e56479d 100644
--- a/functions.c
+++ b/functions.c
@@ -21,7 +21,6 @@
#include <netinet/ether.h>
-#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
@@ -35,6 +34,11 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <stdint.h>
+#include <linux/netlink.h>
+#include <net/ethernet.h>
+#include <linux/rtnetlink.h>
+#include <linux/neighbour.h>
+#include <sys/uio.h>
#include "main.h"
#include "functions.h"
@@ -476,78 +480,169 @@ static void request_mac_resolve(int ai_family, const void *l3addr)
close(sock);
}
+static int resolve_mac_from_cache_open(int ai_family)
+{
+ int socknl;
+ int ret;
+ struct {
+ struct nlmsghdr hdr;
+ struct ndmsg msg;
+ } nlreq;
+ struct sockaddr_nl addrnl;
+ static uint32_t nr_call = 0;
+ uint32_t pid = (++nr_call + getpid()) & 0x3FFFFF;
+
+ memset(&addrnl, 0, sizeof(addrnl));
+ addrnl.nl_family = AF_NETLINK;
+ addrnl.nl_pid = pid;
+ addrnl.nl_groups = 0;
+
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(nlreq.msg));
+ nlreq.hdr.nlmsg_type = RTM_GETNEIGH;
+ nlreq.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ nlreq.msg.ndm_family = ai_family;
+
+ socknl = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (socknl < 0)
+ goto out;
+
+ ret = bind(socknl, (struct sockaddr*)&addrnl, sizeof(addrnl));
+ if (ret < 0)
+ goto outclose;
+
+ ret = send(socknl, &nlreq, nlreq.hdr.nlmsg_len, 0);
+ if (ret < 0)
+ goto outclose;
+out:
+ return socknl;
+outclose:
+ close(socknl);
+ return ret;
+}
+
+static ssize_t resolve_mac_from_cache_dump(int ai_family, void **buf)
+{
+ struct iovec iov;
+ struct msghdr msg;
+ size_t buflen = 4096;
+ ssize_t ret = -1;
+ int socknl;
+
+ *buf = NULL;
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = 0;
+ msg.msg_control = NULL;
+ msg.msg_flags = 0;
+
+retry:
+ socknl = resolve_mac_from_cache_open(ai_family);
+ if (socknl < 0) {
+ ret = socknl;
+ free(*buf);
+ goto out;
+ }
+
+ *buf = realloc(*buf, buflen);
+ if (!*buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ iov.iov_len = buflen;
+ iov.iov_base = *buf;
+
+ ret = recvmsg(socknl, &msg, 0);
+ if (ret < 0)
+ goto err;
+
+ close(socknl);
+ if (msg.msg_flags & MSG_TRUNC) {
+ buflen *= 2;
+ goto retry;
+ }
+
+out:
+ return ret;
+err:
+ close(socknl);
+ free(*buf);
+ *buf = NULL;
+ return ret;
+}
+
static struct ether_addr *resolve_mac_from_cache(int ai_family,
const void *l3addr)
{
+ static uint8_t l3addr_tmp[16];
+ int l3found, llfound;
struct ether_addr mac_empty;
- struct ether_addr *mac_result = NULL, *mac_tmp = NULL;
- struct sockaddr_in inet4;
- int ret;
- FILE *f;
- size_t len = 0;
- char *line = NULL;
- int skip_line = 1;
- size_t column;
- char *token, *input, *saveptr;
- int line_invalid;
- uint32_t ipv4_addr;
+ struct ether_addr mac_tmp;
+ struct ether_addr *mac_result = NULL;
+ void *buf = NULL;
+ struct nlmsghdr *nh;
+ struct ndmsg *ndmsg;
+ struct rtattr *rtattr;
+ size_t len_payload;
+ ssize_t len;
+ size_t l3_len;
- 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");
- if (!f)
- return NULL;
+ switch (ai_family) {
+ case AF_INET:
+ l3_len = 4;
+ break;
+ default:
+ l3_len = 0;
+ }
- while (getline(&line, &len, f) != -1) {
- if (skip_line) {
- skip_line = 0;
- continue;
- }
+ len = resolve_mac_from_cache_dump(ai_family, &buf);
+ if (len < 0)
+ goto out;
- line_invalid = 0;
- column = 0;
- input = line;
- while ((token = strtok_r(input, " \t", &saveptr))) {
- input = NULL;
-
- if (column == 0) {
- ret = inet_pton(AF_INET, token, &inet4.sin_addr);
- if (ret != 1) {
- line_invalid = 1;
- break;
- }
- }
-
- if (column == 3) {
- mac_tmp = ether_aton(token);
- if (!mac_tmp || memcmp(mac_tmp, &mac_empty,
- sizeof(mac_empty)) == 0) {
- line_invalid = 1;
- break;
- }
- }
-
- column++;
- }
-
- if (column < 4)
- line_invalid = 1;
-
- if (line_invalid)
- continue;
-
- if (ipv4_addr == inet4.sin_addr.s_addr) {
- mac_result = mac_tmp;
+ for (nh = buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
+ if (nh->nlmsg_type == NLMSG_DONE)
break;
+
+ l3found = 0;
+ llfound = 0;
+ ndmsg = NLMSG_DATA(nh);
+ len_payload = RTM_PAYLOAD(nh);
+
+ for (rtattr = RTM_RTA(ndmsg); RTA_OK(rtattr, len_payload);
+ rtattr = RTA_NEXT(rtattr, len_payload)) {
+ switch (rtattr->rta_type) {
+ case NDA_DST:
+ memcpy(&l3addr_tmp, RTA_DATA(rtattr), l3_len);
+ l3found = 1;
+ break;
+ case NDA_LLADDR:
+ memcpy(&mac_tmp, RTA_DATA(rtattr),
+ sizeof(mac_tmp));
+ if (memcmp(&mac_tmp, &mac_empty,
+ sizeof(mac_empty)) == 0)
+ llfound = 0;
+ else
+ llfound = 1;
+ break;
+ }
+ }
+
+ if (llfound && l3found) {
+ if (memcmp(&l3addr_tmp, l3addr, l3_len) == 0) {
+ mac_result = &mac_tmp;
+ break;
+ }
}
}
- free(line);
- fclose(f);
+ free(buf);
+out:
return mac_result;
}
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 14+ messages in thread* [B.A.T.M.A.N.] [PATCHv2 3/4] batctl: Replace /proc/net/arp based resolver with rtnl
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 ` Sven Eckelmann
2013-09-24 12:11 ` Marek Lindner
0 siblings, 1 reply; 14+ messages in thread
From: Sven Eckelmann @ 2013-09-22 17:09 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
The /proc/net/arp based solution to resolve mac addresses from IP adresses is
limited to IPv4 addresses. The table for IPv6 addresses to MAC addresses is
only available through rtnetlink. rtnetlink also provides the IPv4 neighbor
table and should therefore should be prefered over the /proc/net/arp solution
to build an infrastructure for further work on the resolver.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
V2:
* optimize for large ARP caches
functions.c | 251 +++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 188 insertions(+), 63 deletions(-)
diff --git a/functions.c b/functions.c
index e4aeb72..697c217 100644
--- a/functions.c
+++ b/functions.c
@@ -21,7 +21,6 @@
#include <netinet/ether.h>
-#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
@@ -35,6 +34,12 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <stdint.h>
+#include <linux/netlink.h>
+#include <net/ethernet.h>
+#include <linux/rtnetlink.h>
+#include <linux/neighbour.h>
+#include <sys/uio.h>
+#include <errno.h>
#include "main.h"
#include "functions.h"
@@ -476,78 +481,198 @@ static void request_mac_resolve(int ai_family, const void *l3addr)
close(sock);
}
-static struct ether_addr *resolve_mac_from_cache(int ai_family,
- const void *l3addr)
+static int resolve_mac_from_cache_open(int ai_family)
{
- struct ether_addr mac_empty;
- struct ether_addr *mac_result = NULL, *mac_tmp = NULL;
- struct sockaddr_in inet4;
+ int socknl;
int ret;
- FILE *f;
- size_t len = 0;
- char *line = NULL;
- int skip_line = 1;
- size_t column;
- char *token, *input, *saveptr;
- int line_invalid;
- uint32_t ipv4_addr;
+ struct {
+ struct nlmsghdr hdr;
+ struct ndmsg msg;
+ } nlreq;
+ struct sockaddr_nl addrnl;
+ static uint32_t nr_call = 0;
+ uint32_t pid = (++nr_call + getpid()) & 0x3FFFFF;
- if (ai_family != AF_INET)
- return NULL;
+ memset(&addrnl, 0, sizeof(addrnl));
+ addrnl.nl_family = AF_NETLINK;
+ addrnl.nl_pid = pid;
+ addrnl.nl_groups = 0;
- memcpy(&ipv4_addr, l3addr, sizeof(ipv4_addr));
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(nlreq.msg));
+ nlreq.hdr.nlmsg_type = RTM_GETNEIGH;
+ nlreq.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ nlreq.msg.ndm_family = ai_family;
+
+ socknl = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (socknl < 0)
+ goto out;
+
+ ret = bind(socknl, (struct sockaddr*)&addrnl, sizeof(addrnl));
+ if (ret < 0)
+ goto outclose;
+
+ ret = send(socknl, &nlreq, nlreq.hdr.nlmsg_len, 0);
+ if (ret < 0)
+ goto outclose;
+out:
+ return socknl;
+outclose:
+ close(socknl);
+ return ret;
+}
+
+static ssize_t resolve_mac_from_cache_dump(int sock, void **buf, size_t *buflen)
+{
+ struct iovec iov;
+ struct msghdr msg;
+ ssize_t ret = -1;
+ int flags = MSG_PEEK | MSG_TRUNC;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = 0;
+ msg.msg_control = NULL;
+ msg.msg_flags = 0;
+
+ iov.iov_len = *buflen;
+ iov.iov_base = *buf;
+
+ ret = recvmsg(sock, &msg, flags);
+ if (ret < 0)
+ goto err;
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ if ((size_t)ret <= *buflen) {
+ ret = -ENOBUFS;
+ goto err;
+ }
+
+ while (*buflen <= (size_t)ret) {
+ if (*buflen == 0)
+ *buflen = 1;
+ *buflen *= 2;
+ }
+
+ *buf = realloc(*buf, *buflen);
+ if (!*buf) {
+ ret = -ENOMEM;
+ *buflen = 0;
+ goto err;
+ }
+ }
+ flags = 0;
+
+ ret = recvmsg(sock, &msg, flags);
+ if (ret < 0)
+ goto err;
+
+ return ret;
+err:
+ free(*buf);
+ *buf = NULL;
+ return ret;
+}
+
+static int resolve_mac_from_cache_parse(struct ndmsg *ndmsg, size_t len_payload,
+ struct ether_addr *mac_addr,
+ uint8_t *l3addr,
+ size_t l3_len)
+{
+ int l3found, llfound;
+ struct rtattr *rtattr;
+ struct ether_addr mac_empty;
+
+ l3found = 0;
+ llfound = 0;
memset(&mac_empty, 0, sizeof(mac_empty));
- f = fopen("/proc/net/arp", "r");
- if (!f)
- return NULL;
-
- while (getline(&line, &len, f) != -1) {
- if (skip_line) {
- skip_line = 0;
- continue;
- }
-
- line_invalid = 0;
- column = 0;
- input = line;
- while ((token = strtok_r(input, " \t", &saveptr))) {
- input = NULL;
-
- if (column == 0) {
- ret = inet_pton(AF_INET, token, &inet4.sin_addr);
- if (ret != 1) {
- line_invalid = 1;
- break;
- }
- }
-
- if (column == 3) {
- mac_tmp = ether_aton(token);
- if (!mac_tmp || memcmp(mac_tmp, &mac_empty,
- sizeof(mac_empty)) == 0) {
- line_invalid = 1;
- break;
- }
- }
-
- column++;
- }
-
- if (column < 4)
- line_invalid = 1;
-
- if (line_invalid)
- continue;
-
- if (ipv4_addr == inet4.sin_addr.s_addr) {
- mac_result = mac_tmp;
+ for (rtattr = RTM_RTA(ndmsg); RTA_OK(rtattr, len_payload);
+ rtattr = RTA_NEXT(rtattr, len_payload)) {
+ switch (rtattr->rta_type) {
+ case NDA_DST:
+ memcpy(l3addr, RTA_DATA(rtattr), l3_len);
+ l3found = 1;
+ break;
+ case NDA_LLADDR:
+ memcpy(mac_addr, RTA_DATA(rtattr), ETH_ALEN);
+ if (memcmp(mac_addr, &mac_empty,
+ sizeof(mac_empty)) == 0)
+ llfound = 0;
+ else
+ llfound = 1;
break;
}
}
- free(line);
- fclose(f);
+ return l3found && llfound;
+}
+
+static struct ether_addr *resolve_mac_from_cache(int ai_family,
+ const void *l3addr)
+{
+ static uint8_t l3addr_tmp[16];
+ struct ether_addr mac_tmp;
+ struct ether_addr *mac_result = NULL;
+ void *buf = NULL;
+ size_t buflen;
+ struct nlmsghdr *nh;
+ ssize_t len;
+ size_t l3_len;
+ int socknl;
+ int parsed;
+ int finished = 0;
+
+ switch (ai_family) {
+ case AF_INET:
+ l3_len = 4;
+ break;
+ default:
+ l3_len = 0;
+ }
+
+ buflen = 8192;
+ buf = malloc(buflen);
+ if (!buf)
+ goto err;
+
+ socknl = resolve_mac_from_cache_open(ai_family);
+ if (socknl < 0)
+ goto err;
+
+
+ while (!finished) {
+ len = resolve_mac_from_cache_dump(socknl, &buf, &buflen);
+ if (len < 0)
+ goto err_sock;
+
+ for (nh = buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
+ if (nh->nlmsg_type == NLMSG_DONE) {
+ finished = 1;
+ break;
+ }
+
+ parsed = resolve_mac_from_cache_parse(NLMSG_DATA(nh),
+ RTM_PAYLOAD(nh),
+ &mac_tmp,
+ l3addr_tmp,
+ l3_len);
+ if (parsed) {
+ if (memcmp(&l3addr_tmp, l3addr, l3_len) == 0) {
+ mac_result = &mac_tmp;
+ break;
+ }
+ }
+ }
+ }
+
+err_sock:
+ close(socknl);
+err:
+ free(buf);
return mac_result;
}
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [B.A.T.M.A.N.] [PATCHv2 3/4] batctl: Replace /proc/net/arp based resolver with rtnl
2013-09-22 17:09 ` [B.A.T.M.A.N.] [PATCHv2 " Sven Eckelmann
@ 2013-09-24 12:11 ` Marek Lindner
0 siblings, 0 replies; 14+ messages in thread
From: Marek Lindner @ 2013-09-24 12:11 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
On Sunday 22 September 2013 19:09:31 Sven Eckelmann wrote:
> The /proc/net/arp based solution to resolve mac addresses from IP adresses
> is limited to IPv4 addresses. The table for IPv6 addresses to MAC addresses
> is only available through rtnetlink. rtnetlink also provides the IPv4
> neighbor table and should therefore should be prefered over the
> /proc/net/arp solution to build an infrastructure for further work on the
> resolver.
>
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> V2:
> * optimize for large ARP caches
>
> functions.c | 251
> +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file
> changed, 188 insertions(+), 63 deletions(-)
Applied in revision 4885dc1.
Thanks,
Marek
^ permalink raw reply [flat|nested] 14+ messages in thread
* [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver
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 ` [B.A.T.M.A.N.] [PATCH 2/4] batctl: Reduce IPv4 focus of mac resolve functions Sven Eckelmann
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 14:43 ` Sven Eckelmann
2013-09-24 12:15 ` Marek Lindner
2013-09-24 15:20 ` Antonio Quartulli
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-24 12:06 ` Marek Lindner
4 siblings, 2 replies; 14+ messages in thread
From: Sven Eckelmann @ 2013-09-22 14:43 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
functions.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/functions.c b/functions.c
index e56479d..45c2120 100644
--- a/functions.c
+++ b/functions.c
@@ -426,6 +426,7 @@ static int resolve_l3addr(int ai_family, const char *asc, void *l3addr)
struct addrinfo hints;
struct addrinfo *res;
struct sockaddr_in *inet4;
+ struct sockaddr_in6 *inet6;
memset(&hints, 0, sizeof(hints));
hints.ai_family = ai_family;
@@ -440,6 +441,11 @@ static int resolve_l3addr(int ai_family, const char *asc, void *l3addr)
memcpy(l3addr, &inet4->sin_addr.s_addr,
sizeof(inet4->sin_addr.s_addr));
break;
+ case AF_INET6:
+ inet6 = (struct sockaddr_in6 *)res->ai_addr;
+ memcpy(l3addr, &inet6->sin6_addr.s6_addr,
+ sizeof(inet6->sin6_addr.s6_addr));
+ break;
default:
ret = -EINVAL;
}
@@ -453,6 +459,7 @@ static void request_mac_resolve(int ai_family, const void *l3addr)
{
const struct sockaddr *sockaddr;
struct sockaddr_in inet4;
+ struct sockaddr_in6 inet6;
size_t sockaddr_len;
int sock;
char t = 0;
@@ -471,6 +478,15 @@ static void request_mac_resolve(int ai_family, const void *l3addr)
sockaddr = (const struct sockaddr *)&inet4;
sockaddr_len = sizeof(inet4);
break;
+ case AF_INET6:
+ memset(&inet6, 0, sizeof(inet6));
+ inet6.sin6_family = ai_family;
+ inet6.sin6_port = htons(9);
+ memcpy(&inet6.sin6_addr.s6_addr, l3addr,
+ sizeof(inet6.sin6_addr.s6_addr));
+ sockaddr = (const struct sockaddr *)&inet6;
+ sockaddr_len = sizeof(inet6);
+ break;
default:
close(sock);
return;
@@ -597,6 +613,9 @@ static struct ether_addr *resolve_mac_from_cache(int ai_family,
case AF_INET:
l3_len = 4;
break;
+ case AF_INET6:
+ l3_len = 16;
+ break;
default:
l3_len = 0;
}
@@ -649,6 +668,7 @@ out:
static struct ether_addr *resolve_mac_from_addr(int ai_family, const char *asc)
{
uint8_t ipv4_addr[4];
+ uint8_t ipv6_addr[16];
void *l3addr;
int ret;
int retries = 5;
@@ -658,6 +678,9 @@ static struct ether_addr *resolve_mac_from_addr(int ai_family, const char *asc)
case AF_INET:
l3addr = ipv4_addr;
break;
+ case AF_INET6:
+ l3addr = ipv6_addr;
+ break;
default:
return NULL;
}
@@ -680,7 +703,7 @@ static struct ether_addr *resolve_mac_from_addr(int ai_family, const char *asc)
struct ether_addr *resolve_mac(const char *asc)
{
struct ether_addr *mac_result = NULL;
- static const int ai_families[] = {AF_INET};
+ static const int ai_families[] = {AF_INET, AF_INET6};
size_t i;
mac_result = ether_aton(asc);
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver
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
1 sibling, 0 replies; 14+ messages in thread
From: Marek Lindner @ 2013-09-24 12:15 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
On Sunday 22 September 2013 16:43:03 Sven Eckelmann wrote:
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> functions.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
Applied in revision c760fb3.
Thanks,
Marek
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver
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
1 sibling, 1 reply; 14+ messages in thread
From: Antonio Quartulli @ 2013-09-24 15:20 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking; +Cc: Sven Eckelmann
[-- Attachment #1: Type: text/plain, Size: 287 bytes --]
On Sun, Sep 22, 2013 at 04:43:03PM +0200, Sven Eckelmann wrote:
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Patch has been applied, but...
I have the feeling somebody forgot to add some documentation: text in usage(),
README, man? :)
Cheers,
--
Antonio Quartulli
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCH 4/4] batctl: Add support for IPv6 to address resolver
2013-09-24 15:20 ` Antonio Quartulli
@ 2013-09-24 18:28 ` Sven Eckelmann
0 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2013-09-24 18:28 UTC (permalink / raw)
To: Antonio Quartulli
Cc: The list for a Better Approach To Mobile Ad-hoc Networking
[-- Attachment #1: Type: text/plain, Size: 430 bytes --]
On Tuesday 24 September 2013 17:20:24 Antonio Quartulli wrote:
> On Sun, Sep 22, 2013 at 04:43:03PM +0200, Sven Eckelmann wrote:
> > Signed-off-by: Sven Eckelmann <sven@narfation.org>
>
> Patch has been applied, but...
> I have the feeling somebody forgot to add some documentation: text in
> usage(), README, man? :)
You are completely right. But I doubt that I will have a lot of time before
the weekend.
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes
2013-09-22 14:42 [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes Sven Eckelmann
` (2 preceding siblings ...)
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-23 7:03 ` Antonio Quartulli
2013-09-23 8:18 ` Sven Eckelmann
2013-09-24 12:06 ` Marek Lindner
4 siblings, 1 reply; 14+ messages in thread
From: Antonio Quartulli @ 2013-09-23 7:03 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking; +Cc: Sven Eckelmann
[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]
On Sun, Sep 22, 2013 at 04:42:23PM +0200, Sven Eckelmann wrote:
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> bat-hosts.c | 5 +++--
> bat-hosts.h | 2 +-
> bisect_iv.c | 7 ++++---
> debug.c | 5 -----
> debug.h | 3 +++
> debugfs.c | 10 ++++------
> debugfs.h | 3 ---
> functions.c | 2 ++
> functions.h | 3 ++-
> ioctl.c | 3 +--
> list-batman.h | 3 ---
> main.c | 3 ---
> ping.c | 5 +++++
> sys.c | 1 -
> sys.h | 2 ++
> tcpdump.c | 6 +++++-
> tcpdump.h | 5 ++++-
> traceroute.c | 4 ++++
> translate.c | 1 -
> 19 files changed, 40 insertions(+), 33 deletions(-)
>
> diff --git a/bat-hosts.c b/bat-hosts.c
> index ee862da..9d36531 100644
> --- a/bat-hosts.c
> +++ b/bat-hosts.c
> @@ -21,14 +21,15 @@
>
>
>
> -#include <stdio.h>
> #include <stdint.h>
> +#include <stdio.h>
why is it important to move stdio.h below stdint.h ? Is there a particular
reason for that?
Cheers,
--
Antonio Quartulli
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes
2013-09-22 14:42 [B.A.T.M.A.N.] [PATCH 1/4] batctl: Add missing includes and remove unused includes Sven Eckelmann
` (3 preceding siblings ...)
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-24 12:06 ` Marek Lindner
4 siblings, 0 replies; 14+ messages in thread
From: Marek Lindner @ 2013-09-24 12:06 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: Sven Eckelmann
On Sunday 22 September 2013 16:42:23 Sven Eckelmann wrote:
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> bat-hosts.c | 5 +++--
> bat-hosts.h | 2 +-
> bisect_iv.c | 7 ++++---
> debug.c | 5 -----
> debug.h | 3 +++
> debugfs.c | 10 ++++------
> debugfs.h | 3 ---
> functions.c | 2 ++
> functions.h | 3 ++-
> ioctl.c | 3 +--
> list-batman.h | 3 ---
> main.c | 3 ---
> ping.c | 5 +++++
> sys.c | 1 -
> sys.h | 2 ++
> tcpdump.c | 6 +++++-
> tcpdump.h | 5 ++++-
> traceroute.c | 4 ++++
> translate.c | 1 -
> 19 files changed, 40 insertions(+), 33 deletions(-)
Applied in revision 62eaa83.
Thanks,
Marek
^ permalink raw reply [flat|nested] 14+ messages in thread