DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
PacketCtor.cpp
Go to the documentation of this file.
1#include <rte_ethdev.h>
2
6
8
9#define IPV4_VERSION 4
10
11//DEFAULT_TTL = 8 -> TTL on wireshark 5
12//DEFAULT_TTL = 5 -> TTL on wireshark 2
13//DEFAULT_TTL = 4 -> TTL on wireshark 1
14
15namespace dunedaq {
16namespace dpdklibs {
17namespace udp {
18
19enum {
22 DEFAULT_TTL = 8
23};
25static int8_t get_xdigit(char ch)
26{
27 if (ch >= '0' && ch <= '9')
28 return ch - '0';
29 if (ch >= 'a' && ch <= 'f')
30 return ch - 'a' + 10;
31 if (ch >= 'A' && ch <= 'F')
32 return ch - 'A' + 10;
33 return -1;
34}
35
36
37bool get_ether_addr6(const char *s0, struct rte_ether_addr *ea)
38{
39 const char *s = s0;
40 int i;
41
42 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
43 int8_t x;
44
45 x = get_xdigit(*s++);
46 if (x < 0)
47 return false;
48
49 ea->addr_bytes[i] = x << 4;
50 x = get_xdigit(*s++);
51 if (x < 0)
52 return false;
53 ea->addr_bytes[i] |= x;
54
55 if (i < RTE_ETHER_ADDR_LEN - 1 &&
56 *s++ != ':')
57 return false;
58 }
59
60 /* return true if at end of string */
61 return *s == '\0';
62}
63
64
65rte_le16_t
66packet_fill(struct ipv4_udp_packet_hdr * packet_hdr)
67{
68 //rte_le16_t total_length = 64;
69 //char message[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
70
71
72 rte_le16_t total_length = 2000;
73 char message[] = "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE";
74
75
76
77 char * payload = (char *)(packet_hdr + 1);
78 memcpy(payload, message, total_length);
79 return total_length;
80}
81
82
83/**************************************************************************/
94void
95pktgen_udp_hdr_ctor(struct ipv4_udp_packet_hdr * packet_hdr, rte_le16_t packet_len, int sport, int dport)
96{
97 packet_hdr->udp_hdr.dgram_len = rte_cpu_to_be_16(packet_len);
98
99 packet_hdr->udp_hdr.src_port = rte_cpu_to_be_16(sport);
100 packet_hdr->udp_hdr.dst_port = rte_cpu_to_be_16(dport);
101
102 packet_hdr->udp_hdr.dgram_cksum = 0; // checksum must be set to 0 in the L4 header by the caller.
103 //TODO I think that the payload must be already there and continuous in memory..
104 return ;
105}
106
107/**************************************************************************/
118void
119pktgen_ipv4_ctor(struct ipv4_udp_packet_hdr * packet_hdr, rte_le16_t packet_len, const std::string& src_ip_addr, const std::string& dst_ip_addr)
120{
121 /* IPv4 Header constructor */
122
123 /* Zero out the header space */
124 memset((char *) &packet_hdr->ipv4_hdr, 0, sizeof(struct rte_ipv4_hdr));
125
126 IpAddr src(src_ip_addr);
127 IpAddr dst(dst_ip_addr);
128
129 struct ipaddr src_reversed_order;
130 src_reversed_order.addr_bytes[3] = src.addr_bytes[0];
131 src_reversed_order.addr_bytes[2] = src.addr_bytes[1];
132 src_reversed_order.addr_bytes[1] = src.addr_bytes[2];
133 src_reversed_order.addr_bytes[0] = src.addr_bytes[3];
134
135 struct ipaddr dst_reversed_order;
136 dst_reversed_order.addr_bytes[3] = dst.addr_bytes[0];
137 dst_reversed_order.addr_bytes[2] = dst.addr_bytes[1];
138 dst_reversed_order.addr_bytes[1] = dst.addr_bytes[2];
139 dst_reversed_order.addr_bytes[0] = dst.addr_bytes[3];
140
141 rte_le32_t src_addr_ser = *((rte_le32_t *) &src_reversed_order);
142 rte_le32_t dst_addr_ser = *((rte_le32_t *) &dst_reversed_order);
143
144 packet_hdr->ipv4_hdr.src_addr = rte_cpu_to_be_32(src_addr_ser);
145 packet_hdr->ipv4_hdr.dst_addr = rte_cpu_to_be_32(dst_addr_ser);
146
147 packet_hdr->ipv4_hdr.version_ihl = (IPV4_VERSION << 4) | (sizeof(struct rte_ipv4_hdr) / 4);
148
149 packet_hdr->ipv4_hdr.total_length = rte_cpu_to_be_16(packet_len); // Payload + udp_hdr + iphdr
150 packet_hdr->ipv4_hdr.time_to_live = DEFAULT_TTL;
151 packet_hdr->ipv4_hdr.type_of_service = DEFAULT_TOS;
152
153 // https://perso.telecom-paristech.fr/drossi/paper/rossi17ipid.pdf
154 packet_hdr->ipv4_hdr.packet_id = rte_cpu_to_be_16(0); // I put a constant here..
155 packet_hdr->ipv4_hdr.fragment_offset = 0;
156 packet_hdr->ipv4_hdr.next_proto_id = IPPROTO_UDP;
157
158 packet_hdr->ipv4_hdr.hdr_checksum = 0;
159 //packet_hdr->ipv4_hdr.hdr_checksum = rte_ipv4_cksum(&packet_hdr->ipv4_hdr);
160
161 //UDP checksum
162 packet_hdr->udp_hdr.dgram_cksum = 0;
163 //packet_hdr->udp_hdr.dgram_cksum = rte_ipv4_udptcp_cksum(&packet_hdr->ipv4_hdr, (void *) &packet_hdr->udp_hdr);
164 //if (packet_hdr->udp_hdr.dgram_cksum == 0) {
165 // packet_hdr->udp_hdr.dgram_cksum = 0xFFFF;
166 //}
167 return ;
168}
169
170
171/**************************************************************************/
182void
183pktgen_ether_hdr_ctor(struct ipv4_udp_packet_hdr * packet_hdr, const std::string& router_mac_address, const int port_id)
184{
185 //pg_ether_addr_copy(&pkt->eth_src_addr, &eth->src_addr);
186 //pg_ether_addr_copy(&pkt->eth_dst_addr, &eth->dst_addr);
187
188 /* src and dest addr */
189 // See definition dpdk-20.08/lib/librte_net/rte_ether.c is defined as static -> not exposed to the lib... redefining here
190
191 get_ether_addr6(router_mac_address.c_str(), &packet_hdr->eth_hdr.dst_addr);
192
193 rte_eth_macaddr_get(port_id, &packet_hdr->eth_hdr.src_addr);
194
195 /* normal ethernet header */
196 packet_hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
197 return;
198}
199
200
201
202void construct_packets_for_burst(const int port_id, const std::string& dst_mac_addr, const int payload_bytes, const int burst_size, rte_mbuf** bufs) {
203 struct ipv4_udp_packet_hdr packet_hdr;
204
205 constexpr int eth_header_bytes = 14;
206 constexpr int udp_header_bytes = 8;
207 constexpr int ipv4_header_bytes = 20;
208
209 int eth_packet_bytes = eth_header_bytes + ipv4_header_bytes + udp_header_bytes + sizeof(detdataformats::DAQEthHeader) + payload_bytes;
210 int ipv4_packet_bytes = eth_packet_bytes - eth_header_bytes;
211 int udp_datagram_bytes = ipv4_packet_bytes - ipv4_header_bytes;
212
213 // Get info for the ethernet header (protocol stack level 2)
214 pktgen_ether_hdr_ctor(&packet_hdr, dst_mac_addr, port_id);
215
216 // Get info for the internet header (protocol stack level 3)
217 pktgen_ipv4_ctor(&packet_hdr, ipv4_packet_bytes);
218
219 // Get info for the UDP header (protocol stack level 4)
220 pktgen_udp_hdr_ctor(&packet_hdr, udp_datagram_bytes);
221
222 detdataformats::DAQEthHeader daqethheader_obj;
223 set_daqethheader_test_values(daqethheader_obj);
224
225 void* dataloc = nullptr;
226 for (int i_pkt = 0; i_pkt < burst_size; ++i_pkt) {
227
228 dataloc = rte_pktmbuf_mtod(bufs[i_pkt], char*);
229 rte_memcpy(dataloc, &packet_hdr, sizeof(packet_hdr));
230
231 dataloc = rte_pktmbuf_mtod_offset(bufs[i_pkt], char*, sizeof(packet_hdr));
232 rte_memcpy(dataloc, &daqethheader_obj, sizeof(daqethheader_obj));
233
234 bufs[i_pkt]->pkt_len = eth_packet_bytes;
235 bufs[i_pkt]->data_len = eth_packet_bytes;
236 }
237}
238
239
240} // namespace udp
241} // namespace dpdklibs
242} // namespace dunedaq
#define IPV4_VERSION
Definition PacketCtor.cpp:9
void pktgen_ether_hdr_ctor(struct ipv4_udp_packet_hdr *packet_hdr, const std::string &dst_mac_address="0a:00:10:c2:15:c1", const int port_id=0)
void construct_packets_for_burst(const int port_id, const std::string &dst_mac_addr, const int payload_bytes, const int burst_size, rte_mbuf **bufs)
void pktgen_ipv4_ctor(struct ipv4_udp_packet_hdr *packet_hdr, rte_le16_t packet_len, const std::string &src_ip_addr="0.0.0.0", const std::string &dst_ip_addr="0.0.0.0")
rte_le16_t packet_fill(struct ipv4_udp_packet_hdr *packet_hdr)
void set_daqethheader_test_values(detdataformats::DAQEthHeader &daqethheader_obj) noexcept
Definition Utils.cpp:232
static int8_t get_xdigit(char ch)
void pktgen_udp_hdr_ctor(struct ipv4_udp_packet_hdr *packet_hdr, rte_le16_t packet_len, int sport=55677, int dport=55678)
bool get_ether_addr6(const char *s0, struct rte_ether_addr *ea)
Including Qt Headers.
PDS Frame with unphysical timestamp detected with ch
DAQEthHeader is a versioned and unified structure for every FE electronics.