From patchwork Wed Oct 24 18:35:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Haws X-Patchwork-Id: 17551 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from open-mesh.org (localhost [IPv6:::1]) by open-mesh.org (Postfix) with ESMTP id AAF6983020; Wed, 24 Oct 2018 20:35:25 +0200 (CEST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=129.123.197.110; helo=sea.usurf.usu.edu; envelope-from=jhaws@sdl.usu.edu; receiver= Received: from sea.usurf.usu.edu (sea.usurf.usu.edu [129.123.197.110]) by open-mesh.org (Postfix) with ESMTP id BE16980478 for ; Wed, 24 Oct 2018 20:35:20 +0200 (CEST) Received: from sea.usurf.usu.edu (localhost.localdomain [127.0.0.1]) by localhost (Email Security Appliance) with SMTP id AB450AF594_BD0BB67B; Wed, 24 Oct 2018 18:35:19 +0000 (GMT) Received: from morpheus.usurf.usu.edu (morpheus.usurf.usu.edu [172.31.35.107]) by sea.usurf.usu.edu (Sophos Email Appliance) with ESMTP id 63D4D15E79B_BD0BB67F; Wed, 24 Oct 2018 18:35:19 +0000 (GMT) Received: from morpheus.usurf.usu.edu (172.31.35.107) by morpheus.usurf.usu.edu (172.31.35.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1531.3; Wed, 24 Oct 2018 12:35:17 -0600 Received: from C01547.usurf.usu.edu (172.31.12.48) by morpheus.usurf.usu.edu (172.31.35.107) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Wed, 24 Oct 2018 12:35:17 -0600 From: Jonathan Haws To: , Date: Wed, 24 Oct 2018 12:35:11 -0600 Message-ID: <20181024183511.19902-1-jhaws@sdl.usu.edu> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 X-SASI-RCODE: 200 Subject: [B.A.T.M.A.N.] [PATCH alfred] Request MAC resolution for IPv4 address not in ARP cache X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking Cc: Jonathan Haws Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" When using IPv4, if the remote server is not yet in the ARP cache, the MAC resolution will fail and data appear to not be shared via alfred. Add a routine (modified from batctl sources) to request MAC resolution by simply sending a datagram to the discard port (UDP/9). This adds the remote MAC to the ARP cache, resulting in successful MAC resolution. Signed-off-by: Jonathan Haws --- alfred.h | 1 + util.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/alfred.h b/alfred.h index eecfdfd..5771483 100644 --- a/alfred.h +++ b/alfred.h @@ -213,3 +213,4 @@ uint16_t get_random_id(void); bool is_valid_ether_addr(uint8_t *addr); int ipv4_arp_request(struct interface *interface, const alfred_addr *addr, struct ether_addr *mac); +void ipv4_request_mac_resolve(const alfred_addr *addr); diff --git a/util.c b/util.c index dd3f00f..a6a98b9 100644 --- a/util.c +++ b/util.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "alfred.h" int time_diff(struct timespec *tv1, struct timespec *tv2, @@ -85,6 +86,7 @@ int ipv4_arp_request(struct interface *interface, const alfred_addr *addr, { struct arpreq arpreq; struct sockaddr_in *sin; + int retries = 1; memset(&arpreq, 0, sizeof(arpreq)); memset(mac, 0, ETH_ALEN); @@ -99,6 +101,14 @@ int ipv4_arp_request(struct interface *interface, const alfred_addr *addr, if (ioctl(interface->netsock, SIOCGARP, &arpreq) < 0) return -1; + while (retries-- && !(arpreq.arp_flags & ATF_COM)) { + ipv4_request_mac_resolve(addr); + usleep(200000); + + if (ioctl(interface->netsock, SIOCGARP, &arpreq) < 0) + return -1; + } + if (arpreq.arp_flags & ATF_COM) { memcpy(mac, arpreq.arp_ha.sa_data, sizeof(*mac)); } else { @@ -108,3 +118,26 @@ int ipv4_arp_request(struct interface *interface, const alfred_addr *addr, return 0; } + +void ipv4_request_mac_resolve(const alfred_addr *addr) +{ + const struct sockaddr *sockaddr; + struct sockaddr_in inet4; + size_t sockaddr_len; + int sock; + char t = 0; + + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) + return; + + memset(&inet4, 0, sizeof(inet4)); + inet4.sin_family = AF_INET; + inet4.sin_port = htons(9); + inet4.sin_addr.s_addr = addr->ipv4.s_addr; + sockaddr = (const struct sockaddr *)&inet4; + sockaddr_len = sizeof(inet4); + + sendto(sock, &t, sizeof(t), 0, sockaddr, sockaddr_len); + close(sock); +}