10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 1992, 1993, 1994, 1995, 1996 30f74e101Schristos * The Regents of the University of California. All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Redistribution and use in source and binary forms, with or without 60f74e101Schristos * modification, are permitted provided that: (1) source code distributions 70f74e101Schristos * retain the above copyright notice and this paragraph in its entirety, (2) 80f74e101Schristos * distributions including binary code include the above copyright notice and 90f74e101Schristos * this paragraph in its entirety in the documentation or other materials 100f74e101Schristos * provided with the distribution, and (3) all advertising materials mentioning 110f74e101Schristos * features or use of this software display the following acknowledgement: 120f74e101Schristos * ``This product includes software developed by the University of California, 130f74e101Schristos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 140f74e101Schristos * the University nor the names of its contributors may be used to endorse 150f74e101Schristos * or promote products derived from this software without specific prior 160f74e101Schristos * written permission. 170f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 180f74e101Schristos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 190f74e101Schristos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 200f74e101Schristos */ 210f74e101Schristos 22c74ad251Schristos #ifndef EXTRACT_H 23c74ad251Schristos #define EXTRACT_H 24c74ad251Schristos 25c74ad251Schristos #include <string.h> 26c74ad251Schristos 27c74ad251Schristos /* 28c74ad251Schristos * For 8-bit values; needed to fetch a one-byte value. Byte order 29c74ad251Schristos * isn't relevant, and alignment isn't an issue. 30c74ad251Schristos */ 31c74ad251Schristos #define EXTRACT_U_1(p) ((uint8_t)(*(p))) 32c74ad251Schristos #define EXTRACT_S_1(p) ((int8_t)(*(p))) 33c74ad251Schristos 34c74ad251Schristos /* 35c74ad251Schristos * Inline functions or macros to extract possibly-unaligned big-endian 36c74ad251Schristos * integral values. 37c74ad251Schristos */ 38c74ad251Schristos #include "funcattrs.h" 39c74ad251Schristos #include "netdissect.h" 40c74ad251Schristos #include "diag-control.h" 41d8be3806Skamil 42d8be3806Skamil /* 43d8be3806Skamil * If we have versions of GCC or Clang that support an __attribute__ 44d8be3806Skamil * to say "if we're building with unsigned behavior sanitization, 45d8be3806Skamil * don't complain about undefined behavior in this function", we 46d8be3806Skamil * label these functions with that attribute - we *know* it's undefined 47d8be3806Skamil * in the C standard, but we *also* know it does what we want with 48d8be3806Skamil * the ISA we're targeting and the compiler we're using. 49d8be3806Skamil * 50d8be3806Skamil * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined)); 51d8be3806Skamil * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether 52d8be3806Skamil * GCC or Clang first had __attribute__((no_sanitize(XXX)). 53d8be3806Skamil * 54d8be3806Skamil * For Clang, we check for __attribute__((no_sanitize(XXX)) with 55d8be3806Skamil * __has_attribute, as there are versions of Clang that support 56d8be3806Skamil * __attribute__((no_sanitize("undefined")) but don't support 57d8be3806Skamil * __attribute__((no_sanitize_undefined)). 58d8be3806Skamil * 59d8be3806Skamil * We define this here, rather than in funcattrs.h, because we 60d8be3806Skamil * only want it used here, we don't want it to be broadly used. 61d8be3806Skamil * (Any printer will get this defined, but this should at least 62d8be3806Skamil * make it harder for people to find.) 63d8be3806Skamil */ 64d8be3806Skamil #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409) 65d8be3806Skamil #define UNALIGNED_OK __attribute__((no_sanitize_undefined)) 66d8be3806Skamil #elif __has_attribute(no_sanitize) 67d8be3806Skamil #define UNALIGNED_OK __attribute__((no_sanitize("undefined"))) 68d8be3806Skamil #else 69d8be3806Skamil #define UNALIGNED_OK 70d8be3806Skamil #endif 71d8be3806Skamil 72c74ad251Schristos #if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ 73c74ad251Schristos (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ 74c74ad251Schristos (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ 75c74ad251Schristos (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) 76c74ad251Schristos /* 77c74ad251Schristos * The processor natively handles unaligned loads, so we can just 78c74ad251Schristos * cast the pointer and fetch through it. 79c74ad251Schristos * 80c74ad251Schristos * XXX - are those all the x86 tests we need? 81c74ad251Schristos * XXX - are those the only 68k tests we need not to generated 82c74ad251Schristos * unaligned accesses if the target is the 68000 or 68010? 83c74ad251Schristos * XXX - are there any tests we don't need, because some definitions are for 84c74ad251Schristos * compilers that also predefine the GCC symbols? 85c74ad251Schristos * XXX - do we need to test for both 32-bit and 64-bit versions of those 86c74ad251Schristos * architectures in all cases? 87c74ad251Schristos */ 88c74ad251Schristos UNALIGNED_OK static inline uint16_t 89c74ad251Schristos EXTRACT_BE_U_2(const void *p) 90c74ad251Schristos { 91c74ad251Schristos return ((uint16_t)ntohs(*(const uint16_t *)(p))); 92c74ad251Schristos } 93c74ad251Schristos 94c74ad251Schristos UNALIGNED_OK static inline int16_t 95c74ad251Schristos EXTRACT_BE_S_2(const void *p) 96c74ad251Schristos { 97c74ad251Schristos return ((int16_t)ntohs(*(const int16_t *)(p))); 98c74ad251Schristos } 99c74ad251Schristos 100c74ad251Schristos UNALIGNED_OK static inline uint32_t 101c74ad251Schristos EXTRACT_BE_U_4(const void *p) 102c74ad251Schristos { 103c74ad251Schristos return ((uint32_t)ntohl(*(const uint32_t *)(p))); 104c74ad251Schristos } 105c74ad251Schristos 106c74ad251Schristos UNALIGNED_OK static inline int32_t 107c74ad251Schristos EXTRACT_BE_S_4(const void *p) 108c74ad251Schristos { 109c74ad251Schristos return ((int32_t)ntohl(*(const int32_t *)(p))); 110c74ad251Schristos } 111c74ad251Schristos 112c74ad251Schristos UNALIGNED_OK static inline uint64_t 113c74ad251Schristos EXTRACT_BE_U_8(const void *p) 114c74ad251Schristos { 115c74ad251Schristos return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | 116c74ad251Schristos ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); 117c74ad251Schristos 118c74ad251Schristos } 119c74ad251Schristos 120c74ad251Schristos UNALIGNED_OK static inline int64_t 121c74ad251Schristos EXTRACT_BE_S_8(const void *p) 122c74ad251Schristos { 123c74ad251Schristos return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | 124c74ad251Schristos ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); 125c74ad251Schristos 126c74ad251Schristos } 1279ad46775Schristos 1289ad46775Schristos /* 129c74ad251Schristos * Extract an IPv4 address, which is in network byte order, and not 130c74ad251Schristos * necessarily aligned, and provide the result in host byte order. 1319ad46775Schristos */ 132c74ad251Schristos UNALIGNED_OK static inline uint32_t 133c74ad251Schristos EXTRACT_IPV4_TO_HOST_ORDER(const void *p) 1349ad46775Schristos { 135c74ad251Schristos return ((uint32_t)ntohl(*(const uint32_t *)(p))); 1369ad46775Schristos } 137c74ad251Schristos #elif ND_IS_AT_LEAST_GNUC_VERSION(2,0) && \ 138b3a00663Schristos (defined(__alpha) || defined(__alpha__) || \ 139b3a00663Schristos defined(__mips) || defined(__mips__)) 1400f74e101Schristos /* 141c74ad251Schristos * This is MIPS or Alpha, which don't natively handle unaligned loads, 142c74ad251Schristos * but which have instructions that can help when doing unaligned 143c74ad251Schristos * loads, and this is GCC 2.0 or later or a compiler that claims to 144c74ad251Schristos * be GCC 2.0 or later, which we assume that mean we have 145c74ad251Schristos * __attribute__((packed)), which we can use to convince the compiler 146c74ad251Schristos * to generate those instructions. 147b3a00663Schristos * 148b3a00663Schristos * Declare packed structures containing a uint16_t and a uint32_t, 1490f74e101Schristos * cast the pointer to point to one of those, and fetch through it; 1500f74e101Schristos * the GCC manual doesn't appear to explicitly say that 1510f74e101Schristos * __attribute__((packed)) causes the compiler to generate unaligned-safe 152c74ad251Schristos * code, but it appears to do so. 1530f74e101Schristos * 154b3a00663Schristos * We do this in case the compiler can generate code using those 155b3a00663Schristos * instructions to do an unaligned load and pass stuff to "ntohs()" or 156c74ad251Schristos * "ntohl()", which might be better than the code to fetch the 157b3a00663Schristos * bytes one at a time and assemble them. (That might not be the 158b3a00663Schristos * case on a little-endian platform, such as DEC's MIPS machines and 159b3a00663Schristos * Alpha machines, where "ntohs()" and "ntohl()" might not be done 160b3a00663Schristos * inline.) 161b3a00663Schristos * 162b3a00663Schristos * We do this only for specific architectures because, for example, 163b3a00663Schristos * at least some versions of GCC, when compiling for 64-bit SPARC, 164b3a00663Schristos * generate code that assumes alignment if we do this. 165b3a00663Schristos * 166b3a00663Schristos * XXX - add other architectures and compilers as possible and 167b3a00663Schristos * appropriate. 168b3a00663Schristos * 169b3a00663Schristos * HP's C compiler, indicated by __HP_cc being defined, supports 170b3a00663Schristos * "#pragma unaligned N" in version A.05.50 and later, where "N" 171b3a00663Schristos * specifies a number of bytes at which the typedef on the next 172b3a00663Schristos * line is aligned, e.g. 173b3a00663Schristos * 174b3a00663Schristos * #pragma unalign 1 175b3a00663Schristos * typedef uint16_t unaligned_uint16_t; 176b3a00663Schristos * 177b3a00663Schristos * to define unaligned_uint16_t as a 16-bit unaligned data type. 178b3a00663Schristos * This could be presumably used, in sufficiently recent versions of 179b3a00663Schristos * the compiler, with macros similar to those below. This would be 180b3a00663Schristos * useful only if that compiler could generate better code for PA-RISC 181b3a00663Schristos * or Itanium than would be generated by a bunch of shifts-and-ORs. 182b3a00663Schristos * 183b3a00663Schristos * DEC C, indicated by __DECC being defined, has, at least on Alpha, 184b3a00663Schristos * an __unaligned qualifier that can be applied to pointers to get the 185b3a00663Schristos * compiler to generate code that does unaligned loads and stores when 186b3a00663Schristos * dereferencing the pointer in question. 187b3a00663Schristos * 188b3a00663Schristos * XXX - what if the native C compiler doesn't support 189b3a00663Schristos * __attribute__((packed))? How can we get it to generate unaligned 190b3a00663Schristos * accesses for *specific* items? 1910f74e101Schristos */ 1920f74e101Schristos typedef struct { 193b3a00663Schristos uint16_t val; 194b3a00663Schristos } __attribute__((packed)) unaligned_uint16_t; 1950f74e101Schristos 1960f74e101Schristos typedef struct { 197c74ad251Schristos int16_t val; 198c74ad251Schristos } __attribute__((packed)) unaligned_int16_t; 199c74ad251Schristos 200c74ad251Schristos typedef struct { 201b3a00663Schristos uint32_t val; 202b3a00663Schristos } __attribute__((packed)) unaligned_uint32_t; 2030f74e101Schristos 204c74ad251Schristos typedef struct { 205c74ad251Schristos int32_t val; 206c74ad251Schristos } __attribute__((packed)) unaligned_int32_t; 207c74ad251Schristos 20872c96ff3Schristos UNALIGNED_OK static inline uint16_t 209c74ad251Schristos EXTRACT_BE_U_2(const void *p) 210870189d2Schristos { 211b3a00663Schristos return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); 212870189d2Schristos } 213870189d2Schristos 214c74ad251Schristos UNALIGNED_OK static inline int16_t 215c74ad251Schristos EXTRACT_BE_S_2(const void *p) 216c74ad251Schristos { 217c74ad251Schristos return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val)); 218c74ad251Schristos } 219c74ad251Schristos 22072c96ff3Schristos UNALIGNED_OK static inline uint32_t 221c74ad251Schristos EXTRACT_BE_U_4(const void *p) 222870189d2Schristos { 223b3a00663Schristos return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); 224870189d2Schristos } 225870189d2Schristos 226c74ad251Schristos UNALIGNED_OK static inline int32_t 227c74ad251Schristos EXTRACT_BE_S_4(const void *p) 228c74ad251Schristos { 229c74ad251Schristos return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val)); 230c74ad251Schristos } 231c74ad251Schristos 23272c96ff3Schristos UNALIGNED_OK static inline uint64_t 233c74ad251Schristos EXTRACT_BE_U_8(const void *p) 234870189d2Schristos { 235dc860a36Sspz return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | 236b3a00663Schristos ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); 237870189d2Schristos } 2380f74e101Schristos 239c74ad251Schristos UNALIGNED_OK static inline int64_t 240c74ad251Schristos EXTRACT_BE_S_8(const void *p) 241c74ad251Schristos { 242c74ad251Schristos return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | 243c74ad251Schristos ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); 244c74ad251Schristos } 245c74ad251Schristos 2460f74e101Schristos /* 247c74ad251Schristos * Extract an IPv4 address, which is in network byte order, and not 248c74ad251Schristos * necessarily aligned, and provide the result in host byte order. 249c74ad251Schristos */ 250c74ad251Schristos UNALIGNED_OK static inline uint32_t 251c74ad251Schristos EXTRACT_IPV4_TO_HOST_ORDER(const void *p) 252c74ad251Schristos { 253c74ad251Schristos return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); 254c74ad251Schristos } 255c74ad251Schristos #else 256c74ad251Schristos /* 257c74ad251Schristos * This architecture doesn't natively support unaligned loads, and either 258c74ad251Schristos * this isn't a GCC-compatible compiler, we don't have __attribute__, 259b3a00663Schristos * or we do but we don't know of any better way with this instruction 260b3a00663Schristos * set to do unaligned loads, so do unaligned loads of big-endian 2610f74e101Schristos * quantities the hard way - fetch the bytes one at a time and 2620f74e101Schristos * assemble them. 263c74ad251Schristos * 264*26ba0b50Schristos * XXX - ARM is a special case. ARMv1 through ARMv5 didn't support 265c74ad251Schristos * unaligned loads; ARMv6 and later support it *but* have a bit in 266c74ad251Schristos * the system control register that the OS can set and that causes 267c74ad251Schristos * unaligned loads to fault rather than succeeding. 268c74ad251Schristos * 269c74ad251Schristos * At least some OSes may set that flag, so we do *not* treat ARM 270c74ad251Schristos * as supporting unaligned loads. If your OS supports them on ARM, 271c74ad251Schristos * and you want to use them, please update the tests in the #if above 272c74ad251Schristos * to check for ARM *and* for your OS. 2730f74e101Schristos */ 274c74ad251Schristos #define EXTRACT_BE_U_2(p) \ 275ba2ff121Schristos ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ 276ba2ff121Schristos ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) 277c74ad251Schristos #define EXTRACT_BE_S_2(p) \ 278c74ad251Schristos ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ 279c74ad251Schristos ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) 280c74ad251Schristos #define EXTRACT_BE_U_4(p) \ 281ba2ff121Schristos ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 282ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 283ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 284ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 285c74ad251Schristos #define EXTRACT_BE_S_4(p) \ 286c74ad251Schristos ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 287c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 288c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 289c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 290c74ad251Schristos #define EXTRACT_BE_U_8(p) \ 291ba2ff121Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ 292ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ 293ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ 294ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ 295ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ 296ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ 297ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ 298ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) 299c74ad251Schristos #define EXTRACT_BE_S_8(p) \ 300c74ad251Schristos ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ 301c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ 302c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ 303c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ 304c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ 305c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ 306c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ 307c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) 308c74ad251Schristos 3090f74e101Schristos /* 310c74ad251Schristos * Extract an IPv4 address, which is in network byte order, and not 311c74ad251Schristos * necessarily aligned, and provide the result in host byte order. 3120f74e101Schristos */ 313c74ad251Schristos #define EXTRACT_IPV4_TO_HOST_ORDER(p) \ 314c74ad251Schristos ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ 315c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ 316c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ 317c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) 318c74ad251Schristos #endif /* unaligned access checks */ 319c74ad251Schristos 320c74ad251Schristos /* 321c74ad251Schristos * Extract numerical values in *host* byte order. (Some metadata 322c74ad251Schristos * headers are in the byte order of the host that wrote the file, 323c74ad251Schristos * and libpcap translate them to the byte order of the host 324c74ad251Schristos * reading the file. This means that if a program on that host 325c74ad251Schristos * reads with libpcap and writes to a new file, the new file will 326c74ad251Schristos * be written in the byte order of the host writing the file. Thus, 327c74ad251Schristos * the magic number in pcap files and byte-order magic in pcapng 328c74ad251Schristos * files can be used to determine the byte order in those metadata 329c74ad251Schristos * headers.) 330c74ad251Schristos * 331c74ad251Schristos * XXX - on platforms that can do unaligned accesses, just cast and 332c74ad251Schristos * dereference the pointer. 333c74ad251Schristos */ 334c74ad251Schristos static inline uint16_t 335c74ad251Schristos EXTRACT_HE_U_2(const void *p) 336870189d2Schristos { 337c74ad251Schristos uint16_t val; 338c74ad251Schristos 339c74ad251Schristos UNALIGNED_MEMCPY(&val, p, sizeof(uint16_t)); 340c74ad251Schristos return val; 341870189d2Schristos } 342870189d2Schristos 343c74ad251Schristos static inline int16_t 344c74ad251Schristos EXTRACT_HE_S_2(const void *p) 345870189d2Schristos { 346c74ad251Schristos int16_t val; 347c74ad251Schristos 348c74ad251Schristos UNALIGNED_MEMCPY(&val, p, sizeof(int16_t)); 349c74ad251Schristos return val; 350870189d2Schristos } 351870189d2Schristos 352c74ad251Schristos static inline uint32_t 353c74ad251Schristos EXTRACT_HE_U_4(const void *p) 354870189d2Schristos { 355c74ad251Schristos uint32_t val; 356870189d2Schristos 357c74ad251Schristos UNALIGNED_MEMCPY(&val, p, sizeof(uint32_t)); 358c74ad251Schristos return val; 359870189d2Schristos } 360870189d2Schristos 361c74ad251Schristos static inline int32_t 362c74ad251Schristos EXTRACT_HE_S_4(const void *p) 363c74ad251Schristos { 364c74ad251Schristos int32_t val; 3650f74e101Schristos 366c74ad251Schristos UNALIGNED_MEMCPY(&val, p, sizeof(int32_t)); 367c74ad251Schristos return val; 368c74ad251Schristos } 369c74ad251Schristos 370c74ad251Schristos /* 371c74ad251Schristos * Extract an IPv4 address, which is in network byte order, and which 372c74ad251Schristos * is not necessarily aligned on a 4-byte boundary, and provide the 373c74ad251Schristos * result in network byte order. 374c74ad251Schristos * 375c74ad251Schristos * This works the same way regardless of the host's byte order. 376c74ad251Schristos */ 377c74ad251Schristos static inline uint32_t 378c74ad251Schristos EXTRACT_IPV4_TO_NETWORK_ORDER(const void *p) 379c74ad251Schristos { 380c74ad251Schristos uint32_t addr; 381c74ad251Schristos 382c74ad251Schristos UNALIGNED_MEMCPY(&addr, p, sizeof(uint32_t)); 383c74ad251Schristos return addr; 384c74ad251Schristos } 385c74ad251Schristos 386c74ad251Schristos /* 387c74ad251Schristos * Non-power-of-2 sizes. 388c74ad251Schristos */ 389c74ad251Schristos #define EXTRACT_BE_U_3(p) \ 390ba2ff121Schristos ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 391ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 392ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) 393b3a00663Schristos 394c74ad251Schristos #define EXTRACT_BE_S_3(p) \ 395c74ad251Schristos (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 396c74ad251Schristos ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 397c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 398c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) : \ 399c74ad251Schristos ((int32_t)(0xFF000000U | \ 400c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ 401c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 402c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))) 403c74ad251Schristos 404c74ad251Schristos #define EXTRACT_BE_U_5(p) \ 405ba2ff121Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 406ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 407ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 408ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 409ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) 410b3a00663Schristos 411c74ad251Schristos #define EXTRACT_BE_S_5(p) \ 412c74ad251Schristos (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 413c74ad251Schristos ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 414c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 415c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 416c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 417c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) : \ 418c74ad251Schristos ((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \ 419c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ 420c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ 421c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 422c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ 423c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))) 424c74ad251Schristos 425c74ad251Schristos #define EXTRACT_BE_U_6(p) \ 426ba2ff121Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 427ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 428ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 429ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 430ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 431ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) 432b3a00663Schristos 433c74ad251Schristos #define EXTRACT_BE_S_6(p) \ 434c74ad251Schristos (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 435c74ad251Schristos ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 436c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 437c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 438c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 439c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 440c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) : \ 441c74ad251Schristos ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \ 442c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ 443c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ 444c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ 445c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ 446c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ 447c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))) 448c74ad251Schristos 449c74ad251Schristos #define EXTRACT_BE_U_7(p) \ 450ba2ff121Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 451ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 452ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 453ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 454ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 455ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 456ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) 4570f74e101Schristos 458c74ad251Schristos #define EXTRACT_BE_S_7(p) \ 459c74ad251Schristos (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ 460c74ad251Schristos ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 461c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 462c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 463c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 464c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 465c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 466c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) : \ 467c74ad251Schristos ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \ 468c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ 469c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ 470c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ 471c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 472c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ 473c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ 474c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))) 475c74ad251Schristos 4760f74e101Schristos /* 4770f74e101Schristos * Macros to extract possibly-unaligned little-endian integral values. 4780f74e101Schristos * XXX - do loads on little-endian machines that support unaligned loads? 4790f74e101Schristos */ 480c74ad251Schristos #define EXTRACT_LE_U_2(p) \ 481ba2ff121Schristos ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 482ba2ff121Schristos ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) 483c74ad251Schristos #define EXTRACT_LE_S_2(p) \ 484c74ad251Schristos ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 485c74ad251Schristos ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) 486c74ad251Schristos #define EXTRACT_LE_U_4(p) \ 487ba2ff121Schristos ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 488ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 489ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 490ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 491c74ad251Schristos #define EXTRACT_LE_S_4(p) \ 492c74ad251Schristos ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 493c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 494ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 495ba2ff121Schristos ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 496c74ad251Schristos #define EXTRACT_LE_U_8(p) \ 497ba2ff121Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ 498ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ 499ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 500ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 501ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 502ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 503ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 504ba2ff121Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 505c74ad251Schristos #define EXTRACT_LE_S_8(p) \ 506c74ad251Schristos ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ 507c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ 508c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 509c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 510c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 511c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 512c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 513c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 514dc860a36Sspz 515c74ad251Schristos /* 516c74ad251Schristos * Non-power-of-2 sizes. 517c74ad251Schristos */ 518c74ad251Schristos 519c74ad251Schristos #define EXTRACT_LE_U_3(p) \ 520c74ad251Schristos ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 521c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 522c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 523c74ad251Schristos #define EXTRACT_LE_S_3(p) \ 524c74ad251Schristos ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 525c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 526c74ad251Schristos ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) 527c74ad251Schristos #define EXTRACT_LE_U_5(p) \ 528c74ad251Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 529c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 530c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 531c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 532c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 533c74ad251Schristos #define EXTRACT_LE_U_6(p) \ 534c74ad251Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 535c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 536c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 537c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 538c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 539c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 540c74ad251Schristos #define EXTRACT_LE_U_7(p) \ 541c74ad251Schristos ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ 542c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ 543c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ 544c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ 545c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ 546c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ 547c74ad251Schristos ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) 548dc860a36Sspz 549dc860a36Sspz /* 550dc860a36Sspz * Macros to check the presence of the values in question. 551dc860a36Sspz */ 552c74ad251Schristos #define ND_TTEST_1(p) ND_TTEST_LEN((p), 1) 553c74ad251Schristos #define ND_TCHECK_1(p) ND_TCHECK_LEN((p), 1) 554dc860a36Sspz 555c74ad251Schristos #define ND_TTEST_2(p) ND_TTEST_LEN((p), 2) 556c74ad251Schristos #define ND_TCHECK_2(p) ND_TCHECK_LEN((p), 2) 557dc860a36Sspz 558c74ad251Schristos #define ND_TTEST_3(p) ND_TTEST_LEN((p), 3) 559c74ad251Schristos #define ND_TCHECK_3(p) ND_TCHECK_LEN((p), 3) 560dc860a36Sspz 561c74ad251Schristos #define ND_TTEST_4(p) ND_TTEST_LEN((p), 4) 562c74ad251Schristos #define ND_TCHECK_4(p) ND_TCHECK_LEN((p), 4) 563dc860a36Sspz 564c74ad251Schristos #define ND_TTEST_5(p) ND_TTEST_LEN((p), 5) 565c74ad251Schristos #define ND_TCHECK_5(p) ND_TCHECK_LEN((p), 5) 566dc860a36Sspz 567c74ad251Schristos #define ND_TTEST_6(p) ND_TTEST_LEN((p), 6) 568c74ad251Schristos #define ND_TCHECK_6(p) ND_TCHECK_LEN((p), 6) 569dc860a36Sspz 570c74ad251Schristos #define ND_TTEST_7(p) ND_TTEST_LEN((p), 7) 571c74ad251Schristos #define ND_TCHECK_7(p) ND_TCHECK_LEN((p), 7) 572dc860a36Sspz 573c74ad251Schristos #define ND_TTEST_8(p) ND_TTEST_LEN((p), 8) 574c74ad251Schristos #define ND_TCHECK_8(p) ND_TCHECK_LEN((p), 8) 57572c96ff3Schristos 576c74ad251Schristos #define ND_TTEST_16(p) ND_TTEST_LEN((p), 16) 577c74ad251Schristos #define ND_TCHECK_16(p) ND_TCHECK_LEN((p), 16) 578c74ad251Schristos 579c74ad251Schristos /* get_u_1 and get_s_1 */ 580c74ad251Schristos 581c74ad251Schristos static inline uint8_t 582c74ad251Schristos get_u_1(netdissect_options *ndo, const u_char *p) 583c74ad251Schristos { 584c74ad251Schristos if (!ND_TTEST_1(p)) 585c74ad251Schristos nd_trunc_longjmp(ndo); 586c74ad251Schristos return EXTRACT_U_1(p); 587c74ad251Schristos } 588c74ad251Schristos 589c74ad251Schristos static inline int8_t 590c74ad251Schristos get_s_1(netdissect_options *ndo, const u_char *p) 591c74ad251Schristos { 592c74ad251Schristos if (!ND_TTEST_1(p)) 593c74ad251Schristos nd_trunc_longjmp(ndo); 594c74ad251Schristos return EXTRACT_S_1(p); 595c74ad251Schristos } 596c74ad251Schristos 597c74ad251Schristos /* get_be_u_N */ 598c74ad251Schristos 599c74ad251Schristos static inline uint16_t 600c74ad251Schristos get_be_u_2(netdissect_options *ndo, const u_char *p) 601c74ad251Schristos { 602c74ad251Schristos if (!ND_TTEST_2(p)) 603c74ad251Schristos nd_trunc_longjmp(ndo); 604c74ad251Schristos return EXTRACT_BE_U_2(p); 605c74ad251Schristos } 606c74ad251Schristos 607c74ad251Schristos static inline uint32_t 608c74ad251Schristos get_be_u_3(netdissect_options *ndo, const u_char *p) 609c74ad251Schristos { 610c74ad251Schristos if (!ND_TTEST_3(p)) 611c74ad251Schristos nd_trunc_longjmp(ndo); 612c74ad251Schristos return EXTRACT_BE_U_3(p); 613c74ad251Schristos } 614c74ad251Schristos 615c74ad251Schristos static inline uint32_t 616c74ad251Schristos get_be_u_4(netdissect_options *ndo, const u_char *p) 617c74ad251Schristos { 618c74ad251Schristos if (!ND_TTEST_4(p)) 619c74ad251Schristos nd_trunc_longjmp(ndo); 620c74ad251Schristos return EXTRACT_BE_U_4(p); 621c74ad251Schristos } 622c74ad251Schristos 623c74ad251Schristos static inline uint64_t 624c74ad251Schristos get_be_u_5(netdissect_options *ndo, const u_char *p) 625c74ad251Schristos { 626c74ad251Schristos if (!ND_TTEST_5(p)) 627c74ad251Schristos nd_trunc_longjmp(ndo); 628c74ad251Schristos return EXTRACT_BE_U_5(p); 629c74ad251Schristos } 630c74ad251Schristos 631c74ad251Schristos static inline uint64_t 632c74ad251Schristos get_be_u_6(netdissect_options *ndo, const u_char *p) 633c74ad251Schristos { 634c74ad251Schristos if (!ND_TTEST_6(p)) 635c74ad251Schristos nd_trunc_longjmp(ndo); 636c74ad251Schristos return EXTRACT_BE_U_6(p); 637c74ad251Schristos } 638c74ad251Schristos 639c74ad251Schristos static inline uint64_t 640c74ad251Schristos get_be_u_7(netdissect_options *ndo, const u_char *p) 641c74ad251Schristos { 642c74ad251Schristos if (!ND_TTEST_7(p)) 643c74ad251Schristos nd_trunc_longjmp(ndo); 644c74ad251Schristos return EXTRACT_BE_U_7(p); 645c74ad251Schristos } 646c74ad251Schristos 647c74ad251Schristos static inline uint64_t 648c74ad251Schristos get_be_u_8(netdissect_options *ndo, const u_char *p) 649c74ad251Schristos { 650c74ad251Schristos if (!ND_TTEST_8(p)) 651c74ad251Schristos nd_trunc_longjmp(ndo); 652c74ad251Schristos return EXTRACT_BE_U_8(p); 653c74ad251Schristos } 654c74ad251Schristos 655c74ad251Schristos /* get_be_s_N */ 656c74ad251Schristos 657c74ad251Schristos static inline int16_t 658c74ad251Schristos get_be_s_2(netdissect_options *ndo, const u_char *p) 659c74ad251Schristos { 660c74ad251Schristos if (!ND_TTEST_2(p)) 661c74ad251Schristos nd_trunc_longjmp(ndo); 662c74ad251Schristos return EXTRACT_BE_S_2(p); 663c74ad251Schristos } 664c74ad251Schristos 665c74ad251Schristos static inline int32_t 666c74ad251Schristos get_be_s_3(netdissect_options *ndo, const u_char *p) 667c74ad251Schristos { 668c74ad251Schristos if (!ND_TTEST_3(p)) 669c74ad251Schristos nd_trunc_longjmp(ndo); 670c74ad251Schristos return EXTRACT_BE_S_3(p); 671c74ad251Schristos } 672c74ad251Schristos 673c74ad251Schristos static inline int32_t 674c74ad251Schristos get_be_s_4(netdissect_options *ndo, const u_char *p) 675c74ad251Schristos { 676c74ad251Schristos if (!ND_TTEST_4(p)) 677c74ad251Schristos nd_trunc_longjmp(ndo); 678c74ad251Schristos return EXTRACT_BE_S_4(p); 679c74ad251Schristos } 680c74ad251Schristos 681c74ad251Schristos static inline int64_t 682c74ad251Schristos get_be_s_5(netdissect_options *ndo, const u_char *p) 683c74ad251Schristos { 684c74ad251Schristos if (!ND_TTEST_5(p)) 685c74ad251Schristos nd_trunc_longjmp(ndo); 686c74ad251Schristos return EXTRACT_BE_S_5(p); 687c74ad251Schristos } 688c74ad251Schristos 689c74ad251Schristos static inline int64_t 690c74ad251Schristos get_be_s_6(netdissect_options *ndo, const u_char *p) 691c74ad251Schristos { 692c74ad251Schristos if (!ND_TTEST_6(p)) 693c74ad251Schristos nd_trunc_longjmp(ndo); 694c74ad251Schristos return EXTRACT_BE_S_6(p); 695c74ad251Schristos } 696c74ad251Schristos 697c74ad251Schristos static inline int64_t 698c74ad251Schristos get_be_s_7(netdissect_options *ndo, const u_char *p) 699c74ad251Schristos { 700c74ad251Schristos if (!ND_TTEST_7(p)) 701c74ad251Schristos nd_trunc_longjmp(ndo); 702c74ad251Schristos return EXTRACT_BE_S_7(p); 703c74ad251Schristos } 704c74ad251Schristos 705c74ad251Schristos static inline int64_t 706c74ad251Schristos get_be_s_8(netdissect_options *ndo, const u_char *p) 707c74ad251Schristos { 708c74ad251Schristos if (!ND_TTEST_8(p)) 709c74ad251Schristos nd_trunc_longjmp(ndo); 710c74ad251Schristos return EXTRACT_BE_S_8(p); 711c74ad251Schristos } 712c74ad251Schristos 713c74ad251Schristos /* get_he_u_N */ 714c74ad251Schristos 715c74ad251Schristos static inline uint16_t 716c74ad251Schristos get_he_u_2(netdissect_options *ndo, const u_char *p) 717c74ad251Schristos { 718c74ad251Schristos if (!ND_TTEST_2(p)) 719c74ad251Schristos nd_trunc_longjmp(ndo); 720c74ad251Schristos return EXTRACT_HE_U_2(p); 721c74ad251Schristos } 722c74ad251Schristos 723c74ad251Schristos static inline uint32_t 724c74ad251Schristos get_he_u_4(netdissect_options *ndo, const u_char *p) 725c74ad251Schristos { 726c74ad251Schristos if (!ND_TTEST_4(p)) 727c74ad251Schristos nd_trunc_longjmp(ndo); 728c74ad251Schristos return EXTRACT_HE_U_4(p); 729c74ad251Schristos } 730c74ad251Schristos 731c74ad251Schristos /* get_he_s_N */ 732c74ad251Schristos 733c74ad251Schristos static inline int16_t 734c74ad251Schristos get_he_s_2(netdissect_options *ndo, const u_char *p) 735c74ad251Schristos { 736c74ad251Schristos if (!ND_TTEST_2(p)) 737c74ad251Schristos nd_trunc_longjmp(ndo); 738c74ad251Schristos return EXTRACT_HE_S_2(p); 739c74ad251Schristos } 740c74ad251Schristos 741c74ad251Schristos static inline int32_t 742c74ad251Schristos get_he_s_4(netdissect_options *ndo, const u_char *p) 743c74ad251Schristos { 744c74ad251Schristos if (!ND_TTEST_4(p)) 745c74ad251Schristos nd_trunc_longjmp(ndo); 746c74ad251Schristos return EXTRACT_HE_S_4(p); 747c74ad251Schristos } 748c74ad251Schristos 749c74ad251Schristos /* get_le_u_N */ 750c74ad251Schristos 751c74ad251Schristos static inline uint16_t 752c74ad251Schristos get_le_u_2(netdissect_options *ndo, const u_char *p) 753c74ad251Schristos { 754c74ad251Schristos if (!ND_TTEST_2(p)) 755c74ad251Schristos nd_trunc_longjmp(ndo); 756c74ad251Schristos return EXTRACT_LE_U_2(p); 757c74ad251Schristos } 758c74ad251Schristos 759c74ad251Schristos static inline uint32_t 760c74ad251Schristos get_le_u_3(netdissect_options *ndo, const u_char *p) 761c74ad251Schristos { 762c74ad251Schristos if (!ND_TTEST_3(p)) 763c74ad251Schristos nd_trunc_longjmp(ndo); 764c74ad251Schristos return EXTRACT_LE_U_3(p); 765c74ad251Schristos } 766c74ad251Schristos 767c74ad251Schristos static inline uint32_t 768c74ad251Schristos get_le_u_4(netdissect_options *ndo, const u_char *p) 769c74ad251Schristos { 770c74ad251Schristos if (!ND_TTEST_4(p)) 771c74ad251Schristos nd_trunc_longjmp(ndo); 772c74ad251Schristos return EXTRACT_LE_U_4(p); 773c74ad251Schristos } 774c74ad251Schristos 775c74ad251Schristos static inline uint64_t 776c74ad251Schristos get_le_u_5(netdissect_options *ndo, const u_char *p) 777c74ad251Schristos { 778c74ad251Schristos if (!ND_TTEST_5(p)) 779c74ad251Schristos nd_trunc_longjmp(ndo); 780c74ad251Schristos return EXTRACT_LE_U_5(p); 781c74ad251Schristos } 782c74ad251Schristos 783c74ad251Schristos static inline uint64_t 784c74ad251Schristos get_le_u_6(netdissect_options *ndo, const u_char *p) 785c74ad251Schristos { 786c74ad251Schristos if (!ND_TTEST_6(p)) 787c74ad251Schristos nd_trunc_longjmp(ndo); 788c74ad251Schristos return EXTRACT_LE_U_6(p); 789c74ad251Schristos } 790c74ad251Schristos 791c74ad251Schristos static inline uint64_t 792c74ad251Schristos get_le_u_7(netdissect_options *ndo, const u_char *p) 793c74ad251Schristos { 794c74ad251Schristos if (!ND_TTEST_7(p)) 795c74ad251Schristos nd_trunc_longjmp(ndo); 796c74ad251Schristos return EXTRACT_LE_U_7(p); 797c74ad251Schristos } 798c74ad251Schristos 799c74ad251Schristos static inline uint64_t 800c74ad251Schristos get_le_u_8(netdissect_options *ndo, const u_char *p) 801c74ad251Schristos { 802c74ad251Schristos if (!ND_TTEST_8(p)) 803c74ad251Schristos nd_trunc_longjmp(ndo); 804c74ad251Schristos return EXTRACT_LE_U_8(p); 805c74ad251Schristos } 806c74ad251Schristos 807c74ad251Schristos /* get_le_s_N */ 808c74ad251Schristos 809c74ad251Schristos static inline int16_t 810c74ad251Schristos get_le_s_2(netdissect_options *ndo, const u_char *p) 811c74ad251Schristos { 812c74ad251Schristos if (!ND_TTEST_2(p)) 813c74ad251Schristos nd_trunc_longjmp(ndo); 814c74ad251Schristos return EXTRACT_LE_S_2(p); 815c74ad251Schristos } 816c74ad251Schristos 817c74ad251Schristos static inline int32_t 818c74ad251Schristos get_le_s_3(netdissect_options *ndo, const u_char *p) 819c74ad251Schristos { 820c74ad251Schristos if (!ND_TTEST_3(p)) 821c74ad251Schristos nd_trunc_longjmp(ndo); 822c74ad251Schristos return EXTRACT_LE_S_3(p); 823c74ad251Schristos } 824c74ad251Schristos 825c74ad251Schristos static inline int32_t 826c74ad251Schristos get_le_s_4(netdissect_options *ndo, const u_char *p) 827c74ad251Schristos { 828c74ad251Schristos if (!ND_TTEST_4(p)) 829c74ad251Schristos nd_trunc_longjmp(ndo); 830c74ad251Schristos return EXTRACT_LE_S_4(p); 831c74ad251Schristos } 832c74ad251Schristos 833c74ad251Schristos static inline int64_t 834c74ad251Schristos get_le_s_8(netdissect_options *ndo, const u_char *p) 835c74ad251Schristos { 836c74ad251Schristos if (!ND_TTEST_8(p)) 837c74ad251Schristos nd_trunc_longjmp(ndo); 838c74ad251Schristos return EXTRACT_LE_S_8(p); 839c74ad251Schristos } 840c74ad251Schristos 841c74ad251Schristos /* get_ipv4_to_{host|network]_order */ 842c74ad251Schristos 843c74ad251Schristos static inline uint32_t 844c74ad251Schristos get_ipv4_to_host_order(netdissect_options *ndo, const u_char *p) 845c74ad251Schristos { 846c74ad251Schristos if (!ND_TTEST_4(p)) 847c74ad251Schristos nd_trunc_longjmp(ndo); 848c74ad251Schristos return EXTRACT_IPV4_TO_HOST_ORDER(p); 849c74ad251Schristos } 850c74ad251Schristos 851c74ad251Schristos static inline uint32_t 852c74ad251Schristos get_ipv4_to_network_order(netdissect_options *ndo, const u_char *p) 853c74ad251Schristos { 854c74ad251Schristos if (!ND_TTEST_4(p)) 855c74ad251Schristos nd_trunc_longjmp(ndo); 856c74ad251Schristos return EXTRACT_IPV4_TO_NETWORK_ORDER(p); 857c74ad251Schristos } 858c74ad251Schristos 859c74ad251Schristos static inline void 860c74ad251Schristos get_cpy_bytes(netdissect_options *ndo, u_char *dst, const u_char *p, size_t len) 861c74ad251Schristos { 862c74ad251Schristos if (!ND_TTEST_LEN(p, len)) 863c74ad251Schristos nd_trunc_longjmp(ndo); 864c74ad251Schristos UNALIGNED_MEMCPY(dst, p, len); 865c74ad251Schristos } 866c74ad251Schristos 867c74ad251Schristos #define GET_U_1(p) get_u_1(ndo, (const u_char *)(p)) 868c74ad251Schristos #define GET_S_1(p) get_s_1(ndo, (const u_char *)(p)) 869c74ad251Schristos 870c74ad251Schristos #define GET_BE_U_2(p) get_be_u_2(ndo, (const u_char *)(p)) 871c74ad251Schristos #define GET_BE_U_3(p) get_be_u_3(ndo, (const u_char *)(p)) 872c74ad251Schristos #define GET_BE_U_4(p) get_be_u_4(ndo, (const u_char *)(p)) 873c74ad251Schristos #define GET_BE_U_5(p) get_be_u_5(ndo, (const u_char *)(p)) 874c74ad251Schristos #define GET_BE_U_6(p) get_be_u_6(ndo, (const u_char *)(p)) 875c74ad251Schristos #define GET_BE_U_7(p) get_be_u_7(ndo, (const u_char *)(p)) 876c74ad251Schristos #define GET_BE_U_8(p) get_be_u_8(ndo, (const u_char *)(p)) 877c74ad251Schristos 878c74ad251Schristos #define GET_BE_S_2(p) get_be_s_2(ndo, (const u_char *)(p)) 879c74ad251Schristos #define GET_BE_S_3(p) get_be_s_3(ndo, (const u_char *)(p)) 880c74ad251Schristos #define GET_BE_S_4(p) get_be_s_4(ndo, (const u_char *)(p)) 881c74ad251Schristos #define GET_BE_S_5(p) get_be_s_5(ndo, (const u_char *)(p)) 882c74ad251Schristos #define GET_BE_S_6(p) get_be_s_6(ndo, (const u_char *)(p)) 883c74ad251Schristos #define GET_BE_S_7(p) get_be_s_7(ndo, (const u_char *)(p)) 884c74ad251Schristos #define GET_BE_S_8(p) get_be_s_8(ndo, (const u_char *)(p)) 885c74ad251Schristos 886c74ad251Schristos #define GET_HE_U_2(p) get_he_u_2(ndo, (const u_char *)(p)) 887c74ad251Schristos #define GET_HE_U_4(p) get_he_u_4(ndo, (const u_char *)(p)) 888c74ad251Schristos 889c74ad251Schristos #define GET_HE_S_2(p) get_he_s_2(ndo, (const u_char *)(p)) 890c74ad251Schristos #define GET_HE_S_4(p) get_he_s_4(ndo, (const u_char *)(p)) 891c74ad251Schristos 892c74ad251Schristos #define GET_LE_U_2(p) get_le_u_2(ndo, (const u_char *)(p)) 893c74ad251Schristos #define GET_LE_U_3(p) get_le_u_3(ndo, (const u_char *)(p)) 894c74ad251Schristos #define GET_LE_U_4(p) get_le_u_4(ndo, (const u_char *)(p)) 895c74ad251Schristos #define GET_LE_U_5(p) get_le_u_5(ndo, (const u_char *)(p)) 896c74ad251Schristos #define GET_LE_U_6(p) get_le_u_6(ndo, (const u_char *)(p)) 897c74ad251Schristos #define GET_LE_U_7(p) get_le_u_7(ndo, (const u_char *)(p)) 898c74ad251Schristos #define GET_LE_U_8(p) get_le_u_8(ndo, (const u_char *)(p)) 899c74ad251Schristos 900c74ad251Schristos #define GET_LE_S_2(p) get_le_s_2(ndo, (const u_char *)(p)) 901c74ad251Schristos #define GET_LE_S_3(p) get_le_s_3(ndo, (const u_char *)(p)) 902c74ad251Schristos #define GET_LE_S_4(p) get_le_s_4(ndo, (const u_char *)(p)) 903c74ad251Schristos #define GET_LE_S_8(p) get_le_s_8(ndo, (const u_char *)(p)) 904c74ad251Schristos 905c74ad251Schristos #define GET_IPV4_TO_HOST_ORDER(p) get_ipv4_to_host_order(ndo, (const u_char *)(p)) 906c74ad251Schristos #define GET_IPV4_TO_NETWORK_ORDER(p) get_ipv4_to_network_order(ndo, (const u_char *)(p)) 907c74ad251Schristos 908c74ad251Schristos #define GET_CPY_BYTES(dst, p, len) get_cpy_bytes(ndo, (u_char *)(dst), (const u_char *)(p), len) 909c74ad251Schristos 910c74ad251Schristos #endif /* EXTRACT_H */ 911