2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * DANNY GASPAROVSKI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/types.h>
42 typedef SSIZE_T slirp_ssize_t;
43 #ifdef BUILDING_LIBSLIRP
44 # define SLIRP_EXPORT __declspec(dllexport)
46 # define SLIRP_EXPORT __declspec(dllimport)
49 #include <sys/types.h>
50 typedef ssize_t slirp_ssize_t;
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
60 /* Opaque structure containing the slirp state */
61 typedef struct Slirp Slirp;
63 /* Flags passed to SlirpAddPollCb and to be returned by SlirpGetREventsCb. */
65 SLIRP_POLL_IN = 1 << 0,
66 SLIRP_POLL_OUT = 1 << 1,
67 SLIRP_POLL_PRI = 1 << 2,
68 SLIRP_POLL_ERR = 1 << 3,
69 SLIRP_POLL_HUP = 1 << 4,
72 /* Callback for application to get data from the guest */
73 typedef slirp_ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
74 /* Callback for application to send data to the guest */
75 typedef slirp_ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
77 typedef void (*SlirpTimerCb)(void *opaque);
78 /* Callback for libslirp to register polling callbacks */
79 typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
80 /* Callback for libslirp to get polling result */
81 typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
83 /* For now libslirp creates only a timer for the IPv6 RA */
84 typedef enum SlirpTimerId {
90 * Callbacks from slirp, to be set by the application.
92 * The opaque parameter is set to the opaque pointer given in the slirp_new /
95 typedef struct SlirpCb {
97 * Send an ethernet frame to the guest network. The opaque parameter is the
98 * one given to slirp_init(). If the guest is not ready to receive a frame,
99 * the function can just drop the data. TCP will then handle retransmissions
101 * <0 reports an IO error.
103 SlirpWriteCb send_packet;
104 /* Print a message for an error due to guest misbehavior. */
105 void (*guest_error)(const char *msg, void *opaque);
106 /* Return the virtual clock value in nanoseconds */
107 int64_t (*clock_get_ns)(void *opaque);
108 /* Create a new timer with the given callback and opaque data. Not
109 * needed if timer_new_opaque is provided. */
110 void *(*timer_new)(SlirpTimerCb cb, void *cb_opaque, void *opaque);
111 /* Remove and free a timer */
112 void (*timer_free)(void *timer, void *opaque);
113 /* Modify a timer to expire at @expire_time (ms) */
114 void (*timer_mod)(void *timer, int64_t expire_time, void *opaque);
115 /* Register a fd for future polling */
116 void (*register_poll_fd)(int fd, void *opaque);
117 /* Unregister a fd */
118 void (*unregister_poll_fd)(int fd, void *opaque);
119 /* Kick the io-thread, to signal that new events may be processed because some TCP buffer
120 * can now receive more data, i.e. slirp_socket_can_recv will return 1. */
121 void (*notify)(void *opaque);
124 * Fields introduced in SlirpConfig version 4 begin
127 /* Initialization has completed and a Slirp* has been created. */
128 void (*init_completed)(Slirp *slirp, void *opaque);
129 /* Create a new timer. When the timer fires, the application passes
130 * the SlirpTimerId and cb_opaque to slirp_handle_timer. */
131 void *(*timer_new_opaque)(SlirpTimerId id, void *cb_opaque, void *opaque);
134 #define SLIRP_CONFIG_VERSION_MIN 1
135 #define SLIRP_CONFIG_VERSION_MAX 5
137 typedef struct SlirpConfig {
138 /* Version must be provided */
141 * Fields introduced in SlirpConfig version 1 begin
143 /* Whether to prevent the guest from accessing the Internet */
145 /* Whether IPv4 is enabled */
147 /* Virtual network for the guest */
148 struct in_addr vnetwork;
149 /* Mask for the virtual network for the guest */
150 struct in_addr vnetmask;
151 /* Virtual address for the host exposed to the guest */
152 struct in_addr vhost;
153 /* Whether IPv6 is enabled */
155 /* Virtual IPv6 network for the guest */
156 struct in6_addr vprefix_addr6;
157 /* Len of the virtual IPv6 network for the guest */
159 /* Virtual address for the host exposed to the guest */
160 struct in6_addr vhost6;
161 /* Hostname exposed to the guest in DHCP hostname option */
162 const char *vhostname;
163 /* Hostname exposed to the guest in the DHCP TFTP server name option */
164 const char *tftp_server_name;
165 /* Path of the files served by TFTP */
166 const char *tftp_path;
167 /* Boot file name exposed to the guest via DHCP */
168 const char *bootfile;
169 /* Start of the DHCP range */
170 struct in_addr vdhcp_start;
171 /* Virtual address for the DNS server exposed to the guest */
172 struct in_addr vnameserver;
173 /* Virtual IPv6 address for the DNS server exposed to the guest */
174 struct in6_addr vnameserver6;
175 /* DNS search names exposed to the guest via DHCP */
176 const char **vdnssearch;
177 /* Domain name exposed to the guest via DHCP */
178 const char *vdomainname;
179 /* MTU when sending packets to the guest */
180 /* Default: IF_MTU_DEFAULT */
182 /* MRU when receiving packets from the guest */
183 /* Default: IF_MRU_DEFAULT */
185 /* Prohibit connecting to 127.0.0.1:* */
186 bool disable_host_loopback;
188 * Enable emulation code (*warning*: this code isn't safe, it is not
189 * recommended to enable it)
194 * Fields introduced in SlirpConfig version 2 begin
196 /* Address to be used when sending data to the Internet */
197 struct sockaddr_in *outbound_addr;
198 /* IPv6 Address to be used when sending data to the Internet */
199 struct sockaddr_in6 *outbound_addr6;
202 * Fields introduced in SlirpConfig version 3 begin
204 /* slirp will not redirect/serve any DNS packet */
208 * Fields introduced in SlirpConfig version 4 begin
210 /* slirp will not reply to any DHCP requests */
214 * Fields introduced in SlirpConfig version 5 begin
216 /* Manufacturer ID (IANA Private Enterprise number) */
219 * MAC address allocated for an out-of-band management controller, to be
220 * retrieved through NC-SI.
222 uint8_t oob_eth_addr[6];
225 /* Create a new instance of a slirp stack */
227 Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks,
229 /* slirp_init is deprecated in favor of slirp_new */
231 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
232 struct in_addr vnetmask, struct in_addr vhost,
233 bool in6_enabled, struct in6_addr vprefix_addr6,
234 uint8_t vprefix_len, struct in6_addr vhost6,
235 const char *vhostname, const char *tftp_server_name,
236 const char *tftp_path, const char *bootfile,
237 struct in_addr vdhcp_start, struct in_addr vnameserver,
238 struct in6_addr vnameserver6, const char **vdnssearch,
239 const char *vdomainname, const SlirpCb *callbacks,
241 /* Shut down an instance of a slirp stack */
243 void slirp_cleanup(Slirp *slirp);
245 /* This is called by the application when it is about to sleep through poll().
246 * *timeout is set to the amount of virtual time (in ms) that the application intends to
247 * wait (UINT32_MAX if infinite). slirp_pollfds_fill updates it according to
248 * e.g. TCP timers, so the application knows it should sleep a smaller amount of
249 * time. slirp_pollfds_fill calls add_poll for each file descriptor
250 * that should be monitored along the sleep. The opaque pointer is passed as
251 * such to add_poll, and add_poll returns an index. */
253 void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
254 SlirpAddPollCb add_poll, void *opaque);
256 /* This is called by the application after sleeping, to report which file
257 * descriptors are available. slirp_pollfds_poll calls get_revents on each file
258 * descriptor, giving it the index that add_poll returned during the
259 * slirp_pollfds_fill call, to know whether the descriptor is available for
260 * read/write/etc. (SLIRP_POLL_*)
261 * select_error should be passed 1 if poll() returned an error. */
263 void slirp_pollfds_poll(Slirp *slirp, int select_error,
264 SlirpGetREventsCb get_revents, void *opaque);
266 /* This is called by the application when the guest emits a packet on the
267 * guest network, to be interpreted by slirp. */
269 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
271 /* This is called by the application when a timer expires, if it provides
272 * the timer_new_opaque callback. It is not needed if the application only
275 void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque);
277 /* These set up / remove port forwarding between a host port in the real world
278 * and the guest network. */
280 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
281 int host_port, struct in_addr guest_addr, int guest_port);
283 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
286 #define SLIRP_HOSTFWD_UDP 1
287 #define SLIRP_HOSTFWD_V6ONLY 2
289 int slirp_add_hostxfwd(Slirp *slirp,
290 const struct sockaddr *haddr, socklen_t haddrlen,
291 const struct sockaddr *gaddr, socklen_t gaddrlen,
294 int slirp_remove_hostxfwd(Slirp *slirp,
295 const struct sockaddr *haddr, socklen_t haddrlen,
298 /* Set up port forwarding between a port in the guest network and a
299 * command running on the host */
301 int slirp_add_exec(Slirp *slirp, const char *cmdline,
302 struct in_addr *guest_addr, int guest_port);
303 /* Set up port forwarding between a port in the guest network and a
304 * Unix port on the host */
306 int slirp_add_unix(Slirp *slirp, const char *unixsock,
307 struct in_addr *guest_addr, int guest_port);
308 /* Set up port forwarding between a port in the guest network and a
309 * callback that will receive the data coming from the port */
311 int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
312 struct in_addr *guest_addr, int guest_port);
314 /* TODO: rather identify a guestfwd through an opaque pointer instead of through
317 /* This is called by the application for a guestfwd, to determine how much data
318 * can be received by the forwarded port through a call to slirp_socket_recv. */
320 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
322 /* This is called by the application for a guestfwd, to provide the data to be
323 * sent on the forwarded port */
325 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
326 const uint8_t *buf, int size);
328 /* Remove entries added by slirp_add_exec, slirp_add_unix or slirp_add_guestfwd */
330 int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr,
333 /* Return a human-readable state of the slirp stack */
335 char *slirp_connection_info(Slirp *slirp);
337 /* Return a human-readable state of the NDP/ARP tables */
339 char *slirp_neighbor_info(Slirp *slirp);
341 /* Save the slirp state through the write_cb. The opaque pointer is passed as
342 * such to the write_cb. */
344 int slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque);
346 /* Returns the version of the slirp state, to be saved along the state */
348 int slirp_state_version(void);
350 /* Load the slirp state through the read_cb. The opaque pointer is passed as
351 * such to the read_cb. The version should be given as it was obtained from
352 * slirp_state_version when slirp_state_save was called. */
354 int slirp_state_load(Slirp *s, int version_id, SlirpReadCb read_cb,
357 /* Return the version of the slirp implementation */
359 const char *slirp_version_string(void);
365 #endif /* LIBSLIRP_H */