utils: Defined uletoh16() and htole16()
[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(uint8_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 le16toh
48 # if BYTE_ORDER == BIG_ENDIAN
49 # define le16toh(x) __builtin_bswap16(x)
50 # else
51 # define le16toh(x) (x)
52 # endif
53 #endif
54 #ifndef htole16
55 # if BYTE_ORDER == BIG_ENDIAN
56 # define htole16(x) __builtin_bswap16(x)
57 # else
58 # define htole16(x) (x)
59 # endif
60 #endif
61
62 #ifndef le32toh
63 # if BYTE_ORDER == BIG_ENDIAN
64 # define le32toh(x) __builtin_bswap32(x)
65 # else
66 # define le32toh(x) (x)
67 # endif
68 #endif
69 #ifndef htole32
70 # if BYTE_ORDER == BIG_ENDIAN
71 # define htole32(x) __builtin_bswap32(x)
72 # else
73 # define htole32(x) (x)
74 # endif
75 #endif
76
77 #ifndef le64toh
78 # if BYTE_ORDER == BIG_ENDIAN
79 # define le64toh(x) __builtin_bswap64(x)
80 # else
81 # define le64toh(x) (x)
82 # endif
83 #endif
84 #ifndef htole64
85 # if BYTE_ORDER == BIG_ENDIAN
86 # define htole64(x) __builtin_bswap64(x)
87 # else
88 # define htole64(x) (x)
89 # endif
90 #endif
91
92 #ifndef be64toh
93 # if BYTE_ORDER == BIG_ENDIAN
94 # define be64toh(x) (x)
95 # else
96 # define be64toh(x) __builtin_bswap64(x)
97 # endif
98 #endif
99 #ifndef htobe64
100 # if BYTE_ORDER == BIG_ENDIAN
101 # define htobe64(x) (x)
102 # else
103 # define htobe64(x) __builtin_bswap64(x)
104 # endif
105 #endif
106
107 /**
108 * Write a 16-bit host order value in network order to an unaligned address.
109 *
110 * @param host host order 16-bit value
111 * @param network unaligned address to write network order value to
112 */
113 static inline void htoun16(void *network, uint16_t host)
114 {
115 char *unaligned = (char*)network;
116
117 host = htons(host);
118 memcpy(unaligned, &host, sizeof(host));
119 }
120
121 /**
122 * Write a 32-bit host order value in network order to an unaligned address.
123 *
124 * @param host host order 32-bit value
125 * @param network unaligned address to write network order value to
126 */
127 static inline void htoun32(void *network, uint32_t host)
128 {
129 char *unaligned = (char*)network;
130
131 host = htonl(host);
132 memcpy((char*)unaligned, &host, sizeof(host));
133 }
134
135 /**
136 * Write a 64-bit host order value in network order to an unaligned address.
137 *
138 * @param host host order 64-bit value
139 * @param network unaligned address to write network order value to
140 */
141 static inline void htoun64(void *network, uint64_t host)
142 {
143 char *unaligned = (char*)network;
144
145 host = htobe64(host);
146 memcpy((char*)unaligned, &host, sizeof(host));
147 }
148
149 /**
150 * Read a 16-bit value in network order from an unaligned address to host order.
151 *
152 * @param network unaligned address to read network order value from
153 * @return host order value
154 */
155 static inline uint16_t untoh16(void *network)
156 {
157 char *unaligned = (char*)network;
158 uint16_t tmp;
159
160 memcpy(&tmp, unaligned, sizeof(tmp));
161 return ntohs(tmp);
162 }
163
164 /**
165 * Read a 32-bit value in network order from an unaligned address to host order.
166 *
167 * @param network unaligned address to read network order value from
168 * @return host order value
169 */
170 static inline uint32_t untoh32(void *network)
171 {
172 char *unaligned = (char*)network;
173 uint32_t tmp;
174
175 memcpy(&tmp, unaligned, sizeof(tmp));
176 return ntohl(tmp);
177 }
178
179 /**
180 * Read a 64-bit value in network order from an unaligned address to host order.
181 *
182 * @param network unaligned address to read network order value from
183 * @return host order value
184 */
185 static inline uint64_t untoh64(void *network)
186 {
187 char *unaligned = (char*)network;
188 uint64_t tmp;
189
190 memcpy(&tmp, unaligned, sizeof(tmp));
191 return be64toh(tmp);
192 }
193
194 /**
195 * Read a 16-bit value in little-endian order from unaligned address.
196 *
197 * @param p unaligned address to read little endian value from
198 * @return host order value
199 */
200 static inline uint16_t uletoh16(void *p)
201 {
202 uint16_t ret;
203
204 memcpy(&ret, p, sizeof(ret));
205 ret = le16toh(ret);
206 return ret;
207 }
208
209 /**
210 * Write a 16-bit value in little-endian to an unaligned address.
211 *
212 * @param p host order 16-bit value
213 * @param v unaligned address to write little endian value to
214 */
215 static inline void htoule16(void *p, uint16_t v)
216 {
217 v = htole16(v);
218 memcpy(p, &v, sizeof(v));
219 }
220
221 /**
222 * Read a 32-bit value in little-endian order from unaligned address.
223 *
224 * @param p unaligned address to read little endian value from
225 * @return host order value
226 */
227 static inline uint32_t uletoh32(void *p)
228 {
229 uint32_t ret;
230
231 memcpy(&ret, p, sizeof(ret));
232 ret = le32toh(ret);
233 return ret;
234 }
235
236 /**
237 * Write a 32-bit value in little-endian to an unaligned address.
238 *
239 * @param p host order 32-bit value
240 * @param v unaligned address to write little endian value to
241 */
242 static inline void htoule32(void *p, uint32_t v)
243 {
244 v = htole32(v);
245 memcpy(p, &v, sizeof(v));
246 }
247
248 #endif /** BYTEORDER_H_ @} */