#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include <pcap/pcap-inttypes.h>
#include <pcap/compiler-tests.h>
#include "portability.h"
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
#define UNALIGNED_OK __attribute__((no_sanitize_undefined))
#elif __has_attribute(no_sanitize)
#define UNALIGNED_OK __attribute__((no_sanitize("undefined")))
#else
#define UNALIGNED_OK
#endif
#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
(defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
(defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
(defined(__s390__) || defined(__s390x__) || defined(__zarch__))
UNALIGNED_OK static inline uint16_t
EXTRACT_BE_U_2(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
UNALIGNED_OK static inline int16_t
EXTRACT_BE_S_2(const void *p)
{
return ((int16_t)ntohs(*(const int16_t *)(p)));
}
UNALIGNED_OK static inline uint32_t
EXTRACT_BE_U_4(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
UNALIGNED_OK static inline int32_t
EXTRACT_BE_S_4(const void *p)
{
return ((int32_t)ntohl(*(const int32_t *)(p)));
}
UNALIGNED_OK static inline uint64_t
EXTRACT_BE_U_8(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
}
UNALIGNED_OK static inline int64_t
EXTRACT_BE_S_8(const void *p)
{
return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
}
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \
(defined(__alpha) || defined(__alpha__) || \
defined(__mips) || defined(__mips__))
typedef struct {
uint16_t val;
} __attribute__((packed)) unaligned_uint16_t;
typedef struct {
int16_t val;
} __attribute__((packed)) unaligned_int16_t;
typedef struct {
uint32_t val;
} __attribute__((packed)) unaligned_uint32_t;
typedef struct {
int32_t val;
} __attribute__((packed)) unaligned_int32_t;
UNALIGNED_OK static inline uint16_t
EXTRACT_BE_U_2(const void *p)
{
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
}
UNALIGNED_OK static inline int16_t
EXTRACT_BE_S_2(const void *p)
{
return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val));
}
UNALIGNED_OK static inline uint32_t
EXTRACT_BE_U_4(const void *p)
{
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
}
UNALIGNED_OK static inline int32_t
EXTRACT_BE_S_4(const void *p)
{
return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val));
}
UNALIGNED_OK static inline uint64_t
EXTRACT_BE_U_8(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
}
UNALIGNED_OK static inline int64_t
EXTRACT_BE_S_8(const void *p)
{
return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
}
#else
#define EXTRACT_BE_U_2(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
#define EXTRACT_BE_S_2(p) \
((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
#define EXTRACT_BE_U_4(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#define EXTRACT_BE_S_4(p) \
((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#define EXTRACT_BE_U_8(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
#define EXTRACT_BE_S_8(p) \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
#define EXTRACT_IPV4_TO_HOST_ORDER(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#endif
#define EXTRACT_BE_U_3(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))
#define EXTRACT_BE_S_3(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) : \
((int32_t)(0xFF000000U | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))))
#define EXTRACT_BE_U_5(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))
#define EXTRACT_BE_S_5(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))))
#define EXTRACT_BE_U_6(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))
#define EXTRACT_BE_S_6(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))))
#define EXTRACT_BE_U_7(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))
#define EXTRACT_BE_S_7(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))))
#define EXTRACT_LE_U_2(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_S_2(p) \
((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_U_4(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_S_4(p) \
((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_U_3(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_S_3(p) \
((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_U_8(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_S_8(p) \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))