7c7e53420250b9c6e536c7107a4d99dccd3f83fa
[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 le32toh
48 # if BYTE_ORDER == BIG_ENDIAN
49 # define le32toh(x) __builtin_bswap32(x)
50 # else
51 # define le32toh(x) (x)
52 # endif
53 #endif
54 #ifndef htole32
55 # if BYTE_ORDER == BIG_ENDIAN
56 # define htole32(x) __builtin_bswap32(x)
57 # else
58 # define htole32(x) (x)
59 # endif
60 #endif
61
62 #ifndef le64toh
63 # if BYTE_ORDER == BIG_ENDIAN
64 # define le64toh(x) __builtin_bswap64(x)
65 # else
66 # define le64toh(x) (x)
67 # endif
68 #endif
69 #ifndef htole64
70 # if BYTE_ORDER == BIG_ENDIAN
71 # define htole64(x) __builtin_bswap64(x)
72 # else
73 # define htole64(x) (x)
74 # endif
75 #endif
76
77 #ifndef be64toh
78 # if BYTE_ORDER == BIG_ENDIAN
79 # define be64toh(x) (x)
80 # else
81 # define be64toh(x) __builtin_bswap64(x)
82 # endif
83 #endif
84 #ifndef htobe64
85 # if BYTE_ORDER == BIG_ENDIAN
86 # define htobe64(x) (x)
87 # else
88 # define htobe64(x) __builtin_bswap64(x)
89 # endif
90 #endif
91
92 /**
93 * Write a 16-bit host order value in network order to an unaligned address.
94 *
95 * @param host host order 16-bit value
96 * @param network unaligned address to write network order value to
97 */
98 static inline void htoun16(void *network, uint16_t host)
99 {
100 char *unaligned = (char*)network;
101
102 host = htons(host);
103 memcpy(unaligned, &host, sizeof(host));
104 }
105
106 /**
107 * Write a 32-bit host order value in network order to an unaligned address.
108 *
109 * @param host host order 32-bit value
110 * @param network unaligned address to write network order value to
111 */
112 static inline void htoun32(void *network, uint32_t host)
113 {
114 char *unaligned = (char*)network;
115
116 host = htonl(host);
117 memcpy((char*)unaligned, &host, sizeof(host));
118 }
119
120 /**
121 * Write a 64-bit host order value in network order to an unaligned address.
122 *
123 * @param host host order 64-bit value
124 * @param network unaligned address to write network order value to
125 */
126 static inline void htoun64(void *network, uint64_t host)
127 {
128 char *unaligned = (char*)network;
129
130 host = htobe64(host);
131 memcpy((char*)unaligned, &host, sizeof(host));
132 }
133
134 /**
135 * Read a 16-bit value in network order from an unaligned address to host order.
136 *
137 * @param network unaligned address to read network order value from
138 * @return host order value
139 */
140 static inline uint16_t untoh16(void *network)
141 {
142 char *unaligned = (char*)network;
143 uint16_t tmp;
144
145 memcpy(&tmp, unaligned, sizeof(tmp));
146 return ntohs(tmp);
147 }
148
149 /**
150 * Read a 32-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 uint32_t untoh32(void *network)
156 {
157 char *unaligned = (char*)network;
158 uint32_t tmp;
159
160 memcpy(&tmp, unaligned, sizeof(tmp));
161 return ntohl(tmp);
162 }
163
164 /**
165 * Read a 64-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 uint64_t untoh64(void *network)
171 {
172 char *unaligned = (char*)network;
173 uint64_t tmp;
174
175 memcpy(&tmp, unaligned, sizeof(tmp));
176 return be64toh(tmp);
177 }
178
179 /**
180 * Read a 32-bit value in little-endian order from unaligned address.
181 *
182 * @param p unaligned address to read little endian value from
183 * @return host order value
184 */
185 static inline uint32_t uletoh32(void *p)
186 {
187 uint32_t ret;
188
189 memcpy(&ret, p, sizeof(ret));
190 ret = le32toh(ret);
191 return ret;
192 }
193
194 /**
195 * Write a 32-bit value in little-endian to an unaligned address.
196 *
197 * @param p host order 32-bit value
198 * @param v unaligned address to write little endian value to
199 */
200 static inline void htoule32(void *p, uint32_t v)
201 {
202 v = htole32(v);
203 memcpy(p, &v, sizeof(v));
204 }
205
206 #endif /** BYTEORDER_H_ @} */