flowmatch_example_transmitter.cpp Source File

Reference Documentation

Platform
Intel® PAC
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.10
Napatech Software Suite: examples/flowmatch/flowmatch_example_transmitter.cpp Source File
flowmatch_example_transmitter.cpp
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2023 Napatech A/S. All Rights Reserved.
4  *
5  * 1. Copying, modification, and distribution of this file, or executable
6  * versions of this file, is governed by the terms of the Napatech Software
7  * license agreement under which this file was made available. If you do not
8  * agree to the terms of the license do not install, copy, access or
9  * otherwise use this file.
10  *
11  * 2. Under the Napatech Software license agreement you are granted a
12  * limited, non-exclusive, non-assignable, copyright license to copy, modify
13  * and distribute this file in conjunction with Napatech SmartNIC's and
14  * similar hardware manufactured or supplied by Napatech A/S.
15  *
16  * 3. The full Napatech Software license agreement is included in this
17  * distribution, please see "NP-0405 Napatech Software license
18  * agreement.pdf"
19  *
20  * 4. Redistributions of source code must retain this copyright notice,
21  * list of conditions and the following disclaimer.
22  *
23  * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, EXPRESS OR
24  * IMPLIED, AND NAPATECH DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING ANY
25  * IMPLIED WARRANTY OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, OR OF
26  * FITNESS FOR A PARTICULAR PURPOSE. TO THE EXTENT NOT PROHIBITED BY
27  * APPLICABLE LAW, IN NO EVENT SHALL NAPATECH BE LIABLE FOR PERSONAL INJURY,
28  * OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER,
29  * INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, CORRUPTION OR
30  * LOSS OF DATA, FAILURE TO TRANSMIT OR RECEIVE ANY DATA OR INFORMATION,
31  * BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING
32  * OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE NAPATECH SOFTWARE OR
33  * SERVICES OR ANY THIRD PARTY SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH
34  * THE NAPATECH SOFTWARE OR SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY
35  * OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF NAPATECH HAS BEEN
36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW
37  * THE EXCLUSION OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF
38  * INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU.
39  *
40  *
41 
42  */
43 
44 // Include this in order to access the Napatech API
45 #include <nt.h>
46 
47 #include <algorithm>
48 #include <chrono>
49 #include <cstdint>
50 #include <cstring>
51 #include <thread>
52 
54 
56 
57 namespace {
58 
59 /**
60  * Swap the IP addresses and port numbers for a package.
61  * Works for both IPv4 and IPv6.
62  */
63 void swapIpAndPort(uint8_t* package)
64 {
65  unsigned int etherType = 12;
66  unsigned int ipHeader = 0;
67  unsigned int tcpHeader = 0;
68 
69  // Handle IEEE 802.1Q
70  if (package[etherType] == 0x81 && package[etherType+1] == 0x00) etherType += 4;
71  ipHeader = etherType + 2;
72 
73  if (package[etherType] == 0x08 && package[etherType+1] == 0x00) { // IPv4
74  unsigned int internetHeaderLength = (package[ipHeader] & 0x0f) * 4;
75  tcpHeader = ipHeader + internetHeaderLength;
76 
77  std::swap_ranges(package+ipHeader+12,package+ipHeader+12+4,package+ipHeader+16);
78  }
79  else if (package[etherType] == 0x86 && package[etherType+1] == 0xdd) { // IPv6
80  tcpHeader = ipHeader + 40;
81 
82  std::swap_ranges(package+ipHeader+8,package+ipHeader+8+16,package+ipHeader+24);
83  }
84  else {
85  return;
86  }
87 
88  std::swap_ranges(package+tcpHeader+0,package+tcpHeader+0+2,package+tcpHeader+2);
89 }
90 
91 } // Unnamed namespace
92 
93 void taskTransmitter(uint32_t port, const uint8_t* package, size_t packageSize,
94  size_t frameSize, int numPackages, uint64_t perPackageDelay, bool swapIp)
95 {
96  int status;
97  NtNetStreamTx_t hNetTx;
98  NtNetBuf_t hNetBufTx;
99 
100  // Open a TX stream.
101  status = NT_NetTxOpen(&hNetTx, "flowmatch_example_transmitter", 1ULL << port, NT_NETTX_NUMA_ANY_HB, 0);
102  handleErrorStatus(status, "NT_NetTxOpen() failed");
103 
104  for (int i = 0; i < numPackages; ++i) {
105  // Get a packet TX buffer for this tx stream and port, 100 ms timeout.
106  status = NT_NetTxGet(hNetTx, &hNetBufTx, port, frameSize, NT_NETTX_PACKET_OPTION_DEFAULT, 100);
107  handleErrorStatus(status, "NT_NetTxGet() failed");
108 
109  // Set data to be transmitted.
110  uint8_t* ptr = static_cast<uint8_t*>(NT_NET_GET_PKT_L2_PTR(hNetBufTx));
111  std::memset(ptr, 0, frameSize);
112  std::memcpy(ptr, package, packageSize);
113  if (swapIp) {
114  swapIpAndPort(ptr);
115  }
116 
117  // Release the TX buffer to transmit the packet.
118  status = NT_NetTxRelease(hNetTx, hNetBufTx);
119  handleErrorStatus(status, "NT_NetTxRelease() failed");
120 
121  if (perPackageDelay != 0) {
122  std::this_thread::sleep_for(std::chrono::milliseconds(perPackageDelay));
123  }
124  }
125 
126  // Give the daemon time to transmit all packages before closing.
127  std::this_thread::sleep_for(std::chrono::milliseconds(100));
128 
129  // Close TX stream.
130  status = NT_NetTxClose(hNetTx);
131  handleErrorStatus(status, "NT_NetTxClose() failed");
132 
133  // Delay before NT_NetTxOpen is called again.
134  std::this_thread::sleep_for(std::chrono::milliseconds(100));
135 }