Repository : ssh://git@open-mesh.org/batctl
On branch : master
>---------------------------------------------------------------
commit c8e4fd483118cda7c9e8575a5f2b12fd55b1f636
Author: Sven Eckelmann <sven(a)narfation.org>
Date: Tue Oct 16 22:54:36 2012 +0200
batctl: Add tool to translate mac/IPv4/bat_host to originator address
Users may want to get the originator which is responsible for a specific mac
address. These addresses can be specified using IPv4 address, ethernet address
or bat-host name.
For example, the output can be used to get the TQ value from the originator
table when only the client address is known and not the gateway address.
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
>---------------------------------------------------------------
c8e4fd483118cda7c9e8575a5f2b12fd55b1f636
Makefile | 2 +-
README | 18 ++++++++++++
main.c | 6 ++++
man/batctl.8 | 5 ++++
translate.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
ping.h => translate.h | 2 +-
6 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 4379837..699a3ea 100755
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ export CONFIG_BATCTL_BISECT=n
# batctl build
BINARY_NAME = batctl
-OBJ = main.o bat-hosts.o functions.o sys.o debug.o ping.o traceroute.o tcpdump.o hash.o vis.o debugfs.o ioctl.o list-batman.o
+OBJ = main.o bat-hosts.o functions.o sys.o debug.o ping.o traceroute.o tcpdump.o hash.o vis.o debugfs.o ioctl.o list-batman.o translate.o
OBJ_BISECT = bisect_iv.o
MANPAGE = man/batctl.8
diff --git a/README b/README
index b9c6b23..efdd3cb 100644
--- a/README
+++ b/README
@@ -75,6 +75,24 @@ $ batctl statistics
dat_reply_tx: 1
dat_reply_rx: 0
+batctl translate
+================
+
+Translates a destination (hostname, IPv4, MAC, bat_host-name) to the originator
+mac address responsible for it.
+
+Usage: batctl translate mac|bat-host|host-name|IPv4-address
+
+Example:
+
+$ batctl translate www.google.de
+02:ca:fe:af:fe:01
+$ batctl translate 02:ca:fe:af:fe:01
+02:ca:fe:af:fe:01
+$ batctl translate 192.168.1.2
+02:ca:fe:af:fe:05
+$ batctl translate fe:fe:00:00:09:01
+02:ca:fe:af:fe:05
batctl ping
============
diff --git a/main.c b/main.c
index d37a46c..e239b2a 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,7 @@
#include "debug.h"
#include "debugfs.h"
#include "ping.h"
+#include "translate.h"
#include "traceroute.h"
#include "tcpdump.h"
#include "bisect_iv.h"
@@ -87,6 +88,7 @@ void print_usage(void)
printf(" \tping|p <destination> \tping another batman adv host via layer 2\n");
printf(" \ttraceroute|tr <destination> \ttraceroute another batman adv host via layer 2\n");
printf(" \ttcpdump|td <interface> \ttcpdump layer 2 traffic on the given interface\n");
+ printf(" \ttranslate|t <destination> \ttranslate a destination to the originator responsible for it\n");
#ifdef BATCTL_BISECT
printf(" \tbisect_iv <file1> .. <fileN>\tanalyze given batman iv log files for routing stability\n");
#endif
@@ -203,6 +205,10 @@ int main(int argc, char **argv)
ret = ioctl_statistics_get(mesh_iface);
+ } else if ((strcmp(argv[1], "translate") == 0) || (strcmp(argv[1], "t") == 0)) {
+
+ ret = translate(mesh_iface, argc - 1, argv + 1);
+
#ifdef BATCTL_BISECT
} else if ((strcmp(argv[1], "bisect_iv") == 0)) {
diff --git a/man/batctl.8 b/man/batctl.8
index feb1a17..3c8edce 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -200,6 +200,11 @@ List of debug tables:
.RE
.RE
.br
+.IP "\fBtranslate\fP|\fBt\fP \fBMAC_address\fP|\fBbat\-host_name\fP|\fBhost_name\fP|\fBIPv4_address\fP"
+
+Translates a destination (hostname, IPv4, MAC, bat_host-name) to the originator
+mac address responsible for it.
+.br
.IP "\fBstatistics\fP|\fBs\fP"
Retrieve traffic counters from batman-adv kernel module. The output may vary depending on which features have been compiled
into the kernel module.
diff --git a/translate.c b/translate.c
new file mode 100644
index 0000000..2d6ede9
--- /dev/null
+++ b/translate.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
+ *
+ * Andreas Langer <an.langer(a)gmx.de>, Marek Lindner <lindner_marek(a)yahoo.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "main.h"
+#include "translate.h"
+#include "functions.h"
+#include "bat-hosts.h"
+
+
+static void translate_usage(void)
+{
+ printf("Usage: batctl [options] translate mac|bat-host|host_name|IPv4_address\n");
+}
+
+int translate(char *mesh_iface, int argc, char **argv)
+{
+ struct ether_addr *dst_mac = NULL;
+ struct bat_host *bat_host;
+ int ret = EXIT_FAILURE;
+ char *dst_string, *mac_string;
+
+ if (argc <= 1) {
+ fprintf(stderr, "Error - destination not specified\n");
+ translate_usage();
+ return EXIT_FAILURE;
+ }
+
+ dst_string = argv[1];
+ bat_hosts_init(0);
+ bat_host = bat_hosts_find_by_name(dst_string);
+
+ if (bat_host)
+ dst_mac = &bat_host->mac_addr;
+
+ if (!dst_mac) {
+ dst_mac = resolve_mac(dst_string);
+
+ if (!dst_mac) {
+ fprintf(stderr, "Error - mac address of the ping destination could not be resolved and is not a bat-host name: %s\n", dst_string);
+ goto out;
+ }
+ }
+
+ dst_mac = translate_mac(mesh_iface, dst_mac);
+ if (dst_mac) {
+ mac_string = ether_ntoa_long(dst_mac);
+ printf("%s\n", mac_string);
+ ret = EXIT_SUCCESS;
+ } else {
+ ret = EXIT_NOSUCCESS;
+ }
+
+out:
+ bat_hosts_free();
+ return ret;
+}
diff --git a/ping.h b/translate.h
similarity index 93%
copy from ping.h
copy to translate.h
index e3f47fc..eb0ef65 100644
--- a/ping.h
+++ b/translate.h
@@ -21,4 +21,4 @@
-int ping(char *mesh_iface, int argc, char **argv);
+int translate(char *mesh_iface, int argc, char **argv);
Repository : ssh://git@open-mesh.org/batman-adv
On branch : next
>---------------------------------------------------------------
commit 2cebface808ba2df76e38a813b3d3f3e97497aff
Author: Linus Lüssing <linus.luessing(a)web.de>
Date: Wed Oct 17 14:53:04 2012 +0200
batman-adv: Fix broadcast packet CRC calculation
So far the crc16 checksum for a batman-adv broadcast data packet, received
on a batman-adv hard interface, was calculated over zero bytes of its
content leading to many incoming broadcast data packets wrongly being
dropped (60-80% packet loss).
This patch fixes this issue by calculating the crc16 over the actual,
complete broadcast payload.
The issue is a regression introduced by
("batman-adv: add broadcast duplicate check").
Signed-off-by: Linus Lüssing <linus.luessing(a)web.de>
Acked-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
>---------------------------------------------------------------
2cebface808ba2df76e38a813b3d3f3e97497aff
bridge_loop_avoidance.c | 8 ++++----
routing.c | 8 +++++++-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 0a9084a..eebab20 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -1210,8 +1210,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
/**
* batadv_bla_check_bcast_duplist
* @bat_priv: the bat priv with all the soft interface information
- * @bcast_packet: originator mac address
- * @hdr_size: maximum length of the frame
+ * @bcast_packet: encapsulated broadcast frame plus batman header
+ * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
*
* check if it is on our broadcast list. Another gateway might
* have sent the same packet because it is connected to the same backbone,
@@ -1224,14 +1224,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
*/
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
struct batadv_bcast_packet *bcast_packet,
- int hdr_size)
+ int bcast_packet_len)
{
int i, length, curr;
uint8_t *content;
uint16_t crc;
struct batadv_bcast_duplist_entry *entry;
- length = hdr_size - sizeof(*bcast_packet);
+ length = bcast_packet_len - sizeof(*bcast_packet);
content = (uint8_t *)bcast_packet;
content += sizeof(*bcast_packet);
diff --git a/routing.c b/routing.c
index 939fc01..376b4cc 100644
--- a/routing.c
+++ b/routing.c
@@ -1124,8 +1124,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
spin_unlock_bh(&orig_node->bcast_seqno_lock);
+ /* keep skb linear for crc calculation */
+ if (skb_linearize(skb) < 0)
+ goto out;
+
+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
+
/* check whether this has been sent by another originator before */
- if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
+ if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
goto out;
/* rebroadcast packet */
Repository : ssh://git@open-mesh.org/batctl
On branch : master
>---------------------------------------------------------------
commit cb75e019e74fc11f9547dadd51abbf3c9df2c5e7
Author: Sven Eckelmann <sven(a)narfation.org>
Date: Sun Oct 14 22:20:53 2012 +0200
batctl: Allow to use IPv4 addresses for ping/traceroute
IPv4 addresses and hostnames are easier to remember than many MAC addresses.
batctl can automatically resolve the MAC address of the target device when the
IP is configured on top of the batman-adv device and the source and destination
batman-adv interface are in the same IPv4 subnet.
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
>---------------------------------------------------------------
cb75e019e74fc11f9547dadd51abbf3c9df2c5e7
README | 4 +-
functions.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
functions.h | 1 +
man/batctl.8 | 18 ++++---
ping.c | 6 +--
traceroute.c | 6 +--
6 files changed, 170 insertions(+), 14 deletions(-)
diff --git a/README b/README
index ad4fc44..b9c6b23 100644
--- a/README
+++ b/README
@@ -81,7 +81,7 @@ batctl ping
Sends a Layer 2 batman-adv ping to check round trip time and connectivity
-Usage: batctl ping [parameters] mac|bat-host
+Usage: batctl ping [parameters] mac|bat-host|host-name|IPv4-address
parameters:
-c ping packet count
-h print this help
@@ -107,7 +107,7 @@ batctl traceroute
Traceroute sends 3 packets to each hop, awaits the answers and prints out the
response times.
-Usage: batctl traceroute [parameters] mac|bat-host
+Usage: batctl traceroute [parameters] mac|bat-host|host-name|IPv4-address
Example:
diff --git a/functions.c b/functions.c
index 7875716..a500444 100644
--- a/functions.c
+++ b/functions.c
@@ -22,6 +22,9 @@
#define _GNU_SOURCE
#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -402,3 +405,149 @@ out:
free(line);
return mac_result;
}
+
+static uint32_t resolve_ipv4(const char *asc)
+{
+ 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;
+ ret = getaddrinfo(asc, NULL, &hints, &res);
+ if (ret)
+ return 0;
+
+ if (res) {
+ inet4 = (struct sockaddr_in *)res->ai_addr;
+ addr = inet4->sin_addr.s_addr;
+ }
+
+ freeaddrinfo(res);
+ return addr;
+}
+
+static void request_arp(uint32_t ipv4_addr)
+{
+ struct sockaddr_in inet4;
+ int sock;
+ char t = 0;
+
+ memset(&inet4, 0, sizeof(inet4));
+ sock = socket(AF_INET, 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));
+ close(sock);
+}
+
+static struct ether_addr *resolve_mac_from_arp(uint32_t ipv4_addr)
+{
+ struct ether_addr mac_empty;
+ struct ether_addr *mac_result = NULL, *mac_tmp;
+ 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;
+
+ 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;
+ break;
+ }
+ }
+
+ free(line);
+ fclose(f);
+ return mac_result;
+}
+
+static struct ether_addr *resolve_mac_from_ipv4(const char *asc)
+{
+ uint32_t ipv4_addr;
+ int retries = 5;
+ struct ether_addr *mac_result = NULL;
+
+ ipv4_addr = resolve_ipv4(asc);
+ if (!ipv4_addr)
+ return NULL;
+
+ while (retries-- && !mac_result) {
+ mac_result = resolve_mac_from_arp(ipv4_addr);
+ if (!mac_result) {
+ request_arp(ipv4_addr);
+ usleep(200000);
+ }
+ }
+
+ return mac_result;
+}
+
+struct ether_addr *resolve_mac(const char *asc)
+{
+ struct ether_addr *mac_result = NULL;
+
+ mac_result = ether_aton(asc);
+ if (mac_result)
+ goto out;
+
+ mac_result = resolve_mac_from_ipv4(asc);
+
+out:
+ return mac_result;
+}
diff --git a/functions.h b/functions.h
index a59bb24..0ec1d1a 100644
--- a/functions.h
+++ b/functions.h
@@ -38,6 +38,7 @@ int read_file(char *dir, char *path, int read_opt,
float orig_timeout, float watch_interval);
int write_file(char *dir, char *fname, char *arg1, char *arg2);
struct ether_addr *translate_mac(char *mesh_iface, struct ether_addr *mac);
+struct ether_addr *resolve_mac(const char *asc);
extern char *line_ptr;
diff --git a/man/batctl.8 b/man/batctl.8
index 369be20..804682e 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -212,19 +212,25 @@ tt - translation table counters
All counters without a prefix concern payload (pure user data) traffic.
.RE
.br
-.IP "\fBping\fP|\fBp\fP [\fB\-c count\fP][\fB\-i interval\fP][\fB\-t time\fP][\fB\-R\fP][\fB\-T\fP] \fBMAC_address\fP|\fBbat\-host_name\fP"
+.IP "\fBping\fP|\fBp\fP [\fB\-c count\fP][\fB\-i interval\fP][\fB\-t time\fP][\fB\-R\fP][\fB\-T\fP] \fBMAC_address\fP|\fBbat\-host_name\fP|\fBhost_name\fP|\fBIPv4_address\fP"
Layer 2 ping of a MAC address or bat\-host name. batctl will try to find the bat\-host name if the given parameter was
-not a MAC address. The "\-c" option tells batctl how man pings should be sent before the program exits. Without the "\-c"
+not a MAC address. It can also try to guess the MAC address using an IPv4 address or a hostname when
+the IPv4 address was configured on top of the batman-adv interface of the destination device and both source and
+destination devices are in the same IPv4 subnet.
+The "\-c" option tells batctl how man pings should be sent before the program exits. Without the "\-c"
option batctl will continue pinging without end. Use CTRL + C to stop it. With "\-i" and "\-t" you can set the default
interval between pings and the timeout time for replies, both in seconds. When run with "\-R", the route taken by the ping
messages will be recorded. With "\-T" you can disable the automatic translation of a client MAC address to the originator
address which is responsible for this client.
.br
-.IP "\fBtraceroute\fP|\fBtr\fP [\fB\-n\fP][\fB\-T\fP] \fBMAC_address\fP|\fBbat\-host_name\fP"
+.IP "\fBtraceroute\fP|\fBtr\fP [\fB\-n\fP][\fB\-T\fP] \fBMAC_address\fP|\fBbat\-host_name\fP|\fBhost_name\fP|\fBIPv4_address\fP"
Layer 2 traceroute to a MAC address or bat\-host name. batctl will try to find the bat\-host name if the given parameter
-was not a MAC address. batctl will send 3 packets to each host and display the response time. If "\-n" is given batctl will
-not replace the MAC addresses with bat\-host names in the output. With "\-T" you can disable the automatic translation of a
-client MAC address to the originator address which is responsible for this client.
+was not a MAC address. It can also try to guess the MAC address using an IPv4 address or a hostname when
+the IPv4 address was configured on top of the batman-adv interface of the destination device and both source and
+destination devices are in the same IPv4 subnet.
+batctl will send 3 packets to each host and display the response time. If "\-n" is given batctl will
+not replace the MAC addresses with bat\-host names in the output. With "\-T" you can disable the automatic translation
+of a client MAC address to the originator address which is responsible for this client.
.br
.IP "\fBtcpdump\fP|\fBtd\fP [\fB\-c\fP][\fB\-n\fP][\fB\-p filter\fP][\fB\-x filter\fP] \fBinterface ...\fP"
batctl will display all packets that are seen on the given interface(s). A variety of options to filter the output
diff --git a/ping.c b/ping.c
index 02132f4..51d18e8 100644
--- a/ping.c
+++ b/ping.c
@@ -44,7 +44,7 @@ char is_aborted = 0;
void ping_usage(void)
{
- printf("Usage: batctl [options] ping [parameters] mac|bat-host \n");
+ printf("Usage: batctl [options] ping [parameters] mac|bat-host|host_name|IPv4_address \n");
printf("parameters:\n");
printf(" \t -c ping packet count \n");
printf(" \t -h print this help\n");
@@ -137,10 +137,10 @@ int ping(char *mesh_iface, int argc, char **argv)
dst_mac = &bat_host->mac_addr;
if (!dst_mac) {
- dst_mac = ether_aton(dst_string);
+ dst_mac = resolve_mac(dst_string);
if (!dst_mac) {
- printf("Error - the ping destination is not a mac address or bat-host name: %s\n", dst_string);
+ printf("Error - mac address of the ping destination could not be resolved and is not a bat-host name: %s\n", dst_string);
goto out;
}
}
diff --git a/traceroute.c b/traceroute.c
index 4e42419..ac2f1fa 100644
--- a/traceroute.c
+++ b/traceroute.c
@@ -43,7 +43,7 @@
void traceroute_usage(void)
{
- printf("Usage: batctl [options] traceroute [parameters] mac|bat-host \n");
+ printf("Usage: batctl [options] traceroute [parameters] mac|bat-host|host_name|IPv4_address \n");
printf("parameters:\n");
printf(" \t -h print this help\n");
printf(" \t -n don't convert addresses to bat-host names\n");
@@ -99,10 +99,10 @@ int traceroute(char *mesh_iface, int argc, char **argv)
dst_mac = &bat_host->mac_addr;
if (!dst_mac) {
- dst_mac = ether_aton(dst_string);
+ dst_mac = resolve_mac(dst_string);
if (!dst_mac) {
- printf("Error - the traceroute destination is not a mac address or bat-host name: %s\n", dst_string);
+ printf("Error - mac address of the ping destination could not be resolved and is not a bat-host name: %s\n", dst_string);
goto out;
}
}