hashref/calc_single_hash/calc_single_hash.c

Reference Documentation

Platform
Intel® PAC
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.10
Napatech Software Suite: hashref/calc_single_hash/calc_single_hash.c
hashref/calc_single_hash/calc_single_hash.c

Description

This source file shows how to use the hash reference library to calculate the hash value(s) for some variants of key data.

The following NTAPI functions are used:

Prerequisites

  • The driver must be installed such that the utility library and its accompanying header files are available. The example program does not require that a Napatech accelerator to be installed, or the driver the be up and running, or for a valid configuration file.

Code

/*
*
* Copyright 2023 Napatech A/S. All Rights Reserved.
*
* 1. Copying, modification, and distribution of this file, or executable
* versions of this file, is governed by the terms of the Napatech Software
* license agreement under which this file was made available. If you do not
* agree to the terms of the license do not install, copy, access or
* otherwise use this file.
*
* 2. Under the Napatech Software license agreement you are granted a
* limited, non-exclusive, non-assignable, copyright license to copy, modify
* and distribute this file in conjunction with Napatech SmartNIC's and
* similar hardware manufactured or supplied by Napatech A/S.
*
* 3. The full Napatech Software license agreement is included in this
* distribution, please see "NP-0405 Napatech Software license
* agreement.pdf"
*
* 4. Redistributions of source code must retain this copyright notice,
* list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, EXPRESS OR
* IMPLIED, AND NAPATECH DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING ANY
* IMPLIED WARRANTY OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, OR OF
* FITNESS FOR A PARTICULAR PURPOSE. TO THE EXTENT NOT PROHIBITED BY
* APPLICABLE LAW, IN NO EVENT SHALL NAPATECH BE LIABLE FOR PERSONAL INJURY,
* OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER,
* INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, CORRUPTION OR
* LOSS OF DATA, FAILURE TO TRANSMIT OR RECEIVE ANY DATA OR INFORMATION,
* BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING
* OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE NAPATECH SOFTWARE OR
* SERVICES OR ANY THIRD PARTY SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH
* THE NAPATECH SOFTWARE OR SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY
* OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF NAPATECH HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW
* THE EXCLUSION OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF
* INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU.
*
*
*/
/**
* @example hashref/calc_single_hash/calc_single_hash.c
* @section calc_single_hash_description Description
*
* This source file shows how to use the hash reference library
* to calculate the hash value(s) for some variants of key data.
*
* The following NTAPI functions are used:
* - @ref NT_HashRefOpen()
* - @ref NT_HashRefCalc()
* - @ref NT_HashRefClose()
*
* @section calc_single_hash_prerequisites Prerequisites
*
* - The driver must be installed such that the utility library and
* its accompanying header files are available. The example program
* does not require that a Napatech accelerator to be installed, or the driver the be
* up and running, or for a valid configuration file.
*
*<hr>
* @section calc_single_hash_code Code
* @}
*/
#include <string.h> /* memset */
#include <stdio.h> /* printf */
#ifdef _WIN32
#include <winsock2.h> /* htonl, htons */
#else
#include <arpa/inet.h> /* htonl, htons */
#endif
#include "ntutil.h" /* Hash reference library */
static int
{
config->u.config_v0.fpgaid.s.item = 200;
config->u.config_v0.fpgaid.s.product = 9220;
config->u.config_v0.fpgaid.s.ver = 50;
config->u.config_v0.fpgaid.s.rev = 3;
config->u.config_v0.fpgaid.s.build = 0;
config->u.config_v0.hashmode = hash_mode;
/* Set the hash mask to its default value */
(void)memset(config->u.config_v0.hashmask, 0xff,
sizeof(config->u.config_v0.hashmask));
config->u.config_v0.streams = 4; /* Distribute to four streams */
config->u.config_v0.seed = 0xffffffff; /* ntservice default */
return 0;
}
static int do_2tuple_ipv4(void)
{
int rc;
struct NtTuple2IPv4_s *hinput = &input.u.tuple2IPv4;
rc = NT_HashRefOpen(&href, &config);
if (rc) {
(void)fprintf(stderr, "Failed to open hash reference library\n");
return rc;
}
/* Note that the hash mode must correspond to the input type
input.hashinput.tuple2IPv4, as specified by input.hashInputType. */
hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("2-tuple hash of (src = 10.10.10.10, dst = 192.168.1.1):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
/* Swap the two IP addresses */
hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("2-tuple hash of (src = 192.168.1.1, dst = 10.10.10.10):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
rc = NT_HashRefClose(href);
if (rc) {
(void)fprintf(stderr, "Failed to close hash reference library\n");
return rc;
}
return 0;
}
static int do_2tuple_ipv6(void)
{
int rc;
const unsigned char src_ip[16] =
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5a, 0x94, 0x6b, 0xff, 0xfe, 0x6a, 0x09, 0x48 };
const unsigned char dst_ip[16] =
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x12, 0x34, 0x39, 0x10, 0x12, 0x90, 0x44, 0x01 };
struct NtTuple2IPv6_s *hinput = &input.u.tuple2IPv6;
rc = NT_HashRefOpen(&href, &config);
if (rc) {
(void)fprintf(stderr, "Failed to open hash reference library\n");
return rc;
}
/* Note that the hash mode must correspond to the input type
input.hashinput.tuple2IPv6, as specified by input.hashInputType. */
(void)memcpy(hinput->srcIP, src_ip, sizeof(src_ip));
(void)memcpy(hinput->dstIP, dst_ip, sizeof(dst_ip));
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("2-tuple hash of (src = fe80::5a94:6bff:fe6a:948,\n"
"dst = fe80::1234:3910:1290:4401)\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
/* Swap the two IP addresses */
(void)memcpy(hinput->srcIP, dst_ip, sizeof(dst_ip));
(void)memcpy(hinput->dstIP, src_ip, sizeof(src_ip));
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("2-tuple hash of (src = fe80::1234:3910:1290:4401,\n"
"dst = fe80::5a94:6bff:fe6a:948)\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
rc = NT_HashRefClose(href);
if (rc) {
(void)fprintf(stderr, "Failed to close hash reference library\n");
return rc;
}
return 0;
}
static int do_5tuple_ipv4(void)
{
int rc;
struct NtTuple5IPv4_s *hinput = &input.u.tuple5IPv4;
rc = NT_HashRefOpen(&href, &config);
if (rc) {
(void)fprintf(stderr, "Failed to open hash reference library\n");
return rc;
}
/* Note that the hash mode must correspond to the input type
input.hashinput.tuple5IPv4, as specified by input.hashInputType. */
hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
hinput->srcPort = htons(14532);
hinput->dstPort = htons(80);
hinput->protocol = 4;
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("5-tuple hash of (src = 10.10.10.10, dst = 192.168.1.1, "
"src_port = 14532, dst_port = 80, protocol = 4):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
/* Swap IP addresses (and ports) */
hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
hinput->dstPort = htons(14532);
hinput->srcPort = htons(80);
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("5-tuple hash of (src = 192.168.1.1, dst = 10.10.10.10, "
"src_port = 14532, dst_port = 80, protocol = 4):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
rc = NT_HashRefClose(href);
if (rc) {
(void)fprintf(stderr, "Failed to close hash reference library\n");
return rc;
}
return 0;
}
static int do_5tuple_ipv6(void)
{
int rc;
const unsigned char src_ip[16] =
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5a, 0x94, 0x6b, 0xff, 0xfe, 0x6a, 0x09, 0x48 };
const unsigned char dst_ip[16] =
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x12, 0x34, 0x39, 0x10, 0x12, 0x90, 0x44, 0x01 };
struct NtTuple5IPv6_s *hinput = &input.u.tuple5IPv6;
rc = NT_HashRefOpen(&href, &config);
if (rc) {
(void)fprintf(stderr, "Failed to open hash reference library\n");
return rc;
}
/* Note that the hash mode must correspond to the input type
input.hashinput.tuple5IPv6, as specified by input.hashInputType. */
assert(sizeof(hinput->srcIP) >= sizeof(src_ip));
assert(sizeof(hinput->dstIP) >= sizeof(dst_ip));
(void)memcpy(hinput->srcIP, src_ip, sizeof(src_ip));
(void)memcpy(hinput->dstIP, dst_ip, sizeof(dst_ip));
hinput->srcPort = htons(14532);
hinput->dstPort = htons(80);
hinput->protocol = 4;
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("5-tuple hash of (src = fe80::5a94:6bff:fe6a:948, "
"dst = fe80::1234:3910:1290:4401, dst_port = 80, protocol = 4):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
/* Swap IP addresses (and ports) */
(void)memcpy(hinput->srcIP, dst_ip, sizeof(dst_ip));
(void)memcpy(hinput->dstIP, src_ip, sizeof(src_ip));
hinput->dstPort = htons(14532);
hinput->srcPort = htons(80);
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("5-tuple hash of (src = fe80::1234:3910:1290:4401, "
"dst = fe80::5a94:6bff:fe6a:948, dst_port = 80, protocol = 4):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
rc = NT_HashRefClose(href);
if (rc) {
(void)fprintf(stderr, "Failed to close hash reference library\n");
return rc;
}
return 0;
}
static int do_ipfragmenttuple_ipv4(void)
{
int rc;
struct NtIpFragmentTupleIPv4_s *hinput = &input.u.ipFragmentTupleIPv4;
rc = NT_HashRefOpen(&href, &config);
if (rc) {
(void)fprintf(stderr, "Failed to open hash reference library\n");
return rc;
}
/* Note that the hash mode must correspond to the input type
input.hashinput.ipFragmentTupleIPv4,
as specified by input.hashInputType. */
hinput->srcIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
hinput->dstIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
hinput->ipId = htons(0x1234); /* 16 bits IP ID */
hinput->ipProt = (uint8_t)1; /* 1 = ICMP */
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("IP fragment hash of (src = 10.10.10.10, dst = 192.168.1.1):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
hinput->srcIP = htonl(0xc0a80101); /* IP V4: 192.168.1.1 */
hinput->dstIP = htonl(0x0a0a0a0a); /* IP V4: 10.10.10.10 */
rc = NT_HashRefCalc(href, &input, &result);
if (rc) {
(void)fprintf(stderr, "Cannot calculate hash value\n");
return rc;
}
(void)printf("IP fragment hash of (src = 192.168.1.1, dst = 10.10.10.10):\n"
"\tvalue = 0x%x, stream number = %d\n",
result.hashvalue, result.stream);
rc = NT_HashRefClose(href);
if (rc) {
(void)fprintf(stderr, "Failed to close hash reference library\n");
return rc;
}
return 0;
}
int main(void)
{
(void)do_2tuple_ipv4();
(void)do_2tuple_ipv6();
(void)do_5tuple_ipv4();
(void)do_5tuple_ipv6();
return 0;
}