Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/libslirp/util.c
2 views
1
/* SPDX-License-Identifier: MIT */
2
/*
3
* util.c (mostly based on QEMU os-win32.c)
4
*
5
* Copyright (c) 2003-2008 Fabrice Bellard
6
* Copyright (c) 2010-2016 Red Hat, Inc.
7
*
8
* QEMU library functions for win32 which are shared between QEMU and
9
* the QEMU tools.
10
*
11
* Permission is hereby granted, free of charge, to any person obtaining a copy
12
* of this software and associated documentation files (the "Software"), to deal
13
* in the Software without restriction, including without limitation the rights
14
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
* copies of the Software, and to permit persons to whom the Software is
16
* furnished to do so, subject to the following conditions:
17
*
18
* The above copyright notice and this permission notice shall be included in
19
* all copies or substantial portions of the Software.
20
*
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
* THE SOFTWARE.
28
*/
29
#include "util.h"
30
31
#include <glib.h>
32
#include <fcntl.h>
33
#include <stdint.h>
34
35
#if defined(_WIN32)
36
int slirp_inet_aton(const char *cp, struct in_addr *ia)
37
{
38
uint32_t addr = inet_addr(cp);
39
if (addr == 0xffffffff) {
40
return 0;
41
}
42
ia->s_addr = addr;
43
return 1;
44
}
45
#endif
46
47
void slirp_set_nonblock(int fd)
48
{
49
#ifndef _WIN32
50
int f;
51
f = fcntl(fd, F_GETFL);
52
assert(f != -1);
53
f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
54
assert(f != -1);
55
#else
56
unsigned long opt = 1;
57
ioctlsocket(fd, FIONBIO, &opt);
58
#endif
59
}
60
61
static void slirp_set_cloexec(int fd)
62
{
63
#ifndef _WIN32
64
int f;
65
f = fcntl(fd, F_GETFD);
66
assert(f != -1);
67
f = fcntl(fd, F_SETFD, f | FD_CLOEXEC);
68
assert(f != -1);
69
#endif
70
}
71
72
/*
73
* Opens a socket with FD_CLOEXEC set
74
* On failure errno contains the reason.
75
*/
76
int slirp_socket(int domain, int type, int protocol)
77
{
78
int ret;
79
80
#ifdef SOCK_CLOEXEC
81
ret = socket(domain, type | SOCK_CLOEXEC, protocol);
82
if (ret != -1 || errno != EINVAL) {
83
return ret;
84
}
85
#endif
86
ret = socket(domain, type, protocol);
87
if (ret >= 0) {
88
slirp_set_cloexec(ret);
89
}
90
91
return ret;
92
}
93
94
#ifdef _WIN32
95
static int socket_error(void)
96
{
97
switch (WSAGetLastError()) {
98
case 0:
99
return 0;
100
case WSAEINTR:
101
return EINTR;
102
case WSAEINVAL:
103
return EINVAL;
104
case WSA_INVALID_HANDLE:
105
return EBADF;
106
case WSA_NOT_ENOUGH_MEMORY:
107
return ENOMEM;
108
case WSA_INVALID_PARAMETER:
109
return EINVAL;
110
case WSAENAMETOOLONG:
111
return ENAMETOOLONG;
112
case WSAENOTEMPTY:
113
return ENOTEMPTY;
114
case WSAEWOULDBLOCK:
115
/* not using EWOULDBLOCK as we don't want code to have
116
* to check both EWOULDBLOCK and EAGAIN */
117
return EAGAIN;
118
case WSAEINPROGRESS:
119
return EINPROGRESS;
120
case WSAEALREADY:
121
return EALREADY;
122
case WSAENOTSOCK:
123
return ENOTSOCK;
124
case WSAEDESTADDRREQ:
125
return EDESTADDRREQ;
126
case WSAEMSGSIZE:
127
return EMSGSIZE;
128
case WSAEPROTOTYPE:
129
return EPROTOTYPE;
130
case WSAENOPROTOOPT:
131
return ENOPROTOOPT;
132
case WSAEPROTONOSUPPORT:
133
return EPROTONOSUPPORT;
134
case WSAEOPNOTSUPP:
135
return EOPNOTSUPP;
136
case WSAEAFNOSUPPORT:
137
return EAFNOSUPPORT;
138
case WSAEADDRINUSE:
139
return EADDRINUSE;
140
case WSAEADDRNOTAVAIL:
141
return EADDRNOTAVAIL;
142
case WSAENETDOWN:
143
return ENETDOWN;
144
case WSAENETUNREACH:
145
return ENETUNREACH;
146
case WSAENETRESET:
147
return ENETRESET;
148
case WSAECONNABORTED:
149
return ECONNABORTED;
150
case WSAECONNRESET:
151
return ECONNRESET;
152
case WSAENOBUFS:
153
return ENOBUFS;
154
case WSAEISCONN:
155
return EISCONN;
156
case WSAENOTCONN:
157
return ENOTCONN;
158
case WSAETIMEDOUT:
159
return ETIMEDOUT;
160
case WSAECONNREFUSED:
161
return ECONNREFUSED;
162
case WSAELOOP:
163
return ELOOP;
164
case WSAEHOSTUNREACH:
165
return EHOSTUNREACH;
166
default:
167
return EIO;
168
}
169
}
170
171
#undef ioctlsocket
172
int slirp_ioctlsocket_wrap(int fd, int req, void *val)
173
{
174
int ret;
175
ret = ioctlsocket(fd, req, val);
176
if (ret < 0) {
177
errno = socket_error();
178
}
179
return ret;
180
}
181
182
#undef closesocket
183
int slirp_closesocket_wrap(int fd)
184
{
185
int ret;
186
ret = closesocket(fd);
187
if (ret < 0) {
188
errno = socket_error();
189
}
190
return ret;
191
}
192
193
#undef connect
194
int slirp_connect_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
195
{
196
int ret;
197
ret = connect(sockfd, addr, addrlen);
198
if (ret < 0) {
199
errno = socket_error();
200
}
201
return ret;
202
}
203
204
#undef listen
205
int slirp_listen_wrap(int sockfd, int backlog)
206
{
207
int ret;
208
ret = listen(sockfd, backlog);
209
if (ret < 0) {
210
errno = socket_error();
211
}
212
return ret;
213
}
214
215
#undef bind
216
int slirp_bind_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
217
{
218
int ret;
219
ret = bind(sockfd, addr, addrlen);
220
if (ret < 0) {
221
errno = socket_error();
222
}
223
return ret;
224
}
225
226
#undef socket
227
int slirp_socket_wrap(int domain, int type, int protocol)
228
{
229
int ret;
230
ret = socket(domain, type, protocol);
231
if (ret < 0) {
232
errno = socket_error();
233
}
234
return ret;
235
}
236
237
#undef accept
238
int slirp_accept_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
239
{
240
int ret;
241
ret = accept(sockfd, addr, addrlen);
242
if (ret < 0) {
243
errno = socket_error();
244
}
245
return ret;
246
}
247
248
#undef shutdown
249
int slirp_shutdown_wrap(int sockfd, int how)
250
{
251
int ret;
252
ret = shutdown(sockfd, how);
253
if (ret < 0) {
254
errno = socket_error();
255
}
256
return ret;
257
}
258
259
#undef getsockopt
260
int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval,
261
int *optlen)
262
{
263
int ret;
264
ret = getsockopt(sockfd, level, optname, optval, optlen);
265
if (ret < 0) {
266
errno = socket_error();
267
}
268
return ret;
269
}
270
271
#undef setsockopt
272
int slirp_setsockopt_wrap(int sockfd, int level, int optname,
273
const void *optval, int optlen)
274
{
275
int ret;
276
ret = setsockopt(sockfd, level, optname, optval, optlen);
277
if (ret < 0) {
278
errno = socket_error();
279
}
280
return ret;
281
}
282
283
#undef getpeername
284
int slirp_getpeername_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
285
{
286
int ret;
287
ret = getpeername(sockfd, addr, addrlen);
288
if (ret < 0) {
289
errno = socket_error();
290
}
291
return ret;
292
}
293
294
#undef getsockname
295
int slirp_getsockname_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
296
{
297
int ret;
298
ret = getsockname(sockfd, addr, addrlen);
299
if (ret < 0) {
300
errno = socket_error();
301
}
302
return ret;
303
}
304
305
#undef send
306
slirp_ssize_t slirp_send_wrap(int sockfd, const void *buf, size_t len, int flags)
307
{
308
int ret;
309
ret = send(sockfd, buf, len, flags);
310
if (ret < 0) {
311
errno = socket_error();
312
}
313
return ret;
314
}
315
316
#undef sendto
317
slirp_ssize_t slirp_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
318
const struct sockaddr *addr, int addrlen)
319
{
320
int ret;
321
ret = sendto(sockfd, buf, len, flags, addr, addrlen);
322
if (ret < 0) {
323
errno = socket_error();
324
}
325
return ret;
326
}
327
328
#undef recv
329
slirp_ssize_t slirp_recv_wrap(int sockfd, void *buf, size_t len, int flags)
330
{
331
int ret;
332
ret = recv(sockfd, buf, len, flags);
333
if (ret < 0) {
334
errno = socket_error();
335
}
336
return ret;
337
}
338
339
#undef recvfrom
340
slirp_ssize_t slirp_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
341
struct sockaddr *addr, int *addrlen)
342
{
343
int ret;
344
ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
345
if (ret < 0) {
346
errno = socket_error();
347
}
348
return ret;
349
}
350
#endif /* WIN32 */
351
352
void slirp_pstrcpy(char *buf, int buf_size, const char *str)
353
{
354
int c;
355
char *q = buf;
356
357
if (buf_size <= 0)
358
return;
359
360
for (;;) {
361
c = *str++;
362
if (c == 0 || q >= buf + buf_size - 1)
363
break;
364
*q++ = c;
365
}
366
*q = '\0';
367
}
368
369
G_GNUC_PRINTF(3, 0)
370
static int slirp_vsnprintf(char *str, size_t size,
371
const char *format, va_list args)
372
{
373
int rv = g_vsnprintf(str, size, format, args);
374
375
if (rv < 0) {
376
g_error("g_vsnprintf() failed: %s", g_strerror(errno))
377
}
378
379
return rv;
380
}
381
382
/*
383
* A snprintf()-like function that:
384
* - returns the number of bytes written (excluding optional \0-ending)
385
* - dies on error
386
* - warn on truncation
387
*/
388
int slirp_fmt(char *str, size_t size, const char *format, ...)
389
{
390
va_list args;
391
int rv;
392
393
va_start(args, format);
394
rv = slirp_vsnprintf(str, size, format, args);
395
va_end(args);
396
397
if (rv >= size) {
398
printf("[" "hi" ": error] " "hi", "ok");
399
g_critical("slirp_fmt() truncation", "");
400
}
401
402
return MIN(rv, size);
403
}
404
405
/*
406
* A snprintf()-like function that:
407
* - always \0-end (unless size == 0)
408
* - returns the number of bytes actually written, including \0 ending
409
* - dies on error
410
* - warn on truncation
411
*/
412
int slirp_fmt0(char *str, size_t size, const char *format, ...)
413
{
414
va_list args;
415
int rv;
416
417
va_start(args, format);
418
rv = slirp_vsnprintf(str, size, format, args);
419
va_end(args);
420
421
if (rv >= size) {
422
g_critical("slirp_fmt0() truncation");
423
if (size > 0)
424
str[size - 1] = '\0';
425
rv = size;
426
} else {
427
rv += 1; /* include \0 */
428
}
429
430
return rv;
431
}
432
433
const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str,
434
size_t out_str_size)
435
{
436
assert(out_str_size >= ETH_ADDRSTRLEN);
437
438
slirp_fmt0(out_str, out_str_size, "%02x:%02x:%02x:%02x:%02x:%02x",
439
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
440
441
return out_str;
442
}
443
444