1 /*
2 * nghttp3
3 *
4 * Copyright (c) 2019 nghttp3 contributors
5 * Copyright (c) 2017 ngtcp2 contributors
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26 #ifndef NGHTTP3_CONV_H
27 #define NGHTTP3_CONV_H
28
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif /* HAVE_CONFIG_H */
32
33 #ifdef HAVE_ARPA_INET_H
34 # include <arpa/inet.h>
35 #endif /* HAVE_ARPA_INET_H */
36
37 #ifdef HAVE_NETINET_IN_H
38 # include <netinet/in.h>
39 #endif /* HAVE_NETINET_IN_H */
40
41 #ifdef HAVE_BYTESWAP_H
42 # include <byteswap.h>
43 #endif /* HAVE_BYTESWAP_H */
44
45 #ifdef HAVE_ENDIAN_H
46 # include <endian.h>
47 #endif /* HAVE_ENDIAN_H */
48
49 #ifdef HAVE_SYS_ENDIAN_H
50 # include <sys/endian.h>
51 #endif /* HAVE_SYS_ENDIAN_H */
52
53 #include <nghttp3/nghttp3.h>
54
55 #if defined(HAVE_BSWAP_64) || \
56 (defined(HAVE_DECL_BSWAP_64) && HAVE_DECL_BSWAP_64 > 0)
57 # define nghttp3_bswap64 bswap_64
58 #else /* !HAVE_BSWAP_64 */
59 # define nghttp3_bswap64(N) \
60 ((uint64_t)(ntohl((uint32_t)(N))) << 32 | ntohl((uint32_t)((N) >> 32)))
61 #endif /* !HAVE_BSWAP_64 */
62
63 #if defined(HAVE_BE64TOH) || \
64 (defined(HAVE_DECL_BE64TOH) && HAVE_DECL_BE64TOH > 0)
65 # define nghttp3_ntohl64(N) be64toh(N)
66 # define nghttp3_htonl64(N) htobe64(N)
67 #else /* !HAVE_BE64TOH */
68 # if defined(WORDS_BIGENDIAN)
69 # define nghttp3_ntohl64(N) (N)
70 # define nghttp3_htonl64(N) (N)
71 # else /* !WORDS_BIGENDIAN */
72 # define nghttp3_ntohl64(N) nghttp3_bswap64(N)
73 # define nghttp3_htonl64(N) nghttp3_bswap64(N)
74 # endif /* !WORDS_BIGENDIAN */
75 #endif /* !HAVE_BE64TOH */
76
77 #if defined(WIN32)
78 /* Windows requires ws2_32 library for ntonl family of functions. We
79 define inline functions for those functions so that we don't have
80 dependency on that lib. */
81
82 # ifdef _MSC_VER
83 # define STIN static __inline
84 # else
85 # define STIN static inline
86 # endif
87
htonl(uint32_t hostlong)88 STIN uint32_t htonl(uint32_t hostlong) {
89 uint32_t res;
90 unsigned char *p = (unsigned char *)&res;
91 *p++ = (unsigned char)(hostlong >> 24);
92 *p++ = (hostlong >> 16) & 0xffu;
93 *p++ = (hostlong >> 8) & 0xffu;
94 *p = hostlong & 0xffu;
95 return res;
96 }
97
htons(uint16_t hostshort)98 STIN uint16_t htons(uint16_t hostshort) {
99 uint16_t res;
100 unsigned char *p = (unsigned char *)&res;
101 *p++ = (unsigned char)(hostshort >> 8);
102 *p = hostshort & 0xffu;
103 return res;
104 }
105
ntohl(uint32_t netlong)106 STIN uint32_t ntohl(uint32_t netlong) {
107 uint32_t res;
108 unsigned char *p = (unsigned char *)&netlong;
109 res = *p++ << 24;
110 res += *p++ << 16;
111 res += *p++ << 8;
112 res += *p;
113 return res;
114 }
115
ntohs(uint16_t netshort)116 STIN uint16_t ntohs(uint16_t netshort) {
117 uint16_t res;
118 unsigned char *p = (unsigned char *)&netshort;
119 res = *p++ << 8;
120 res += *p;
121 return res;
122 }
123
124 #endif /* WIN32 */
125
126 /*
127 * nghttp3_get_varint reads variable-length integer from |p|, and
128 * returns it in host byte order. The number of bytes read is stored
129 * in |*plen|.
130 */
131 int64_t nghttp3_get_varint(size_t *plen, const uint8_t *p);
132
133 /*
134 * nghttp3_get_varint_fb reads first byte of encoded variable-length
135 * integer from |p|.
136 */
137 int64_t nghttp3_get_varint_fb(const uint8_t *p);
138
139 /*
140 * nghttp3_get_varint_len returns the required number of bytes to read
141 * variable-length integer starting at |p|.
142 */
143 size_t nghttp3_get_varint_len(const uint8_t *p);
144
145 /*
146 * nghttp3_put_uint64be writes |n| in host byte order in |p| in
147 * network byte order. It returns the one beyond of the last written
148 * position.
149 */
150 uint8_t *nghttp3_put_uint64be(uint8_t *p, uint64_t n);
151
152 /*
153 * nghttp3_put_uint48be writes |n| in host byte order in |p| in
154 * network byte order. It writes only least significant 48 bits. It
155 * returns the one beyond of the last written position.
156 */
157 uint8_t *nghttp3_put_uint48be(uint8_t *p, uint64_t n);
158
159 /*
160 * nghttp3_put_uint32be writes |n| in host byte order in |p| in
161 * network byte order. It returns the one beyond of the last written
162 * position.
163 */
164 uint8_t *nghttp3_put_uint32be(uint8_t *p, uint32_t n);
165
166 /*
167 * nghttp3_put_uint24be writes |n| in host byte order in |p| in
168 * network byte order. It writes only least significant 24 bits. It
169 * returns the one beyond of the last written position.
170 */
171 uint8_t *nghttp3_put_uint24be(uint8_t *p, uint32_t n);
172
173 /*
174 * nghttp3_put_uint16be writes |n| in host byte order in |p| in
175 * network byte order. It returns the one beyond of the last written
176 * position.
177 */
178 uint8_t *nghttp3_put_uint16be(uint8_t *p, uint16_t n);
179
180 /*
181 * nghttp3_put_varint writes |n| in |p| using variable-length integer
182 * encoding. It returns the one beyond of the last written position.
183 */
184 uint8_t *nghttp3_put_varint(uint8_t *p, int64_t n);
185
186 /*
187 * nghttp3_put_varint_len returns the required number of bytes to
188 * encode |n|.
189 */
190 size_t nghttp3_put_varint_len(int64_t n);
191
192 /*
193 * nghttp3_ord_stream_id returns the ordinal number of |stream_id|.
194 */
195 uint64_t nghttp3_ord_stream_id(int64_t stream_id);
196
197 /*
198 * NGHTTP3_PRI_INC_MASK is a bit mask to retrieve incremental bit from
199 * a value produced by nghttp3_pri_to_uint8.
200 */
201 #define NGHTTP3_PRI_INC_MASK (1 << 7)
202
203 /*
204 * nghttp3_pri_to_uint8 encodes |pri| into uint8_t variable.
205 */
206 uint8_t nghttp3_pri_to_uint8(const nghttp3_pri *pri);
207
208 /*
209 * nghttp3_pri_uint8_urgency extracts urgency from |PRI| which is
210 * supposed to be constructed by nghttp3_pri_to_uint8.
211 */
212 #define nghttp3_pri_uint8_urgency(PRI) \
213 ((uint32_t)((PRI) & ~NGHTTP3_PRI_INC_MASK))
214
215 /*
216 * nghttp3_pri_uint8_inc extracts inc from |PRI| which is supposed to
217 * be constructed by nghttp3_pri_to_uint8.
218 */
219 #define nghttp3_pri_uint8_inc(PRI) (((PRI)&NGHTTP3_PRI_INC_MASK) != 0)
220
221 #endif /* NGHTTP3_CONV_H */
222