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