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