1 | /* SPDX-License-Identifier: MIT */
|
---|
2 | /*
|
---|
3 | * Copyright (c) 2003-2008 Fabrice Bellard
|
---|
4 | * Copyright (c) 2010-2019 Red Hat, Inc.
|
---|
5 | *
|
---|
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
7 | * of this software and associated documentation files (the "Software"), to deal
|
---|
8 | * in the Software without restriction, including without limitation the rights
|
---|
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
10 | * copies of the Software, and to permit persons to whom the Software is
|
---|
11 | * furnished to do so, subject to the following conditions:
|
---|
12 | *
|
---|
13 | * The above copyright notice and this permission notice shall be included in
|
---|
14 | * all copies or substantial portions of the Software.
|
---|
15 | *
|
---|
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
---|
22 | * THE SOFTWARE.
|
---|
23 | */
|
---|
24 | #ifndef UTIL_H_
|
---|
25 | #define UTIL_H_
|
---|
26 |
|
---|
27 | #include <glib.h>
|
---|
28 |
|
---|
29 | #include <stdlib.h>
|
---|
30 | #include <stdio.h>
|
---|
31 | #include <assert.h>
|
---|
32 | #include <errno.h>
|
---|
33 | #include <sys/types.h>
|
---|
34 | #include <sys/stat.h>
|
---|
35 | #include <inttypes.h>
|
---|
36 |
|
---|
37 | #ifdef _WIN32
|
---|
38 | #include <winsock2.h>
|
---|
39 | #include <windows.h>
|
---|
40 | #include <ws2tcpip.h>
|
---|
41 | #else
|
---|
42 | #include <unistd.h>
|
---|
43 | #include <sys/socket.h>
|
---|
44 | #include <netinet/tcp.h>
|
---|
45 | #include <netinet/in.h>
|
---|
46 | #endif
|
---|
47 |
|
---|
48 | #include "libslirp.h"
|
---|
49 |
|
---|
50 | #ifdef __GNUC__
|
---|
51 | #define SLIRP_PACKED_BEGIN
|
---|
52 | #if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
|
---|
53 | #define SLIRP_PACKED_END __attribute__((gcc_struct, packed))
|
---|
54 | #else
|
---|
55 | #define SLIRP_PACKED_END __attribute__((packed))
|
---|
56 | #endif
|
---|
57 | #elif defined(_MSC_VER)
|
---|
58 | #define SLIRP_PACKED_BEGIN __pragma(pack(push, 1))
|
---|
59 | #define SLIRP_PACKED_END __pragma(pack(pop))
|
---|
60 | #endif
|
---|
61 |
|
---|
62 | #ifndef DIV_ROUND_UP
|
---|
63 | #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
---|
64 | #endif
|
---|
65 |
|
---|
66 | #ifndef container_of
|
---|
67 | #define container_of(ptr, type, member) \
|
---|
68 | ((type *) (((char *)(ptr)) - offsetof(type, member)))
|
---|
69 | #endif
|
---|
70 |
|
---|
71 | #ifndef G_SIZEOF_MEMBER
|
---|
72 | #define G_SIZEOF_MEMBER(type, member) sizeof(((type *)0)->member)
|
---|
73 | #endif
|
---|
74 |
|
---|
75 | #if defined(_WIN32) /* CONFIG_IOVEC */
|
---|
76 | #if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */
|
---|
77 | struct iovec {
|
---|
78 | void *iov_base;
|
---|
79 | size_t iov_len;
|
---|
80 | };
|
---|
81 | #endif
|
---|
82 | #else
|
---|
83 | #include <sys/uio.h>
|
---|
84 | #endif
|
---|
85 |
|
---|
86 | #define stringify(s) tostring(s)
|
---|
87 | #define tostring(s) #s
|
---|
88 |
|
---|
89 | #define SCALE_MS 1000000
|
---|
90 |
|
---|
91 | #define ETH_ALEN 6
|
---|
92 | #define ETH_ADDRSTRLEN 18 /* "xx:xx:xx:xx:xx:xx", with trailing NUL */
|
---|
93 | #define ETH_HLEN 14
|
---|
94 | #define ETH_MINLEN 60
|
---|
95 | #define ETH_P_IP (0x0800) /* Internet Protocol packet */
|
---|
96 | #define ETH_P_ARP (0x0806) /* Address Resolution packet */
|
---|
97 | #define ETH_P_IPV6 (0x86dd)
|
---|
98 | #define ETH_P_VLAN (0x8100)
|
---|
99 | #define ETH_P_DVLAN (0x88a8)
|
---|
100 | #define ETH_P_NCSI (0x88f8)
|
---|
101 | #define ETH_P_UNKNOWN (0xffff)
|
---|
102 |
|
---|
103 | /* FIXME: remove me when made standalone */
|
---|
104 | #ifdef _WIN32
|
---|
105 | #undef accept
|
---|
106 | #undef bind
|
---|
107 | #undef closesocket
|
---|
108 | #undef connect
|
---|
109 | #undef getpeername
|
---|
110 | #undef getsockname
|
---|
111 | #undef getsockopt
|
---|
112 | #undef ioctlsocket
|
---|
113 | #undef listen
|
---|
114 | #undef recv
|
---|
115 | #undef recvfrom
|
---|
116 | #undef send
|
---|
117 | #undef sendto
|
---|
118 | #undef setsockopt
|
---|
119 | #undef shutdown
|
---|
120 | #undef socket
|
---|
121 | #endif
|
---|
122 |
|
---|
123 | #ifdef _WIN32
|
---|
124 | #define connect slirp_connect_wrap
|
---|
125 | int slirp_connect_wrap(int fd, const struct sockaddr *addr, int addrlen);
|
---|
126 | #define listen slirp_listen_wrap
|
---|
127 | int slirp_listen_wrap(int fd, int backlog);
|
---|
128 | #define bind slirp_bind_wrap
|
---|
129 | int slirp_bind_wrap(int fd, const struct sockaddr *addr, int addrlen);
|
---|
130 | #define socket slirp_socket_wrap
|
---|
131 | int slirp_socket_wrap(int domain, int type, int protocol);
|
---|
132 | #define accept slirp_accept_wrap
|
---|
133 | int slirp_accept_wrap(int fd, struct sockaddr *addr, int *addrlen);
|
---|
134 | #define shutdown slirp_shutdown_wrap
|
---|
135 | int slirp_shutdown_wrap(int fd, int how);
|
---|
136 | #define getpeername slirp_getpeername_wrap
|
---|
137 | int slirp_getpeername_wrap(int fd, struct sockaddr *addr, int *addrlen);
|
---|
138 | #define getsockname slirp_getsockname_wrap
|
---|
139 | int slirp_getsockname_wrap(int fd, struct sockaddr *addr, int *addrlen);
|
---|
140 | #define send slirp_send_wrap
|
---|
141 | slirp_ssize_t slirp_send_wrap(int fd, const void *buf, size_t len, int flags);
|
---|
142 | #define sendto slirp_sendto_wrap
|
---|
143 | slirp_ssize_t slirp_sendto_wrap(int fd, const void *buf, size_t len, int flags,
|
---|
144 | const struct sockaddr *dest_addr, int addrlen);
|
---|
145 | #define recv slirp_recv_wrap
|
---|
146 | slirp_ssize_t slirp_recv_wrap(int fd, void *buf, size_t len, int flags);
|
---|
147 | #define recvfrom slirp_recvfrom_wrap
|
---|
148 | slirp_ssize_t slirp_recvfrom_wrap(int fd, void *buf, size_t len, int flags,
|
---|
149 | struct sockaddr *src_addr, int *addrlen);
|
---|
150 | #define closesocket slirp_closesocket_wrap
|
---|
151 | int slirp_closesocket_wrap(int fd);
|
---|
152 | #define ioctlsocket slirp_ioctlsocket_wrap
|
---|
153 | int slirp_ioctlsocket_wrap(int fd, int req, void *val);
|
---|
154 | #define getsockopt slirp_getsockopt_wrap
|
---|
155 | int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval,
|
---|
156 | int *optlen);
|
---|
157 | #define setsockopt slirp_setsockopt_wrap
|
---|
158 | int slirp_setsockopt_wrap(int sockfd, int level, int optname,
|
---|
159 | const void *optval, int optlen);
|
---|
160 | #define inet_aton slirp_inet_aton
|
---|
161 | int slirp_inet_aton(const char *cp, struct in_addr *ia);
|
---|
162 | #else
|
---|
163 | #define closesocket(s) close(s)
|
---|
164 | #define ioctlsocket(s, r, v) ioctl(s, r, v)
|
---|
165 | #endif
|
---|
166 |
|
---|
167 | int slirp_socket(int domain, int type, int protocol);
|
---|
168 | void slirp_set_nonblock(int fd);
|
---|
169 |
|
---|
170 | static inline int slirp_socket_set_v6only(int fd, int v)
|
---|
171 | {
|
---|
172 | return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v));
|
---|
173 | }
|
---|
174 |
|
---|
175 | static inline int slirp_socket_set_nodelay(int fd)
|
---|
176 | {
|
---|
177 | int v = 1;
|
---|
178 | return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
|
---|
179 | }
|
---|
180 |
|
---|
181 | static inline int slirp_socket_set_fast_reuse(int fd)
|
---|
182 | {
|
---|
183 | #ifndef _WIN32
|
---|
184 | int v = 1;
|
---|
185 | return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
|
---|
186 | #else
|
---|
187 | /* Enabling the reuse of an endpoint that was used by a socket still in
|
---|
188 | * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
|
---|
189 | * fast reuse is the default and SO_REUSEADDR does strange things. So we
|
---|
190 | * don't have to do anything here. More info can be found at:
|
---|
191 | * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
|
---|
192 | return 0;
|
---|
193 | #endif
|
---|
194 | }
|
---|
195 |
|
---|
196 | void slirp_pstrcpy(char *buf, int buf_size, const char *str);
|
---|
197 |
|
---|
198 | int slirp_fmt(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4);
|
---|
199 | int slirp_fmt0(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4);
|
---|
200 |
|
---|
201 | /*
|
---|
202 | * Pretty print a MAC address into out_str.
|
---|
203 | * As a convenience returns out_str.
|
---|
204 | */
|
---|
205 | const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str,
|
---|
206 | size_t out_str_len);
|
---|
207 |
|
---|
208 | #endif
|
---|