DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
Utils.cpp
Go to the documentation of this file.
1
9
11#include "logging/Logging.hpp"
13
14#include <algorithm>
15#include <cstring>
16#include <fstream>
17#include <iomanip>
18#include <iterator>
19#include <sstream>
20#include <string>
21#include <utility>
22#include <vector>
23
24namespace dunedaq {
25namespace dpdklibs {
26namespace udp {
27
28std::uint16_t
29get_payload_size_udp_hdr(struct rte_udp_hdr* udp_hdr)
30{
31 return rte_be_to_cpu_16(udp_hdr->dgram_len) - sizeof(struct rte_udp_hdr);
32}
33
34std::uint16_t
36{
37 return rte_be_to_cpu_16(ipv4_udp_hdr->udp_hdr.dgram_len) - sizeof(struct rte_udp_hdr);
38}
39
40rte_be32_t
41ip_address_dotdecimal_to_binary(std::uint8_t byte1, std::uint8_t byte2, std::uint8_t byte3, std::uint8_t byte4)
42{
43 rte_le32_t ip_address = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
44 return rte_cpu_to_be_32(ip_address);
45}
46
47struct ipaddr
48ip_address_binary_to_dotdecimal(rte_le32_t binary_ipv4_address)
49{
50 struct ipaddr addr;
51 memcpy(&addr, &binary_ipv4_address, sizeof(rte_le32_t));
52 return addr;
53}
54
55std::string
57{
58 std::ostringstream ostrs;
59 ostrs << (unsigned)ipv4_address.addr_bytes[3] << '.' << (unsigned)ipv4_address.addr_bytes[2] << '.' << (unsigned)ipv4_address.addr_bytes[1] << '.' << (unsigned)ipv4_address.addr_bytes[0];
60 return ostrs.str();
61 /*printf("%i.%i.%i.%i",
62 ipv4_address.addr_bytes[3],
63 ipv4_address.addr_bytes[2],
64 ipv4_address.addr_bytes[1],
65 ipv4_address.addr_bytes[0]);
66 */
67}
68
69char*
70get_udp_payload(const rte_mbuf* mbuf)
71{
72 struct ipv4_udp_packet_hdr* udp_packet = rte_pktmbuf_mtod(mbuf, struct ipv4_udp_packet_hdr*);
73 // dump_udp_header(udp_packet);
74 // uint16_t payload_size = get_payload_size(udp_packet);
75 char* payload = (char*)(udp_packet + 1);
76 return payload;
77
78 /*
79 if (dump_mode == 10) {
80 return payload;
81 }
82
83 if (dump_mode == 0 || dump_mode == 3) {
84 printf("UDP Payload size: %i\n", payload_size);
85 uint byte;
86 for (byte = 0; byte < payload_size; byte++) {
87 printf("%02x ", *(payload + byte) & 0xFF);
88 //printf("%s", (payload + byte));
89 }
90 printf("\n");
91 }
92
93 if (dump_mode == 1 || dump_mode == 3) {
94 printf("%s\n", payload);
95 }
96 return payload;
97 */
98}
99
100inline void
101hex_digits_to_stream(std::ostringstream& ostrs, int value, char separator = ':', char fill = '0', int digits = 2)
102{
103 ostrs << std::setfill(fill) << std::setw(digits) << std::hex << value << std::dec << separator;
104}
105
106std::string
107// dump_udp_header(struct ipv4_udp_packet_hdr * pkt)
108get_udp_header_str(struct rte_mbuf* mbuf)
109{
110 struct ipv4_udp_packet_hdr* pkt = rte_pktmbuf_mtod(mbuf, struct ipv4_udp_packet_hdr*);
111 std::ostringstream ostrs;
112 ostrs << "\n------ start of packet ----- \n";
113 ostrs << "dst mac addr: ";
114 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[0]);
115 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[1]);
116 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[2]);
117 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[3]);
118 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[4]);
119 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.dst_addr.addr_bytes[5], '\n');
120 ostrs << "src mac addr: ";
121 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[0]);
122 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[1]);
123 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[2]);
124 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[3]);
125 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[4]);
126 hex_digits_to_stream(ostrs, (int)pkt->eth_hdr.src_addr.addr_bytes[5], '\n');
127 ostrs << "ethtype: " << (unsigned)pkt->eth_hdr.ether_type << '\n';
128
129 ostrs << "------ IP header ----- \n";
130 ostrs << "ipv4 version: " << (unsigned)pkt->ipv4_hdr.version_ihl << '\n';
131 ostrs << "ipv4 type_of_service: " << (unsigned)pkt->ipv4_hdr.type_of_service << '\n';
132 ostrs << "ipv4 total lenght: " << (unsigned)rte_be_to_cpu_16(pkt->ipv4_hdr.total_length) << '\n';
133 ostrs << "ipv4 packet_id: " << (unsigned)pkt->ipv4_hdr.packet_id << '\n';
134 ostrs << "ipv4 fragment_offset: " << (unsigned)pkt->ipv4_hdr.fragment_offset << '\n';
135 ostrs << "ipv4 time_to_live: " << (unsigned)pkt->ipv4_hdr.time_to_live << '\n';
136 ostrs << "ipv4 next_proto_id: " << (unsigned)pkt->ipv4_hdr.next_proto_id << '\n';
137 ostrs << "ipv4 checksum: " << (unsigned)rte_be_to_cpu_16(pkt->ipv4_hdr.hdr_checksum) << '\n';
138 std::string srcaddr = get_ipv4_decimal_addr_str(ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(pkt->ipv4_hdr.src_addr)));
139 std::string dstaddr = get_ipv4_decimal_addr_str(ip_address_binary_to_dotdecimal(rte_be_to_cpu_32(pkt->ipv4_hdr.dst_addr)));
140 ostrs << "src_addr: " << srcaddr << '\n';
141 ostrs << "dst_addr: " << dstaddr << '\n';
142
143 ostrs << "------ UDP header ----- \n";
144 ostrs << "UDP src_port: " << (unsigned)rte_be_to_cpu_16(pkt->udp_hdr.src_port) << '\n';
145 ostrs << "UDP dst_port: " << (unsigned)rte_be_to_cpu_16(pkt->udp_hdr.dst_port) << '\n';
146 ostrs << "UDP len: " << (unsigned)rte_be_to_cpu_16(pkt->udp_hdr.dgram_len) << '\n';
147 ostrs << "UDP checksum: " << (unsigned)rte_be_to_cpu_16(pkt->udp_hdr.dgram_cksum) << '\n';
148
149 return ostrs.str();
150}
151
152std::string
153get_udp_packet_str(struct rte_mbuf* mbuf)
154{
155 struct ipv4_udp_packet_hdr* pkt = rte_pktmbuf_mtod(mbuf, struct ipv4_udp_packet_hdr*);
156 char* payload = (char*)(pkt);
157 std::ostringstream ostrs;
158 std::uint8_t byte;
159 for (byte = 0; byte < rte_be_to_cpu_16(pkt->udp_hdr.dgram_len); byte++) {
160 hex_digits_to_stream(ostrs, (unsigned)(*(payload + byte)), ' ');
161 // printf("%02x ", *(payload + byte) & 0xFF);
162 // printf("%s", (payload + byte));
163 }
164 return ostrs.str();
165}
166
167void
168add_file_contents_to_vector(const std::string& filename, std::vector<char>& buffervec)
169{
170
171 char byte = 0x0;
172
173 std::ifstream packetfile;
174 packetfile.open(filename, std::ios::binary);
175
176 if (!packetfile) {
177 throw ::dunedaq::datahandlinglibs::CannotOpenFile(ERS_HERE, filename);
178 }
179
180 while (packetfile.get(byte)) {
181 buffervec.push_back(byte);
182 }
183
184 packetfile.close();
185}
186
187std::vector<std::pair<const void*, int>>
188get_ethernet_packets(const std::vector<char>& buffervec)
189{
190
191 std::vector<std::pair<const void*, int>> ethernet_packets;
192 const std::vector<uint16_t> allowed_ethertypes{ 0x0800, 0x0806 };
193
194 for (int byte_index = 0; byte_index < buffervec.size();) {
195 const auto buf_ptr = &buffervec.at(byte_index);
196 auto hdr = reinterpret_cast<const ipv4_udp_packet_hdr*>(buf_ptr);
197
198 // A sanity check
199 bool match = false;
200 for (auto allowed_ethertype : allowed_ethertypes) {
201 if (hdr->eth_hdr.ether_type == rte_be_to_cpu_16(allowed_ethertype)) {
202 match = true;
203 break;
204 }
205 }
206
207 if (!match) {
208 std::stringstream msgstr;
209 msgstr << "Ether type in ethernet header (value " << std::hex << rte_be_to_cpu_16(hdr->eth_hdr.ether_type) << std::dec << ") either unknown or unsupported";
210 throw dunedaq::dpdklibs::BadPacketHeaderIssue(ERS_HERE, msgstr.str());
211 }
212
213 int ipv4_packet_size = rte_be_to_cpu_16(hdr->ipv4_hdr.total_length);
214 constexpr int min_packet_size = sizeof(rte_ipv4_hdr) + sizeof(rte_udp_hdr);
215 constexpr int max_packet_size = 10000;
216
217 if (ipv4_packet_size < min_packet_size || ipv4_packet_size > max_packet_size) {
218 std::stringstream msgstr;
219 msgstr << "Calculated IPv4 packet size of " << ipv4_packet_size << " bytes is out of the required range of (" << min_packet_size << ", " << max_packet_size << ") bytes";
220 throw dunedaq::dpdklibs::BadPacketHeaderIssue(ERS_HERE, msgstr.str());
221 }
222
223 int ethernet_packet_size = sizeof(rte_ether_hdr) + ipv4_packet_size;
224 ethernet_packets.emplace_back(std::pair<const void*, int>{ buf_ptr, ethernet_packet_size });
225 byte_index += ethernet_packet_size;
226 }
227
228 return ethernet_packets;
229}
230
231void
233{
234 daqethheader_obj.version = 0;
235 daqethheader_obj.det_id = 1;
236 daqethheader_obj.crate_id = 2;
237 daqethheader_obj.slot_id = 3;
238 daqethheader_obj.stream_id = 4;
239 daqethheader_obj.reserved = 5;
240 daqethheader_obj.seq_id = 6;
241 daqethheader_obj.block_length = 7;
242 daqethheader_obj.timestamp = 8;
243}
244
245std::string
246get_rte_mbuf_str(const rte_mbuf* mbuf) noexcept
247{
248 std::stringstream ss;
249
250 ss << "\nrte_mbuf info:";
251 ss << "\npkt_len: " << mbuf->pkt_len;
252 ss << "\ndata_len: " << mbuf->data_len;
253 ss << "\nBuffer address: " << std::hex << mbuf->buf_addr;
254 ss << "\nRef count: " << std::dec << rte_mbuf_refcnt_read(mbuf);
255 ss << "\nport: " << mbuf->port;
256 ss << "\nol_flags: " << std::hex << mbuf->ol_flags;
257 ss << "\npacket_type: " << std::dec << mbuf->packet_type;
258 ss << "\nl2 type: " << static_cast<int>(mbuf->l2_type);
259 ss << "\nl3 type: " << static_cast<int>(mbuf->l3_type);
260 ss << "\nl4 type: " << static_cast<int>(mbuf->l4_type);
261 ss << "\ntunnel type: " << static_cast<int>(mbuf->tun_type);
262 ss << "\nInner l2 type: " << static_cast<int>(mbuf->inner_l2_type);
263 ss << "\nInner l3 type: " << static_cast<int>(mbuf->inner_l3_type);
264 ss << "\nInner l4 type: " << static_cast<int>(mbuf->inner_l4_type);
265 ss << "\nbuf_len: " << mbuf->buf_len;
266 ss << "\nl2_len: " << mbuf->l2_len;
267 ss << "\nl3_len: " << mbuf->l3_len;
268 ss << "\nl4_len: " << mbuf->l4_len;
269 ss << "\nouter_l2_len: " << mbuf->outer_l2_len;
270 ss << "\nouter_l3_len: " << mbuf->outer_l3_len;
271 ss << std::dec;
272
273 return ss.str();
274}
275
276std::string
277get_opmon_string(const StreamUID& sid)
278{
279 std::stringstream opmonstr;
280 opmonstr << "det" << sid.det_id << "_crt" << sid.crate_id << "_slt" << sid.slot_id << "_str" << sid.stream_id;
281 return opmonstr.str();
282}
283
284} // namespace udp
285} // namespace dpdklibs
286} // namespace dunedaq
#define ERS_HERE
static void fill(const ResourceSet &rs, std::vector< const ResourceSetOR * > &rs_or, std::vector< const ResourceSetAND * > &rs_and, TestCircularDependency &cd_fuse)
rte_be32_t ip_address_dotdecimal_to_binary(std::uint8_t byte1, std::uint8_t byte2, std::uint8_t byte3, std::uint8_t byte4)
Definition Utils.cpp:41
std::uint16_t get_payload_size(struct ipv4_udp_packet_hdr *ipv4_udp_hdr)
Definition Utils.cpp:35
std::string get_udp_packet_str(struct rte_mbuf *mbuf)
Definition Utils.cpp:153
void hex_digits_to_stream(std::ostringstream &ostrs, int value, char separator=':', char fill='0', int digits=2)
Definition Utils.cpp:101
std::vector< std::pair< const void *, int > > get_ethernet_packets(const std::vector< char > &buffervec)
Definition Utils.cpp:188
char * get_udp_payload(const rte_mbuf *mbuf)
Definition Utils.cpp:70
std::string get_ipv4_decimal_addr_str(struct ipaddr ipv4_address)
Definition Utils.cpp:56
std::string get_opmon_string(const StreamUID &sid)
Definition Utils.cpp:277
std::string get_udp_header_str(struct rte_mbuf *mbuf)
Definition Utils.cpp:108
struct ipaddr ip_address_binary_to_dotdecimal(rte_le32_t binary_ipv4_address)
Definition Utils.cpp:48
void add_file_contents_to_vector(const std::string &filename, std::vector< char > &buffervec)
Definition Utils.cpp:168
std::uint16_t get_payload_size_udp_hdr(struct rte_udp_hdr *udp_hdr)
Definition Utils.cpp:29
std::string get_rte_mbuf_str(const rte_mbuf *mbuf) noexcept
Definition Utils.cpp:246
void set_daqethheader_test_values(detdataformats::DAQEthHeader &daqethheader_obj) noexcept
Definition Utils.cpp:232
Including Qt Headers.
DAQEthHeader is a versioned and unified structure for every FE electronics.