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