calc_single_hash.c Source File

Reference Documentation

Platform
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.15
Napatech Software Suite: examples/hashref/calc_single_hash/calc_single_hash.c Source File
calc_single_hash.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 hashref/calc_single_hash/calc_single_hash.c
45  * @section calc_single_hash_description Description
46  *
47  * This source file shows how to use the hash reference library
48  * to calculate the hash value(s) for some variants of key data.
49  *
50  * The following NTAPI functions are used:
51  * - @ref NT_HashRefOpen()
52  * - @ref NT_HashRefCalc()
53  * - @ref NT_HashRefClose()
54  *
55  * @section calc_single_hash_prerequisites Prerequisites
56  *
57  * - The driver must be installed such that the utility library and
58  * its accompanying header files are available. The example program
59  * does not require that a Napatech accelerator to be installed, or the driver the be
60  * up and running, or for a valid configuration file.
61  *
62  *<hr>
63  * @section calc_single_hash_code Code
64  * @}
65  */
66 
67 #include <string.h> /* memset */
68 #include <stdio.h> /* printf */
69 #ifdef _WIN32
70 #include <winsock2.h> /* htonl, htons */
71 #else
72 #include <arpa/inet.h> /* htonl, htons */
73 #endif
74 
75 #include "ntutil.h" /* Hash reference library */
76 
77 static int
79 {
80  config->config = NT_HASHREF_CONFIG_V0;
82  config->u.config_v0.fpgaid.s.item = 200;
83  config->u.config_v0.fpgaid.s.product = 9220;
84  config->u.config_v0.fpgaid.s.ver = 50;
85  config->u.config_v0.fpgaid.s.rev = 3;
86  config->u.config_v0.fpgaid.s.build = 0;
87  config->u.config_v0.hashmode = hash_mode;
88  /* Set the hash mask to its default value */
89  (void)memset(config->u.config_v0.hashmask, 0xff,
90  sizeof(config->u.config_v0.hashmask));
91  config->u.config_v0.streams = 4; /* Distribute to four streams */
92  config->u.config_v0.seed = 0xffffffff; /* ntservice default */
93 
94  return 0;
95 }
96 
97 static int do_2tuple_ipv4(void)
98 {
99  NtHashRefConfig_t config;
100  NtHashRef_t href;
101  NtHashRefInput_t input;
102  NtHashRefResult_t result;
103  int rc;
104  struct NtTuple2IPv4_s *hinput = &input.u.tuple2IPv4;
105 
107 
108  rc = NT_HashRefOpen(&href, &config);
109  if (rc) {
110  (void)fprintf(stderr, "Failed to open hash reference library\n");
111  return rc;
112  }
113 
114  /* Note that the hash mode must correspond to the input type
115  input.hashinput.tuple2IPv4, as specified by input.hashInputType. */
117  hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
118  hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
119 
120  rc = NT_HashRefCalc(href, &input, &result);
121  if (rc) {
122  (void)fprintf(stderr, "Cannot calculate hash value\n");
123  return rc;
124  }
125 
126  (void)printf("2-tuple hash of (src = 10.10.10.10, dst = 192.168.1.1):\n"
127  "\tvalue = 0x%x, stream number = %d\n",
128  result.hashvalue, result.stream);
129 
130  /* Swap the two IP addresses */
131  hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
132  hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
133 
134  rc = NT_HashRefCalc(href, &input, &result);
135  if (rc) {
136  (void)fprintf(stderr, "Cannot calculate hash value\n");
137  return rc;
138  }
139 
140  (void)printf("2-tuple hash of (src = 192.168.1.1, dst = 10.10.10.10):\n"
141  "\tvalue = 0x%x, stream number = %d\n",
142  result.hashvalue, result.stream);
143 
144  rc = NT_HashRefClose(href);
145  if (rc) {
146  (void)fprintf(stderr, "Failed to close hash reference library\n");
147  return rc;
148  }
149 
150  return 0;
151 }
152 
153 static int do_2tuple_ipv6(void)
154 {
155  NtHashRefConfig_t config;
156  NtHashRef_t href;
157  NtHashRefInput_t input;
158  NtHashRefResult_t result;
159  int rc;
160  const unsigned char src_ip[16] =
161  { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162  0x5a, 0x94, 0x6b, 0xff, 0xfe, 0x6a, 0x09, 0x48 };
163  const unsigned char dst_ip[16] =
164  { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165  0x12, 0x34, 0x39, 0x10, 0x12, 0x90, 0x44, 0x01 };
166  struct NtTuple2IPv6_s *hinput = &input.u.tuple2IPv6;
167 
169 
170  rc = NT_HashRefOpen(&href, &config);
171  if (rc) {
172  (void)fprintf(stderr, "Failed to open hash reference library\n");
173  return rc;
174  }
175 
176  /* Note that the hash mode must correspond to the input type
177  input.hashinput.tuple2IPv6, as specified by input.hashInputType. */
179  (void)memcpy(hinput->srcIP, src_ip, sizeof(src_ip));
180  (void)memcpy(hinput->dstIP, dst_ip, sizeof(dst_ip));
181 
182  rc = NT_HashRefCalc(href, &input, &result);
183  if (rc) {
184  (void)fprintf(stderr, "Cannot calculate hash value\n");
185  return rc;
186  }
187 
188  (void)printf("2-tuple hash of (src = fe80::5a94:6bff:fe6a:948,\n"
189  "dst = fe80::1234:3910:1290:4401)\n"
190  "\tvalue = 0x%x, stream number = %d\n",
191  result.hashvalue, result.stream);
192 
193  /* Swap the two IP addresses */
194  (void)memcpy(hinput->srcIP, dst_ip, sizeof(dst_ip));
195  (void)memcpy(hinput->dstIP, src_ip, sizeof(src_ip));
196 
197  rc = NT_HashRefCalc(href, &input, &result);
198  if (rc) {
199  (void)fprintf(stderr, "Cannot calculate hash value\n");
200  return rc;
201  }
202 
203 
204  (void)printf("2-tuple hash of (src = fe80::1234:3910:1290:4401,\n"
205  "dst = fe80::5a94:6bff:fe6a:948)\n"
206  "\tvalue = 0x%x, stream number = %d\n",
207  result.hashvalue, result.stream);
208 
209  rc = NT_HashRefClose(href);
210  if (rc) {
211  (void)fprintf(stderr, "Failed to close hash reference library\n");
212  return rc;
213  }
214 
215  return 0;
216 }
217 
218 static int do_5tuple_ipv4(void)
219 {
220  NtHashRefConfig_t config;
221  NtHashRef_t href;
222  NtHashRefInput_t input;
223  NtHashRefResult_t result;
224  int rc;
225  struct NtTuple5IPv4_s *hinput = &input.u.tuple5IPv4;
226 
228 
229  rc = NT_HashRefOpen(&href, &config);
230  if (rc) {
231  (void)fprintf(stderr, "Failed to open hash reference library\n");
232  return rc;
233  }
234 
235  /* Note that the hash mode must correspond to the input type
236  input.hashinput.tuple5IPv4, as specified by input.hashInputType. */
238  hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
239  hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
240  hinput->srcPort = htons(14532);
241  hinput->dstPort = htons(80);
242  hinput->protocol = 4;
243 
244  rc = NT_HashRefCalc(href, &input, &result);
245  if (rc) {
246  (void)fprintf(stderr, "Cannot calculate hash value\n");
247  return rc;
248  }
249 
250  (void)printf("5-tuple hash of (src = 10.10.10.10, dst = 192.168.1.1, "
251  "src_port = 14532, dst_port = 80, protocol = 4):\n"
252  "\tvalue = 0x%x, stream number = %d\n",
253  result.hashvalue, result.stream);
254 
255  /* Swap IP addresses (and ports) */
256  hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
257  hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
258  hinput->dstPort = htons(14532);
259  hinput->srcPort = htons(80);
260 
261  rc = NT_HashRefCalc(href, &input, &result);
262  if (rc) {
263  (void)fprintf(stderr, "Cannot calculate hash value\n");
264  return rc;
265  }
266 
267  (void)printf("5-tuple hash of (src = 192.168.1.1, dst = 10.10.10.10, "
268  "src_port = 14532, dst_port = 80, protocol = 4):\n"
269  "\tvalue = 0x%x, stream number = %d\n",
270  result.hashvalue, result.stream);
271 
272  rc = NT_HashRefClose(href);
273  if (rc) {
274  (void)fprintf(stderr, "Failed to close hash reference library\n");
275  return rc;
276  }
277 
278  return 0;
279 }
280 
281 static int do_5tuple_ipv6(void)
282 {
283  NtHashRefConfig_t config;
284  NtHashRef_t href;
285  NtHashRefInput_t input;
286  NtHashRefResult_t result;
287  int rc;
288  const unsigned char src_ip[16] =
289  { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290  0x5a, 0x94, 0x6b, 0xff, 0xfe, 0x6a, 0x09, 0x48 };
291  const unsigned char dst_ip[16] =
292  { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293  0x12, 0x34, 0x39, 0x10, 0x12, 0x90, 0x44, 0x01 };
294  struct NtTuple5IPv6_s *hinput = &input.u.tuple5IPv6;
295 
297 
298  rc = NT_HashRefOpen(&href, &config);
299  if (rc) {
300  (void)fprintf(stderr, "Failed to open hash reference library\n");
301  return rc;
302  }
303 
304  /* Note that the hash mode must correspond to the input type
305  input.hashinput.tuple5IPv6, as specified by input.hashInputType. */
307  assert(sizeof(hinput->srcIP) >= sizeof(src_ip));
308  assert(sizeof(hinput->dstIP) >= sizeof(dst_ip));
309  (void)memcpy(hinput->srcIP, src_ip, sizeof(src_ip));
310  (void)memcpy(hinput->dstIP, dst_ip, sizeof(dst_ip));
311  hinput->srcPort = htons(14532);
312  hinput->dstPort = htons(80);
313  hinput->protocol = 4;
314 
315  rc = NT_HashRefCalc(href, &input, &result);
316  if (rc) {
317  (void)fprintf(stderr, "Cannot calculate hash value\n");
318  return rc;
319  }
320 
321  (void)printf("5-tuple hash of (src = fe80::5a94:6bff:fe6a:948, "
322  "dst = fe80::1234:3910:1290:4401, dst_port = 80, protocol = 4):\n"
323  "\tvalue = 0x%x, stream number = %d\n",
324  result.hashvalue, result.stream);
325 
326  /* Swap IP addresses (and ports) */
327  (void)memcpy(hinput->srcIP, dst_ip, sizeof(dst_ip));
328  (void)memcpy(hinput->dstIP, src_ip, sizeof(src_ip));
329  hinput->dstPort = htons(14532);
330  hinput->srcPort = htons(80);
331 
332  rc = NT_HashRefCalc(href, &input, &result);
333  if (rc) {
334  (void)fprintf(stderr, "Cannot calculate hash value\n");
335  return rc;
336  }
337 
338  (void)printf("5-tuple hash of (src = fe80::1234:3910:1290:4401, "
339  "dst = fe80::5a94:6bff:fe6a:948, dst_port = 80, protocol = 4):\n"
340  "\tvalue = 0x%x, stream number = %d\n",
341  result.hashvalue, result.stream);
342 
343  rc = NT_HashRefClose(href);
344  if (rc) {
345  (void)fprintf(stderr, "Failed to close hash reference library\n");
346  return rc;
347  }
348 
349  return 0;
350 }
351 
352 static int do_ipfragmenttuple_ipv4(void)
353 {
354  NtHashRefConfig_t config;
355  NtHashRef_t href;
356  NtHashRefInput_t input;
357  NtHashRefResult_t result;
358  int rc;
359  struct NtIpFragmentTupleIPv4_s *hinput = &input.u.ipFragmentTupleIPv4;
360 
362 
363  rc = NT_HashRefOpen(&href, &config);
364  if (rc) {
365  (void)fprintf(stderr, "Failed to open hash reference library\n");
366  return rc;
367  }
368 
369  /* Note that the hash mode must correspond to the input type
370  input.hashinput.ipFragmentTupleIPv4,
371  as specified by input.hashInputType. */
373  hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
374  hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
375  hinput->ipId = htons(0x1234); /* 16 bits IP ID */
376  hinput->ipProt = (uint8_t)1; /* 1 = ICMP */
377 
378  rc = NT_HashRefCalc(href, &input, &result);
379  if (rc) {
380  (void)fprintf(stderr, "Cannot calculate hash value\n");
381  return rc;
382  }
383 
384  (void)printf("IP fragment hash of (src = 10.10.10.10, dst = 192.168.1.1):\n"
385  "\tvalue = 0x%x, stream number = %d\n",
386  result.hashvalue, result.stream);
387 
388  hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
389  hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
390 
391  rc = NT_HashRefCalc(href, &input, &result);
392  if (rc) {
393  (void)fprintf(stderr, "Cannot calculate hash value\n");
394  return rc;
395  }
396 
397  (void)printf("IP fragment hash of (src = 192.168.1.1, dst = 10.10.10.10):\n"
398  "\tvalue = 0x%x, stream number = %d\n",
399  result.hashvalue, result.stream);
400 
401  rc = NT_HashRefClose(href);
402  if (rc) {
403  (void)fprintf(stderr, "Failed to close hash reference library\n");
404  return rc;
405  }
406 
407  return 0;
408 }
409 
410 int main(void)
411 {
412  (void)do_2tuple_ipv4();
413  (void)do_2tuple_ipv6();
414  (void)do_5tuple_ipv4();
415  (void)do_5tuple_ipv6();
416  (void)do_ipfragmenttuple_ipv4();
417 
418  return 0;
419 }