/*
* Copyright (c) 2001-2020 Mellanox Technologies, Ltd. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VTYPES_H
#define VTYPES_H
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <linux/kernel.h>
#include <byteswap.h>
#include "utils/types.h"
#include "utils/bullseye.h"
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
static inline uint64_t htonll(uint64_t x) { return bswap_64(x); }
static inline uint64_t ntohll(uint64_t x) { return bswap_64(x); }
#elif __BYTE_ORDER == __BIG_ENDIAN
static inline uint64_t htonll(uint64_t x) { return x; }
static inline uint64_t ntohll(uint64_t x) { return x; }
#else
#error __BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
// Check if given IP address is in a specific ip class / range
#define ZERONET_N(a) (((long int)(a)) == (long int)(htonl(0x00000000)))
#define LOOPBACK_N(a) (((long int)(a) & htonl(0xff000000)) == htonl(0x7f000000))
#define IN_CLASSD_N(a) (((long int)(a) & htonl(0xf0000000)) == htonl(0xe0000000))
#define IN_CLASSE_N(a) (((long int)(a) & htonl(0xffffffff)) == htonl(0xffffffff))
#define IN_MULTICAST_N(a) IN_CLASSD_N(a)
#define IS_BROADCAST_N(a) IN_CLASSE_N(a)
// printf formating when IP is in network byte ordering (for LITTLE_ENDIAN)
#define NETWORK_IP_PRINTQUAD_LITTLE_ENDIAN(ip) (uint8_t)((ip)&0xff), (uint8_t)(((ip)>>8)&0xff),(uint8_t)(((ip)>>16)&0xff),(uint8_t)(((ip)>>24)&0xff)
// printf formating when IP is in host byte ordering (for LITTLE_ENDIAN)
#define HOST_IP_PRINTQUAD_LITTLE_ENDIAN(ip) (uint8_t)(((ip)>>24)&0xff),(uint8_t)(((ip)>>16)&0xff),(uint8_t)(((ip)>>8)&0xff),(uint8_t)((ip)&0xff)
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* The host byte order is the same as network byte order, so these functions are all just identity. */
# define NIPQUAD(ip) NETWORK_IP_PRINTQUAD_LITTLE_ENDIAN(ip)
# define HIPQUAD(ip) HOST_IP_PRINTQUAD_LITTLE_ENDIAN(ip)
#else
# if __BYTE_ORDER == __BIG_ENDIAN
# define NIPQUAD(ip) HOST_IP_PRINTQUAD_LITTLE_ENDIAN(ip)
# define HIPQUAD(ip) NETWORK_IP_PRINTQUAD_LITTLE_ENDIAN(ip)
# endif
#endif
#define ETH_HW_ADDR_PRINT_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define ETH_HW_ADDR_PRINT_ADDR(__addr) \
((unsigned char *)(__addr))[0], ((unsigned char *)(__addr))[1], \
((unsigned char *)(__addr))[2], ((unsigned char *)(__addr))[3], \
((unsigned char *)(__addr))[4], ((unsigned char *)(__addr))[5]
#define IPOIB_HW_ADDR_PRINT_FMT_16 "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X"
#define IPOIB_HW_ADDR_PRINT_ADDR_16(__addr) \
((unsigned char *)(__addr))[0],((unsigned char *)(__addr))[1], \
((unsigned char *)(__addr))[2],((unsigned char *)(__addr))[3], \
((unsigned char *)(__addr))[4],((unsigned char *)(__addr))[5], \
((unsigned char *)(__addr))[6],((unsigned char *)(__addr))[7], \
((unsigned char *)(__addr))[8],((unsigned char *)(__addr))[9], \
((unsigned char *)(__addr))[10],((unsigned char *)(__addr))[11], \
((unsigned char *)(__addr))[12],((unsigned char *)(__addr))[13], \
((unsigned char *)(__addr))[14],((unsigned char *)(__addr))[15]
#define IPOIB_HW_ADDR_PRINT_FMT "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X"
#define IPOIB_HW_ADDR_PRINT_ADDR(__addr) \
((unsigned char *)(__addr))[0],((unsigned char *)(__addr))[1], \
((unsigned char *)(__addr))[2],((unsigned char *)(__addr))[3], \
((unsigned char *)(__addr))[4],((unsigned char *)(__addr))[5], \
((unsigned char *)(__addr))[6],((unsigned char *)(__addr))[7], \
((unsigned char *)(__addr))[8],((unsigned char *)(__addr))[9], \
((unsigned char *)(__addr))[10],((unsigned char *)(__addr))[11], \
((unsigned char *)(__addr))[12],((unsigned char *)(__addr))[13], \
((unsigned char *)(__addr))[14],((unsigned char *)(__addr))[15], \
((unsigned char *)(__addr))[16],((unsigned char *)(__addr))[17], \
((unsigned char *)(__addr))[18],((unsigned char *)(__addr))[19]
#define ETH_HW_ADDR_SSCAN_FMT "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX"
#define ETH_HW_ADDR_SSCAN(__addr) \
&(__addr[0]),&(__addr[1]), \
&(__addr[2]),&(__addr[3]), \
&(__addr[4]),&(__addr[5])
#define IPOIB_HW_ADDR_SSCAN_FMT "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX"
#define IPOIB_HW_ADDR_SSCAN(__addr) \
&(__addr[0]),&(__addr[1]), \
&(__addr[2]),&(__addr[3]), \
&(__addr[4]),&(__addr[5]), \
&(__addr[6]),&(__addr[7]), \
&(__addr[8]),&(__addr[9]), \
&(__addr[10]),&(__addr[11]), \
&(__addr[12]),&(__addr[13]), \
&(__addr[14]),&(__addr[15]), \
&(__addr[16]),&(__addr[17]), \
&(__addr[18]),&(__addr[19])
#define ETH_HDR_LEN (ETH_HLEN)
#define ETH_VLAN_HDR_LEN (ETH_HDR_LEN + sizeof(struct vlanhdr))
#define GRH_HDR_LEN (sizeof(struct ibv_grh))
#define IPOIB_HDR_LEN (sizeof(struct ipoibhdr))
#define IPOIB_HEADER ((uint32_t)0x08000000)
#define IPOIB_ARP_HEADER ((uint32_t)0x08060000)
#define IPOIB_HW_ADDR_LEN 20
#define IPOIB_HW_ADDR_GID_LEN 16
#define MAX_L2_ADDR_LEN (MAX(IPOIB_HW_ADDR_LEN, ETH_ALEN))
#define IPV4_VERSION 0x4
#define IPV4_HDR_LEN_WITHOUT_OPTIONS (sizeof(struct iphdr)) // Ip Header without any options
#define IPV4_IGMP_HDR_LEN (IPV4_HDR_LEN_WITHOUT_OPTIONS + sizeof(uint32_t))
#define IPV4_IGMP_HDR_LEN_WORDS (IPV4_IGMP_HDR_LEN / sizeof(uint32_t))
#define IGMP_HDR_LEN (sizeof(struct igmphdr))
#define IGMP_HDR_LEN_WORDS (IGMP_HDR_LEN / sizeof(uint32_t))
#define DONT_FRAGMENT_FLAG 0x4000
#define MORE_FRAGMENTS_FLAG 0x2000
#define FRAGMENT_OFFSET 0x1FFF
#define MAX_APP_ID_LENGHT 64
#define INPORT_ANY ((uint16_t)0x0000)
#define MCE_IMM_DATA_MASK_MC_TX_LOOP_DISABLED (1 << 0)
#define BROADCAST_IP "255.255.255.255"
#ifndef ARPHRD_INFINIBAND
#define ARPHRD_INFINIBAND 32 /* InfiniBand */
#endif
#ifndef ARPHRD_ETHER
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
#endif
#ifndef ARPHRD_LOOPBACK
#define ARPHRD_LOOPBACK 772 /* Loopback device */
#endif
#ifndef ETH_P_8021Q
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#endif
struct __attribute__ ((packed)) ipoibhdr {
uint32_t ipoib_header;
};
struct __attribute__((packed)) vlanhdr {
uint16_t h_vlan_TCI; /* Encapsulates priority and VLAN ID */
uint16_t h_vlan_encapsulated_proto; /* packet type ID field (or len) */
};
#include <sys/epoll.h>
//support for RH 5.7 and older OS
#ifndef EPOLLHUP
#define EPOLLHUP 0x010
#endif
#ifndef EPOLLRDHUP
#define EPOLLRDHUP 0x2000
#endif
#endif //VTYPES_H