1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 #ifndef _SYS_BYTEORDER_H
42 #define _SYS_BYTEORDER_H
43
44 #if defined(__GNUC__) && defined(_ASM_INLINES) && \
45 (defined(__i386) || defined(__amd64))
46 #include <asm/byteorder.h>
47 #endif
48
49 #include <sys/isa_defs.h>
50 #include <inttypes.h>
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 /*
57 * macros for conversion between host and (internet) network byte order
58 */
59
60 #if defined(_ZFS_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint)
61 /* big-endian */
62 #define ntohl(x) (x)
63 #define ntohs(x) (x)
64 #define htonl(x) (x)
65 #define htons(x) (x)
66
67 #elif !defined(ntohl) /* little-endian */
68
69 #ifndef _IN_PORT_T
70 #define _IN_PORT_T
71 typedef uint16_t in_port_t;
72 #endif
73
74 #ifndef _IN_ADDR_T
75 #define _IN_ADDR_T
76 typedef uint32_t in_addr_t;
77 #endif
78
79 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5)
80 extern uint32_t htonl(uint32_t);
81 extern uint16_t htons(uint16_t);
82 extern uint32_t ntohl(uint32_t);
83 extern uint16_t ntohs(uint16_t);
84 #else
85 extern in_addr_t htonl(in_addr_t);
86 extern in_port_t htons(in_port_t);
87 extern in_addr_t ntohl(in_addr_t);
88 extern in_port_t ntohs(in_port_t);
89 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */
90 #endif
91
92 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
93
94 #ifdef __COVERITY__
95 /*
96 * Coverity's taint warnings from byteswapping are false positives for us.
97 * Suppress them by hiding byteswapping from Coverity.
98 */
99 #define BSWAP_8(x) ((x) & 0xff)
100 #define BSWAP_16(x) ((x) & 0xffff)
101 #define BSWAP_32(x) ((x) & 0xffffffff)
102 #define BSWAP_64(x) (x)
103
104 #else /* __COVERITY__ */
105
106 /*
107 * Macros to reverse byte order
108 */
109 #define BSWAP_8(x) ((x) & 0xff)
110 #define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
111 #define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
112 #define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
113
114 #endif /* __COVERITY__ */
115
116 #define BMASK_8(x) ((x) & 0xff)
117 #define BMASK_16(x) ((x) & 0xffff)
118 #define BMASK_32(x) ((x) & 0xffffffff)
119 #define BMASK_64(x) (x)
120
121 /*
122 * Macros to convert from a specific byte order to/from native byte order
123 */
124 #ifdef _ZFS_BIG_ENDIAN
125 #define BE_8(x) BMASK_8(x)
126 #define BE_16(x) BMASK_16(x)
127 #define BE_32(x) BMASK_32(x)
128 #define BE_64(x) BMASK_64(x)
129 #define LE_8(x) BSWAP_8(x)
130 #define LE_16(x) BSWAP_16(x)
131 #define LE_32(x) BSWAP_32(x)
132 #define LE_64(x) BSWAP_64(x)
133 #else
134 #define LE_8(x) BMASK_8(x)
135 #define LE_16(x) BMASK_16(x)
136 #define LE_32(x) BMASK_32(x)
137 #define LE_64(x) BMASK_64(x)
138 #define BE_8(x) BSWAP_8(x)
139 #define BE_16(x) BSWAP_16(x)
140 #define BE_32(x) BSWAP_32(x)
141 #define BE_64(x) BSWAP_64(x)
142 #endif
143
144 #ifdef _ZFS_BIG_ENDIAN
145 static __inline__ uint64_t
htonll(uint64_t n)146 htonll(uint64_t n)
147 {
148 return (n);
149 }
150
151 static __inline__ uint64_t
ntohll(uint64_t n)152 ntohll(uint64_t n)
153 {
154 return (n);
155 }
156 #else
157 static __inline__ uint64_t
158 htonll(uint64_t n)
159 {
160 return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
161 }
162
163 static __inline__ uint64_t
164 ntohll(uint64_t n)
165 {
166 return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
167 }
168 #endif
169
170 /*
171 * Macros to read unaligned values from a specific byte order to
172 * native byte order
173 */
174
175 #define BE_IN8(xa) \
176 *((uint8_t *)(xa))
177
178 #define BE_IN16(xa) \
179 (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
180
181 #define BE_IN32(xa) \
182 (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
183
184 #define BE_IN64(xa) \
185 (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
186
187 #define LE_IN8(xa) \
188 *((uint8_t *)(xa))
189
190 #define LE_IN16(xa) \
191 (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
192
193 #define LE_IN32(xa) \
194 (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
195
196 #define LE_IN64(xa) \
197 (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
198
199 /*
200 * Macros to write unaligned values from native byte order to a specific byte
201 * order.
202 */
203
204 #define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
205
206 #define BE_OUT16(xa, yv) \
207 BE_OUT8((uint8_t *)(xa) + 1, yv); \
208 BE_OUT8((uint8_t *)(xa), (yv) >> 8);
209
210 #define BE_OUT32(xa, yv) \
211 BE_OUT16((uint8_t *)(xa) + 2, yv); \
212 BE_OUT16((uint8_t *)(xa), (yv) >> 16);
213
214 #define BE_OUT64(xa, yv) \
215 BE_OUT32((uint8_t *)(xa) + 4, yv); \
216 BE_OUT32((uint8_t *)(xa), (yv) >> 32);
217
218 #define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
219
220 #define LE_OUT16(xa, yv) \
221 LE_OUT8((uint8_t *)(xa), yv); \
222 LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
223
224 #define LE_OUT32(xa, yv) \
225 LE_OUT16((uint8_t *)(xa), yv); \
226 LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
227
228 #define LE_OUT64(xa, yv) \
229 LE_OUT32((uint8_t *)(xa), yv); \
230 LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
231
232 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
233
234 #ifdef __cplusplus
235 }
236 #endif
237
238 #endif /* _SYS_BYTEORDER_H */
239