byteorder: Always define be64toh/htobe64 macros
[strongswan.git] / src / libstrongswan / utils / utils / byteorder.h
1 /*
2 * Copyright (C) 2008-2014 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /**
18 * @defgroup byteorder_i byteorder
19 * @{ @ingroup utils_i
20 */
21
22 #ifndef BYTEORDER_H_
23 #define BYTEORDER_H_
24
25 /**
26 * Architecture independent bitfield definition helpers (at least with GCC).
27 *
28 * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
29 * BITFIELD2(u_int8_t,
30 * low: 4,
31 * high: 4,
32 * ) flags;
33 * The member defined first placed at bit 0.
34 */
35 #if BYTE_ORDER == LITTLE_ENDIAN
36 #define BITFIELD2(t, a, b,...) struct { t a; t b; __VA_ARGS__}
37 #define BITFIELD3(t, a, b, c,...) struct { t a; t b; t c; __VA_ARGS__}
38 #define BITFIELD4(t, a, b, c, d,...) struct { t a; t b; t c; t d; __VA_ARGS__}
39 #define BITFIELD5(t, a, b, c, d, e,...) struct { t a; t b; t c; t d; t e; __VA_ARGS__}
40 #elif BYTE_ORDER == BIG_ENDIAN
41 #define BITFIELD2(t, a, b,...) struct { t b; t a; __VA_ARGS__}
42 #define BITFIELD3(t, a, b, c,...) struct { t c; t b; t a; __VA_ARGS__}
43 #define BITFIELD4(t, a, b, c, d,...) struct { t d; t c; t b; t a; __VA_ARGS__}
44 #define BITFIELD5(t, a, b, c, d, e,...) struct { t e; t d; t c; t b; t a; __VA_ARGS__}
45 #endif
46
47 #ifndef le32toh
48 # if BYTE_ORDER == BIG_ENDIAN
49 # define le32toh(x) __builtin_bswap32(x)
50 # define htole32(x) __builtin_bswap32(x)
51 # else
52 # define le32toh(x) (x)
53 # define htole32(x) (x)
54 # endif
55 #endif
56
57 #ifndef le64toh
58 # if BYTE_ORDER == BIG_ENDIAN
59 # define le64toh(x) __builtin_bswap64(x)
60 # define htole64(x) __builtin_bswap64(x)
61 # else
62 # define le64toh(x) (x)
63 # define htole64(x) (x)
64 # endif
65 #endif
66
67 #ifndef be64toh
68 # if BYTE_ORDER == BIG_ENDIAN
69 # define be64toh(x) (x)
70 # define htobe64(x) (x)
71 # else
72 # define be64toh(x) __builtin_bswap64(x)
73 # define htobe64(x) __builtin_bswap64(x)
74 # endif
75 #endif
76
77 /**
78 * Write a 16-bit host order value in network order to an unaligned address.
79 *
80 * @param host host order 16-bit value
81 * @param network unaligned address to write network order value to
82 */
83 static inline void htoun16(void *network, u_int16_t host)
84 {
85 char *unaligned = (char*)network;
86
87 host = htons(host);
88 memcpy(unaligned, &host, sizeof(host));
89 }
90
91 /**
92 * Write a 32-bit host order value in network order to an unaligned address.
93 *
94 * @param host host order 32-bit value
95 * @param network unaligned address to write network order value to
96 */
97 static inline void htoun32(void *network, u_int32_t host)
98 {
99 char *unaligned = (char*)network;
100
101 host = htonl(host);
102 memcpy((char*)unaligned, &host, sizeof(host));
103 }
104
105 /**
106 * Write a 64-bit host order value in network order to an unaligned address.
107 *
108 * @param host host order 64-bit value
109 * @param network unaligned address to write network order value to
110 */
111 static inline void htoun64(void *network, u_int64_t host)
112 {
113 char *unaligned = (char*)network;
114
115 #ifdef be64toh
116 host = htobe64(host);
117 memcpy((char*)unaligned, &host, sizeof(host));
118 #else
119 u_int32_t high_part, low_part;
120
121 high_part = host >> 32;
122 high_part = htonl(high_part);
123 low_part = host & 0xFFFFFFFFLL;
124 low_part = htonl(low_part);
125
126 memcpy(unaligned, &high_part, sizeof(high_part));
127 unaligned += sizeof(high_part);
128 memcpy(unaligned, &low_part, sizeof(low_part));
129 #endif
130 }
131
132 /**
133 * Read a 16-bit value in network order from an unaligned address to host order.
134 *
135 * @param network unaligned address to read network order value from
136 * @return host order value
137 */
138 static inline u_int16_t untoh16(void *network)
139 {
140 char *unaligned = (char*)network;
141 u_int16_t tmp;
142
143 memcpy(&tmp, unaligned, sizeof(tmp));
144 return ntohs(tmp);
145 }
146
147 /**
148 * Read a 32-bit value in network order from an unaligned address to host order.
149 *
150 * @param network unaligned address to read network order value from
151 * @return host order value
152 */
153 static inline u_int32_t untoh32(void *network)
154 {
155 char *unaligned = (char*)network;
156 u_int32_t tmp;
157
158 memcpy(&tmp, unaligned, sizeof(tmp));
159 return ntohl(tmp);
160 }
161
162 /**
163 * Read a 64-bit value in network order from an unaligned address to host order.
164 *
165 * @param network unaligned address to read network order value from
166 * @return host order value
167 */
168 static inline u_int64_t untoh64(void *network)
169 {
170 char *unaligned = (char*)network;
171
172 #ifdef be64toh
173 u_int64_t tmp;
174
175 memcpy(&tmp, unaligned, sizeof(tmp));
176 return be64toh(tmp);
177 #else
178 u_int32_t high_part, low_part;
179
180 memcpy(&high_part, unaligned, sizeof(high_part));
181 unaligned += sizeof(high_part);
182 memcpy(&low_part, unaligned, sizeof(low_part));
183
184 high_part = ntohl(high_part);
185 low_part = ntohl(low_part);
186
187 return (((u_int64_t)high_part) << 32) + low_part;
188 #endif
189 }
190
191 /**
192 * Read a 32-bit value in little-endian order from unaligned address.
193 *
194 * @param network unaligned address to read little endian value from
195 * @return host order value
196 */
197 static inline u_int32_t uletoh32(void *p)
198 {
199 u_int32_t ret;
200
201 memcpy(&ret, p, sizeof(ret));
202 ret = le32toh(ret);
203 return ret;
204 }
205
206 /**
207 * Write a 32-bit value in little-endian to an unaligned address.
208 *
209 * @param host host order 32-bit value
210 * @param network unaligned address to write little endian value to
211 */
212 static inline void htoule32(void *p, u_int32_t v)
213 {
214 v = htole32(v);
215 memcpy(p, &v, sizeof(v));
216 }
217
218 #endif /** BYTEORDER_H_ @} */