25#ifndef JOIN_FABRIC_ARP_HPP
26#define JOIN_FABRIC_ARP_HPP
35#include <unordered_map>
39#include <linux/filter.h>
40#include <net/if_arp.h>
100 template <
typename Rep,
typename Period>
103 if (ip.
family () != AF_INET)
126 return get (ip, std::chrono::seconds (5));
136 template <
typename Rep,
typename Period>
138 std::chrono::duration<Rep, Period> timeout)
140 return Arp (interface).get (ip, timeout);
151 return get (interface, ip, std::chrono::seconds (5));
160 template <
typename Rep,
typename Period>
163 if (ip.
family () != AF_INET)
175 struct sock_filter code[] = {
176 {0x28, 0, 0, 0x0000000c}, {0x15, 0, 3, 0x00000806}, {0x28, 0, 0, 0x00000014},
177 {0x15, 0, 1, 0x00000002}, {0x6, 0, 0, 0x00040000}, {0x6, 0, 0, 0x00000000},
180 struct sock_fprog bpf;
185 ::setsockopt (
handle (), SOL_SOCKET, SO_ATTACH_FILTER, &bpf,
sizeof (bpf));
192 ::memcpy (out.eth.h_source, srcMac.
addr (), ETH_ALEN);
193 out.eth.h_proto = ::htons (ETH_P_ARP);
195 out.arp.ar_hrd = ::htons (ARPHRD_ETHER);
196 out.arp.ar_pro = ::htons (ETH_P_IP);
197 out.arp.ar_hln = ETH_ALEN;
199 out.arp.ar_op = ::htons (ARPOP_REQUEST);
200 ::memcpy (out.arp.ar_sha, srcMac.
addr (), ETH_ALEN);
201 ::memcpy (&out.arp.ar_sip, srcIp.
addr (), sizeof (uint32_t));
203 ::memcpy (&out.arp.ar_tip, ip.
addr (), sizeof (uint32_t));
207 if (
write (
reinterpret_cast<const char*
> (&out),
sizeof (Packet)) == -1)
214 MacAddress mac = waitResponse (lock, out.arp.ar_tip, timeout);
228 return request (ip, std::chrono::seconds (5));
238 template <
typename Rep,
typename Period>
240 std::chrono::duration<Rep, Period> timeout)
242 return Arp (interface).request (ip, timeout);
253 return request (interface, ip, std::chrono::seconds (5));
307 struct __attribute__ ((packed)) ArpPacket
314 uint8_t ar_sha[ETH_ALEN];
316 uint8_t ar_tha[ETH_ALEN];
323 struct __attribute__ ((packed)) Packet
336 template <
typename Rep,
typename Period>
337 MacAddress waitResponse (ScopedLock<Mutex>& lock, uint32_t tip, std::chrono::duration<Rep, Period> timeout)
339 auto inserted = _pending.emplace (tip, std::make_unique<PendingRequest> ());
340 if (!inserted.second)
348 if (!inserted.first->second->cond.timedWait (lock, timeout))
350 _pending.erase (inserted.first);
351 lastError = std::make_error_code (std::errc::no_such_device_or_address);
355 MacAddress mac = inserted.first->second->mac;
356 _pending.erase (inserted.first);
365 void onReceive (
int fd)
noexcept override;
368 static constexpr size_t _bufferSize = 4096;
373 struct PendingRequest
380 std::unordered_map<uint32_t, std::unique_ptr<PendingRequest>> _pending;
386 const std::string _interface;
389 NeighborManager* _neighbors =
nullptr;
392 Reactor*
const _reactor =
nullptr;
ARP protocol class.
Definition arp.hpp:49
~Arp()=default
destroy the Arp instance.
static MacAddress request(const std::string &interface, const IpAddress &ip)
get the MAC address for the given IP address using ARP request.
Definition arp.hpp:251
int add(const MacAddress &mac, const IpAddress &ip)
add entry the MAC address of the given IP address to ARP cache.
Definition arp.cpp:56
MacAddress request(const IpAddress &ip, std::chrono::duration< Rep, Period > timeout)
get the MAC address for the given IP address using ARP request.
Definition arp.hpp:161
Arp(const Arp &other)=delete
create instance by copy.
static MacAddress request(const std::string &interface, const IpAddress &ip, std::chrono::duration< Rep, Period > timeout)
get the MAC address for the given IP address using ARP request.
Definition arp.hpp:239
static MacAddress get(const std::string &interface, const IpAddress &ip)
discover the MAC address for the given internet layer address.
Definition arp.hpp:149
static MacAddress get(const std::string &interface, const IpAddress &ip, std::chrono::duration< Rep, Period > timeout)
discover the MAC address for the given internet layer address.
Definition arp.hpp:137
Arp()=delete
create the Arp instance.
MacAddress get(const IpAddress &ip, std::chrono::duration< Rep, Period > timeout)
get the MAC address for the given IP address using netlink neighbor cache or ARP request.
Definition arp.hpp:101
int remove(const IpAddress &ip)
remove the MAC address of the given IP address from ARP cache.
Definition arp.cpp:87
MacAddress cache(const IpAddress &ip)
get the MAC address for the given IP address using ARP cache.
Definition arp.cpp:118
Arp & operator=(const Arp &other)=delete
assign instance by copy.
MacAddress request(const IpAddress &ip)
get the MAC address for the given IP address using ARP request.
Definition arp.hpp:226
MacAddress get(const IpAddress &ip)
get the MAC address for the given IP address using ARP cache or ARP request.
Definition arp.hpp:124
Arp(Arp &&other)=delete
create instance by move.
basic socket class.
Definition socket.hpp:60
virtual int setOption(Option option, int value) noexcept
set the given option to the given value.
Definition socket.hpp:407
virtual void close() noexcept
close the socket.
Definition socket.hpp:223
virtual int bind(const Endpoint &endpoint) noexcept
assigns the specified endpoint to the socket.
Definition socket.hpp:238
@ Broadcast
Definition socket.hpp:89
int handle() const noexcept
get socket native handle.
Definition socket.hpp:534
virtual int write(const char *data, unsigned long maxSize) noexcept
write data.
Definition socket.hpp:352
friend class Reactor
friendship with reactor.
Definition reactor.hpp:113
IPv6, IPv4 address class.
Definition ipaddress.hpp:51
int family() const
get address family.
Definition ipaddress.cpp:1250
static IpAddress ipv4Address(const std::string &interface)
get the specified interface IPv4 address.
Definition ipaddress.cpp:1526
const void * addr() const
get the internal address structure.
Definition ipaddress.cpp:1259
MAC address class.
Definition macaddress.hpp:46
static const MacAddress broadcast
broadcast MAC address.
Definition macaddress.hpp:309
bool isWildcard() const
check if MAC address is a wildcard address.
Definition macaddress.cpp:182
static const MacAddress wildcard
wildcard MAC address.
Definition macaddress.hpp:306
static MacAddress address(const std::string &interface)
get the specified interface MAC address.
Definition macaddress.cpp:355
const uint8_t * addr() const
get the internal MAC address array address.
Definition macaddress.cpp:164
ARP / NDP neighbor manager class.
Definition neighbormanager.hpp:138
int delHandler(int fd, bool sync=true) noexcept
delete handler from reactor.
Definition reactor.cpp:150
int addHandler(int fd, EventHandler *handler, bool sync=true) noexcept
add handler to reactor.
Definition reactor.cpp:94
class owning a mutex for the duration of a scoped block.
Definition mutex.hpp:246
Definition acceptor.hpp:32
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:150