transmit_pcap_example.c Source File

Reference Documentation

Platform
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.15
Napatech Software Suite: examples/net/transmit_pcap/transmit_pcap_example.c Source File
transmit_pcap_example.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2025 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 "NA-0009 Software License Agreement.pdf"
18  *
19  * 4. Redistributions of source code must retain this copyright notice,
20  * list of conditions and the following disclaimer.
21  *
22  * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, EXPRESS OR
23  * IMPLIED, AND NAPATECH DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING ANY
24  * IMPLIED WARRANTY OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, OR OF
25  * FITNESS FOR A PARTICULAR PURPOSE. TO THE EXTENT NOT PROHIBITED BY
26  * APPLICABLE LAW, IN NO EVENT SHALL NAPATECH BE LIABLE FOR PERSONAL INJURY,
27  * OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER,
28  * INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, CORRUPTION OR
29  * LOSS OF DATA, FAILURE TO TRANSMIT OR RECEIVE ANY DATA OR INFORMATION,
30  * BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING
31  * OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE NAPATECH SOFTWARE OR
32  * SERVICES OR ANY THIRD PARTY SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH
33  * THE NAPATECH SOFTWARE OR SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY
34  * OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF NAPATECH HAS BEEN
35  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW
36  * THE EXCLUSION OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF
37  * INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU.
38  *
39  *
40 
41  */
42 
43 /**
44  * @example net/transmit_pcap/transmit_pcap_example.c
45  * @section transmit_pcap_example_description Description
46  *
47  * This source file is an example of how to transmit PCAP packets using the
48  * packet interface in NTAPI. The example will transmit 2500000 packets with a
49  * size of 1024 bytes from port 0. The packet contains an incrementing 32bit
50  * pattern.
51  *
52  * PCAP can also be used with transmit on timestamp, or segment interfaces. See
53  * the respective examples to see how to use those interfaces. Note that for
54  * PCAP transmit on timestamp, the "forceTxOnTs" feature must be enabled.
55  *
56  * The following NTAPI functions are used:
57  * - @ref NT_Init()
58  * - @ref NT_NetTxOpen_v2()
59  * - @ref NT_NetTxGet()
60  * - @ref NT_NET_GET_PKT_L2_PTR()
61  * - @ref NT_NetTxRelease()
62  * - @ref NT_NetTxClose()
63  * - @ref NT_Done()
64  * - @ref NT_ExplainError()
65  *
66  * @section transmit_pcap_example_prerequisites Prerequisites
67  * - The ntservice.ini must have at least one HostBuffersTx defined. Below is
68  * an example of a minimum ini-file. It will create a 4MB TX hostbuffer from
69  * NUMA node 0.
70  *
71  * @code
72  * [System]
73  * TimestampFormat = NATIVE
74  *
75  * [Adapter0]
76  * AdapterType = NT20E2
77  * BusId = 00:0a:00.00
78  * HostBuffersTx = [1,4,0]
79  * @endcode
80  *
81  * @section transmit_pcap_example_flow Program flow
82  * @{
83  * The following is required to transmit packets:
84  * - \#include/nt.h - Applications/Tools only need to include @ref
85  * nt.h to obtain prototypes, macros etc. from NTAPI.
86  * - @ref NT_Init(@ref NTAPI_VERSION) - Initialize the NTAPI
87  * library. @ref NTAPI_VERSION is a define that describes the version
88  * of the API described in the header files included by @ref
89  * nt.h. NT_Init() will ask the NTAPI library to convert return data
90  * to the @ref NTAPI_VERSION if possible. This will ensure that
91  * applications can run on NTAPI libraries of newer versions.
92  * - @ref NT_NetTxOpen_v2() - Open a hostbuffer than can transmit packets to port 0.
93  * - @ref NT_NetTxGet() - Get an empty tx buffer. This will get a 296 byte
94  * wire length packet buffer that will be sent onto port 0 when
95  * released.
96  * - @ref NT_NET_GET_PKT_DESCR_PTR() is used to retrieve the descriptor
97  * - @ref NT_NET_GET_PKT_L2_PTR() is used to get the L2 pointer to the tx
98  * buffer, this is where the payload is placed.
99  * - @ref NT_NetTxRelease() - Release the tx packet buffer. Once a tx
100  * buffer is released it will be transmitted
101  * - @ref NT_NetTxClose() - Close the TX stream.
102  * - @ref NT_Done() - Close down the NTAPI library.
103  *
104  *<hr>
105  * @section transmit_pcap_example_code Code
106  * @}
107  */
108 
109 // Include this in order to access the Napatech API
110 #include <nt.h>
111 
112 // default TX packet test setup
113 #define PACKETS 2500000
114 #define PACKET_SIZE 1024 // Packet size to transmit (incl crc.)
115 #define PORT 0
116 
117 // This is the timespec for PCAP. For PCAP_NANO, the ts_usec field
118 // will instead of micro-seconds contain nanoseconds.
119 struct pcap_timespec_s {
120  uint32_t ts_sec;
121  uint32_t ts_usec;
122 };
123 
124 // Standard PCAP record header.
125 struct pcap_record_s {
126  struct pcap_timespec_s time;
127  uint32_t incl_len;
128  uint32_t orig_len;
129 };
130 
131 // printError is a simple convenience function for printing an NTAPI error
132 // message to stderr.
133 static void printError(const char *prefix, int errorCode) {
134  char errorBuffer[NT_ERRBUF_SIZE];
135  NT_ExplainError(errorCode, errorBuffer, sizeof errorBuffer);
136  fprintf(stderr, "%s: %s\n", prefix, errorBuffer);
137 }
138 
139 int main(void)
140 {
141  //
142  // Initialize the API. This also checks if we are compatible with the
143  // installed library version.
144  //
145  int status;
146 
147  if ((status = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) {
148  printError("NT_Init() failed", status);
149  return -1;
150  }
151 
152  //
153  // Open a TX stream
154  //
155  NtNetStreamTx_t hNetTx;
156  NtNetTxAttr_t txAttr;
157  NT_NetTxOpenAttrSetName(&txAttr, "pcaptransmit_example_txstream");
158  NT_NetTxOpenAttrSetPortMask(&txAttr, (1<<PORT));
162 
163  if ((status = NT_NetTxOpen_Attr(&hNetTx, &txAttr)) != NT_SUCCESS) {
164  printError("NT_NetTxOpen_Attr() failed", status);
165  return -1;
166  }
167 
168  //
169  // Retrieve a packet buffer, fill it, and repeat until we have transmitted
170  // the requested amount of packets.
171  //
172  printf("Commencing transmission\n");
173 
174  NtNetBuf_t hNetBufTx;
175  int numPackets;
176 
177  for (numPackets = 0; numPackets < PACKETS; numPackets++) {
178 
179  // Get a packet TX buffer for this tx stream and port, without timeout
180  if ((status = NT_NetTxGet(hNetTx, &hNetBufTx, PORT, PACKET_SIZE,
181  NT_NETTX_PACKET_OPTION_DEFAULT, -1)) != NT_SUCCESS) {
182  printError("NT_NetTxGet() failed", status);
183  return -1;
184  }
185 
186  // Fill the packet with an incrementing payload. Note that this will result
187  // in a garbage ethernet frame.
188  uint32_t *ptr = (uint32_t*)NT_NET_GET_PKT_L2_PTR(hNetBufTx);
189  for (uint32_t i = 0; i < PACKET_SIZE/4; i++) {
190  *(ptr+i) = i;
191  }
192 
193  // Set the pcap header fields. If used in a transmit on timestamp context,
194  // the timeval fields must be set to a sensible value.
195  struct pcap_record_s *hdr = (struct pcap_record_s*)NT_NET_GET_PKT_DESCR_PTR(hNetBufTx);
196  hdr->incl_len = PACKET_SIZE;
197  hdr->orig_len = PACKET_SIZE;
198  hdr->time.ts_sec = 0;
199  hdr->time.ts_usec = 0;
200 
201  // Release the TX buffer to transmit the packet.
202  if ((status = NT_NetTxRelease(hNetTx, hNetBufTx)) != NT_SUCCESS) {
203  printError("NT_NetTxRelease() failed", status);
204  return -1;
205  }
206  }
207 
208  //
209  // Terminate
210  //
211  printf("Done: %d packets sent\n", numPackets);
212 
213  // Close the TX stream
214  NT_NetTxClose(hNetTx);
215 
216  // Close the API
217  NT_Done();
218 
219  return 0;
220 }