DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
ARP.cpp
Go to the documentation of this file.
1
8#include <arpa/inet.h>
9#include <rte_arp.h>
10#include <rte_ethdev.h>
11
12#include <iostream>
13#include <sstream>
14#include <iomanip>
15
16#include "dpdklibs/arp/ARP.hpp"
17
18namespace dunedaq {
19namespace dpdklibs {
20namespace arp {
21
22void
23pktgen_send_garp(struct rte_mbuf *m, uint32_t port_id, rte_be32_t ip_add_bin)
24{
25 struct rte_ether_hdr *eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
26 struct rte_arp_hdr *arp = (struct rte_arp_hdr *)&eth[1];
27
28 /* src and dest addr */
29 memset(&eth->dst_addr, 0xFF, 6);
30 // MAC addr of port
31 struct rte_ether_addr mac_addr;
32 rte_eth_macaddr_get(port_id, &mac_addr);
33 rte_ether_addr_copy(&mac_addr, &eth->src_addr);
34 // Set ETH type
35 eth->ether_type = htons(RTE_ETHER_TYPE_ARP);
36
37
38 memset(arp, 0, sizeof(struct rte_arp_hdr));
39 rte_memcpy(&arp->arp_data.arp_sha, &mac_addr, 6);
40
41 inetAddrCopy(&arp->arp_data.arp_sip, &ip_add_bin);
42
43 rte_memcpy(&arp->arp_data.arp_tha, &mac_addr, 6);
44 inetAddrCopy(&arp->arp_data.arp_tip, &ip_add_bin);
45
46 /* Fill in the rest of the ARP packet header */
47 arp->arp_hardware = htons(RTE_ARP_HRD_ETHER);
48 arp->arp_protocol = htons(RTE_ETHER_TYPE_IPV4);
49 arp->arp_hlen = 6;
50 arp->arp_plen = 4;
51 arp->arp_opcode = htons(RTE_ARP_OP_REQUEST);
52
53 m->pkt_len = 60;
54 m->data_len = 60;
55
56 struct rte_mbuf *arp_tx_mbuf[1];
57 arp_tx_mbuf[0] = m;
58
59
60 std::string srcaddr = dunedaq::dpdklibs::udp::get_ipv4_decimal_addr_str(dunedaq::dpdklibs::udp::ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(arp->arp_data.arp_sip)));
61 std::string dstaddr = dunedaq::dpdklibs::udp::get_ipv4_decimal_addr_str(dunedaq::dpdklibs::udp::ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(arp->arp_data.arp_tip)));
63 TLOG_DEBUG(10) << "GARP SRC IP: " << srcaddr;
64 TLOG_DEBUG(10) << "GARP DEST IP: " << dstaddr;
65 TLOG_DEBUG(10) << "LOCAL IP: " << localaddr;
66
67 rte_eth_tx_burst(port_id, 0, arp_tx_mbuf, 1);
68}
69
70
71inline void
72hex_digits_to_stream(std::ostringstream& ostrs, int value, char separator = ':', char fill = '0', int digits = 2) {
73 ostrs << std::setfill(fill) << std::setw(digits) << std::hex << value << std::dec << separator;
74}
75
76
77void
78pktgen_process_arp(struct rte_mbuf *m, uint32_t port_id, rte_be32_t ip_add_bin)
79{
80 struct rte_ether_hdr *eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
81 struct rte_arp_hdr *arp = (struct rte_arp_hdr *)&eth[1];
82
83 if (arp->arp_opcode == rte_cpu_to_be_16(RTE_ARP_OP_REQUEST)) {
84 arp->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REPLY);
85
86
87 /* Grab the source MAC addresses */
88 struct rte_ether_addr mac_addr;
89 rte_eth_macaddr_get(port_id, &mac_addr);
90
91 std::string srcaddr = dunedaq::dpdklibs::udp::get_ipv4_decimal_addr_str(dunedaq::dpdklibs::udp::ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(arp->arp_data.arp_sip)));
92 std::string dstaddr = dunedaq::dpdklibs::udp::get_ipv4_decimal_addr_str(dunedaq::dpdklibs::udp::ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(arp->arp_data.arp_tip)));
94
95 TLOG_DEBUG(10) << "ARP SRC IP: " << srcaddr;
96 TLOG_DEBUG(10) << "ARP DEST IP: " << dstaddr;
97 TLOG_DEBUG(10) << "ARP LOCAL IP: " << localaddr;
98
99 // Bail out if not our ipaddress
100 if ( arp->arp_data.arp_tip != ip_add_bin) return;
101
102 TLOG_DEBUG(10) << "ARP Received " << dstaddr << " I'm the target " << localaddr;
103
104 /* Swap the two MAC addresses */
105 ethAddrSwap(&arp->arp_data.arp_sha, &arp->arp_data.arp_tha);
106
107 /* Swap the two IP addresses */
108 inetAddrSwap(&arp->arp_data.arp_tip, &arp->arp_data.arp_sip);
109
110 /* Set the packet to ARP reply */
111 arp->arp_opcode = htons(RTE_ARP_OP_REPLY);
112
113 /* Swap the MAC addresses */
114 ethAddrSwap(&eth->dst_addr, &eth->src_addr);
115
116 /* Copy in the MAC address for the reply. */
117 rte_memcpy(&arp->arp_data.arp_sha, &mac_addr, 6);
118 rte_memcpy(&eth->src_addr, &mac_addr, 6);
119
120 struct rte_mbuf *arp_tx_mbuf[1];
121 arp_tx_mbuf[0] = m;
122
123 rte_eth_tx_burst(port_id, 0, arp_tx_mbuf, 1);
124 TLOG_DEBUG(10) << "Sending ARP reply";
125
126 /* No need to free mbuf as it was reused */
127 return;
128 }
129}
130
131} // namespace arp
132} // namespace dpdklibs
133} // namespace dunedaq
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
void inetAddrCopy(void *t, void *f)
Definition ARP.hpp:68
void ethAddrSwap(void *t, void *f)
Definition ARP.hpp:47
void pktgen_send_garp(struct rte_mbuf *m, uint32_t port_id, rte_be32_t binary_ip_address)
Definition ARP.cpp:23
void hex_digits_to_stream(std::ostringstream &ostrs, int value, char separator=':', char fill='0', int digits=2)
Definition ARP.cpp:72
void pktgen_process_arp(struct rte_mbuf *m, uint32_t pid, rte_be32_t binary_ip_address)
Definition ARP.cpp:78
void inetAddrSwap(void *t, void *f)
Definition ARP.hpp:57
std::string get_ipv4_decimal_addr_str(struct ipaddr ipv4_address)
Definition Utils.cpp:56
struct ipaddr ip_address_binary_to_dotdecimal(rte_le32_t binary_ipv4_address)
Definition Utils.cpp:48
The DUNE-DAQ namespace.
Definition DataStore.hpp:57