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