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