@@ -89,7 +89,7 @@ struct ip {
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
#define IP_MAXPACKET 65535 /* maximum packet size */
@@ -151,7 +151,7 @@ struct ip_timestamp {
n_long ipt_time;
} ipt_ta[1];
} ipt_timestamp;
-} QEMU_PACKED;
+} SLIRP_PACKED;
/* flag bits for ipt_flg */
#define IPOPT_TS_TSONLY 0 /* timestamps only */
@@ -181,11 +181,11 @@ struct ip_timestamp {
struct mbuf_ptr {
struct mbuf *mptr;
uint32_t dummy;
-} QEMU_PACKED;
+} SLIRP_PACKED;
#else
struct mbuf_ptr {
struct mbuf *mptr;
-} QEMU_PACKED;
+} SLIRP_PACKED;
#endif
struct qlink {
void *next, *prev;
@@ -201,7 +201,7 @@ struct ipovly {
uint16_t ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
/*
* Ip reassembly queue structure. Each fragment
@@ -217,7 +217,7 @@ struct ipq {
uint8_t ipq_p; /* protocol of this fragment */
uint16_t ipq_id; /* sequence id for reassembly */
struct in_addr ipq_src,ipq_dst;
-} QEMU_PACKED;
+} SLIRP_PACKED;
/*
* Ip header, when holding a fragment.
@@ -227,7 +227,7 @@ struct ipq {
struct ipasfrag {
struct qlink ipf_link;
struct ip ipf_ip;
-} QEMU_PACKED;
+} SLIRP_PACKED;
#define ipf_off ipf_ip.ip_off
#define ipf_tos ipf_ip.ip_tos
@@ -7,7 +7,6 @@
#define SLIRP_IP6_H
#include <glib.h>
-#include "net/eth.h"
#define ALLNODES_MULTICAST { .s6_addr = \
{ 0xff, 0x02, 0x00, 0x00,\
@@ -133,7 +132,7 @@ struct ip6 {
uint8_t ip_nh; /* next header */
uint8_t ip_hl; /* hop limit */
struct in6_addr ip_src, ip_dst; /* source and dest address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
/*
* IPv6 pseudo-header used by upper-layer protocols
@@ -145,7 +144,7 @@ struct ip6_pseudohdr {
uint16_t ih_zero_hi; /* zero */
uint8_t ih_zero_lo; /* zero */
uint8_t ih_nh; /* next header */
-} QEMU_PACKED;
+} SLIRP_PACKED;
#endif
@@ -48,12 +48,12 @@ struct ndp_ra { /* Router Advertisement Message */
uint16_t lifetime; /* Router Lifetime */
uint32_t reach_time; /* Reachable Time */
uint32_t retrans_time; /* Retrans Timer */
-} QEMU_PACKED;
+} SLIRP_PACKED;
struct ndp_ns { /* Neighbor Solicitation Message */
uint32_t reserved;
struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
struct ndp_na { /* Neighbor Advertisement Message */
#if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -72,13 +72,13 @@ struct ndp_na { /* Neighbor Advertisement Message */
reserved_lo:24;
#endif
struct in6_addr target; /* Target Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
struct ndp_redirect {
uint32_t reserved;
struct in6_addr target; /* Target Address */
struct in6_addr dest; /* Destination Address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
/*
* Structure of an icmpv6 header.
@@ -103,7 +103,7 @@ struct icmp6 {
#define icmp6_nns icmp6_body.ndp_ns
#define icmp6_nna icmp6_body.ndp_na
#define icmp6_redirect icmp6_body.ndp_redirect
-} QEMU_PACKED;
+} SLIRP_PACKED;
#define ICMP6_MINLEN 4
#define ICMP6_ERROR_MINLEN 8
@@ -134,16 +134,16 @@ struct ndpopt {
uint32_t pref_lt; /* Preferred Lifetime */
uint32_t reserved2;
struct in6_addr prefix;
- } QEMU_PACKED prefixinfo;
+ } SLIRP_PACKED prefixinfo;
#define ndpopt_prefixinfo ndpopt_body.prefixinfo
struct rdnss {
uint16_t reserved;
uint32_t lifetime;
struct in6_addr addr;
- } QEMU_PACKED rdnss;
+ } SLIRP_PACKED rdnss;
#define ndpopt_rdnss ndpopt_body.rdnss
} ndpopt_body;
-} QEMU_PACKED;
+} SLIRP_PACKED;
/* NDP options type */
#define NDPOPT_LINKLAYER_SOURCE 1 /* Source Link-Layer Address */
@@ -1,7 +1,17 @@
#ifndef LIBSLIRP_H
#define LIBSLIRP_H
-#include "qemu-common.h"
+#include <glib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <in6addr.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
typedef struct Slirp Slirp;
new file mode 100644
@@ -0,0 +1,218 @@
+/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+
+/*
+ * slirp version: Copy from QEMU, removed all but tail queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef QTAILQ_H
+#define QTAILQ_H
+
+/*
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ */
+
+#define Q_TAILQ_HEAD(name, type, qual) \
+ struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+ }
+#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type, )
+
+#define QTAILQ_HEAD_INITIALIZER(head) \
+ { \
+ NULL, &(head).tqh_first \
+ }
+
+#define Q_TAILQ_ENTRY(type, qual) \
+ struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */ \
+ }
+#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type, )
+
+/*
+ * Tail queue functions.
+ */
+#define QTAILQ_INIT(head) \
+ do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_INSERT_HEAD(head, elm, field) \
+ do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_INSERT_TAIL(head, elm, field) \
+ do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) \
+ do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_INSERT_BEFORE(listelm, elm, field) \
+ do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_REMOVE(head, elm, field) \
+ do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ (elm)->field.tqe_prev = NULL; \
+ } while (/*CONSTCOND*/ 0)
+
+#define QTAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); (var); (var) = ((var)->field.tqe_next))
+
+#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
+ for ((var) = ((head)->tqh_first); \
+ (var) && ((next_var) = ((var)->field.tqe_next), 1); \
+ (var) = (next_var))
+
+#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+#define QTAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev_var) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var) && \
+ ((prev_var) = \
+ (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)), \
+ 1); \
+ (var) = (prev_var))
+
+/*
+ * Tail queue access methods.
+ */
+#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+#define QTAILQ_FIRST(head) ((head)->tqh_first)
+#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define QTAILQ_IN_USE(elm, field) ((elm)->field.tqe_prev != NULL)
+
+#define QTAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define QTAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define field_at_offset(base, offset, type) \
+ ((type)(((char *)(base)) + (offset)))
+
+typedef struct DUMMY_Q_ENTRY DUMMY_Q_ENTRY;
+typedef struct DUMMY_Q DUMMY_Q;
+
+struct DUMMY_Q_ENTRY {
+ QTAILQ_ENTRY(DUMMY_Q_ENTRY) next;
+};
+
+struct DUMMY_Q {
+ QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY) head;
+};
+
+#define dummy_q ((DUMMY_Q *)0)
+#define dummy_qe ((DUMMY_Q_ENTRY *)0)
+
+/*
+ * Offsets of layout of a tail queue head.
+ */
+#define QTAILQ_FIRST_OFFSET (offsetof(typeof(dummy_q->head), tqh_first))
+#define QTAILQ_LAST_OFFSET (offsetof(typeof(dummy_q->head), tqh_last))
+/*
+ * Raw access of elements of a tail queue
+ */
+#define QTAILQ_RAW_FIRST(head) \
+ (*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **))
+#define QTAILQ_RAW_TQH_LAST(head) \
+ (*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***))
+
+/*
+ * Offsets of layout of a tail queue element.
+ */
+#define QTAILQ_NEXT_OFFSET (offsetof(typeof(dummy_qe->next), tqe_next))
+#define QTAILQ_PREV_OFFSET (offsetof(typeof(dummy_qe->next), tqe_prev))
+
+/*
+ * Raw access of elements of a tail entry
+ */
+#define QTAILQ_RAW_NEXT(elm, entry) \
+ (*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **))
+#define QTAILQ_RAW_TQE_PREV(elm, entry) \
+ (*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***))
+/*
+ * Tail queue tranversal using pointer arithmetic.
+ */
+#define QTAILQ_RAW_FOREACH(elm, head, entry) \
+ for ((elm) = QTAILQ_RAW_FIRST(head); (elm); \
+ (elm) = QTAILQ_RAW_NEXT(elm, entry))
+/*
+ * Tail queue insertion using pointer arithmetic.
+ */
+#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) \
+ do { \
+ QTAILQ_RAW_NEXT(elm, entry) = NULL; \
+ QTAILQ_RAW_TQE_PREV(elm, entry) = QTAILQ_RAW_TQH_LAST(head); \
+ *QTAILQ_RAW_TQH_LAST(head) = (elm); \
+ QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry); \
+ } while (/*CONSTCOND*/ 0)
+
+#endif /* QTAILQ_H */
@@ -5,8 +5,8 @@
typedef char *caddr_t;
-# include <windows.h>
# include <winsock2.h>
+# include <windows.h>
# include <ws2tcpip.h>
# include <sys/timeb.h>
# include <iphlpapi.h>
@@ -45,10 +45,8 @@ typedef char *caddr_t;
#define quehead slirp_quehead
#include "debug.h"
-
-#include "qemu/queue.h"
-#include "qemu/sockets.h"
-#include "net/eth.h"
+#include "util.h"
+#include "qtailq.h"
#include "libslirp.h"
#include "ip.h"
@@ -93,7 +91,7 @@ struct slirp_arphdr {
uint32_t ar_sip; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
uint32_t ar_tip; /* target IP address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
#define ARP_TABLE_SIZE 16
@@ -110,7 +108,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
struct ndpentry {
unsigned char eth_addr[ETH_ALEN]; /* sender hardware address */
struct in6_addr ip_addr; /* sender IP address */
-} QEMU_PACKED;
+} SLIRP_PACKED;
#define NDP_TABLE_SIZE 16
new file mode 100644
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010-2016 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#endif
+
+#if defined(_WIN32)
+# define SLIRP_PACKED __attribute__((gcc_struct, packed))
+#else
+# define SLIRP_PACKED __attribute__((packed))
+#endif
+
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#endif
+
+#define SCALE_MS 1000000
+
+#ifndef container_of
+#define container_of(ptr, type, member) (__extension__({ \
+ const typeof(((type *) 0)->member) *__mptr = (ptr); \
+ (type *) ((char *) __mptr - offsetof(type, member));}))
+#endif
+
+#ifndef glue
+#define xglue(x, y) x ## y
+#define glue(x, y) xglue(x, y)
+#define stringify(s) tostring(s)
+#define tostring(s) #s
+#endif
+
+#if defined(_WIN32) /* CONFIG_IOVEC */
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#else
+#include <sys/uio.h>
+#endif
+
+#define ETH_ALEN 6
+#define ETH_HLEN 6
+#define ETH_P_IP (0x0800) /* Internet Protocol packet */
+#define ETH_P_ARP (0x0806) /* Address Resolution packet */
+#define ETH_P_IPV6 (0x86dd)
+#define ETH_P_VLAN (0x8100)
+#define ETH_P_DVLAN (0x88a8)
+#define ETH_P_NCSI (0x88f8)
+#define ETH_P_UNKNOWN (0xffff)
+
+#ifdef _WIN32
+int slirp_closesocket(int fd);
+int slirp_ioctlsocket(int fd, int req, void *val);
+int inet_aton(const char *cp, struct in_addr *ia);
+#define slirp_getsockopt(sockfd, level, optname, optval, optlen) \
+ getsockopt(sockfd, level, optname, (void *)optval, optlen)
+#define slirp_setsockopt(sockfd, level, optname, optval, optlen) \
+ setsockopt(sockfd, level, optname, (const void *)optval, optlen)
+#define slirp_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
+#else
+#define slirp_setsockopt setsockopt
+#define slirp_getsockopt getsockopt
+#define slirp_recv recv
+#define slirp_closesocket close
+#define slirp_ioctlsocket ioctl
+#endif
+
+int slirp_socket(int domain, int type, int protocol);
+
+static inline int socket_set_nodelay(int fd)
+{
+ int v = 1;
+ return slirp_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+}
+
+static inline int socket_set_fast_reuse(int fd)
+{
+#ifndef _WIN32
+ int v = 1;
+ return slirp_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
+#else
+ /* Enabling the reuse of an endpoint that was used by a socket still in
+ * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
+ * fast reuse is the default and SO_REUSEADDR does strange things. So we
+ * don't have to do anything here. More info can be found at:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
+ return 0;
+#endif
+}
+
+static inline void pstrcpy(char *buf, int buf_size, const char *str)
+{
+ int c;
+ char *q = buf;
+
+ if (buf_size <= 0)
+ return;
+
+ for(;;) {
+ c = *str++;
+ if (c == 0 || q >= buf + buf_size - 1)
+ break;
+ *q++ = c;
+ }
+ *q = '\0';
+}
+
+#endif
@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
@@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#if defined(_WIN32)
@@ -30,7 +30,6 @@
* in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
*/
-#include "qemu/osdep.h"
#include "slirp.h"
/*
@@ -20,8 +20,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "qemu/osdep.h"
-#include "qemu/log.h"
#include "slirp.h"
#include "dhcpv6.h"
@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
@@ -5,9 +5,7 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
-#include "qemu/timer.h"
static void
ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
@@ -3,12 +3,8 @@
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip6_icmp.h"
-#include "qemu/timer.h"
-#include "qemu/error-report.h"
-#include "qemu/log.h"
#define NDP_Interval g_rand_int_range(slirp->grand, \
NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval)
@@ -3,7 +3,6 @@
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip6_icmp.h"
@@ -3,8 +3,6 @@
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
*/
-#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "slirp.h"
/* Number of packets queued before we start sending
@@ -30,7 +30,6 @@
* ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"
@@ -79,7 +78,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
struct ip *ip = mtod(m, struct ip *);
struct sockaddr_in addr;
- so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+ so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (so->s == -1) {
return -1;
}
@@ -110,7 +109,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
void icmp_detach(struct socket *so)
{
- closesocket(so->s);
+ slirp_closesocket(so->s);
sofree(so);
}
@@ -420,7 +419,7 @@ void icmp_receive(struct socket *so)
icp = mtod(m, struct icmp *);
id = icp->icmp_id;
- len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+ len = slirp_recv(so->s, icp, M_ROOM(m), 0);
/*
* The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent
* between host OSes. On Linux, only the ICMP header and payload is
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
/* Number of packets queued before we start sending
@@ -15,7 +15,6 @@
* the flags
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#define MBUF_THRESH 30
@@ -5,11 +5,8 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "libslirp.h"
-#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
#ifdef DEBUG
int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
@@ -85,14 +82,14 @@ slirp_socketpair_with_oob(int sv[2])
int ret, s;
sv[1] = -1;
- s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+ s = slirp_socket(AF_INET, SOCK_STREAM, 0);
if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0 ||
getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
goto err;
}
- sv[1] = qemu_socket(AF_INET, SOCK_STREAM, 0);
+ sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0);
if (sv[1] < 0) {
goto err;
}
@@ -115,16 +112,16 @@ slirp_socketpair_with_oob(int sv[2])
goto err;
}
- closesocket(s);
+ slirp_closesocket(s);
return 0;
err:
g_critical("slirp_socketpair(): %s", strerror(errno));
if (s >= 0) {
- closesocket(s);
+ slirp_closesocket(s);
}
if (sv[1] >= 0) {
- closesocket(sv[1]);
+ slirp_closesocket(sv[1]);
}
return -1;
}
@@ -164,16 +161,16 @@ fork_exec(struct socket *so, const char *ex)
if (err) {
g_critical("fork_exec: %s", err->message);
g_error_free(err);
- closesocket(sp[0]);
- closesocket(sp[1]);
+ slirp_closesocket(sp[0]);
+ slirp_closesocket(sp[1]);
return 0;
}
so->s = sp[0];
- closesocket(sp[1]);
+ slirp_closesocket(sp[1]);
socket_set_fast_reuse(so->s);
opt = 1;
- qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
so->slirp->cb->set_nonblock(so->s);
return 1;
}
@@ -6,7 +6,6 @@
* This code is licensed under the GPL version 2 or later. See the
* COPYING file in the top-level directory.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ncsi-pkt.h"
@@ -3,8 +3,6 @@
* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
*/
-#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "slirp.h"
void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
@@ -5,9 +5,7 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
-#include "qemu/main-loop.h"
static void sbappendsb(struct sbuf *sb, struct mbuf *m);
@@ -21,15 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/timer.h"
-#include "qemu/error-report.h"
-#include "chardev/char-fe.h"
-#include "migration/register.h"
#include "slirp.h"
-#include "hw/hw.h"
-#include "qemu/cutils.h"
#ifdef WITH_STATE
#include "state.h"
@@ -5,8 +5,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "slirp.h"
#include "ip_icmp.h"
#ifdef __sun__
@@ -187,7 +185,7 @@ soread(struct socket *so)
*/
sopreprbuf(so, iov, &n);
- nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
+ nn = slirp_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
if (nn <= 0) {
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
return 0;
@@ -203,7 +201,7 @@ soread(struct socket *so)
if (getpeername(so->s, paddr, &alen) < 0) {
err = errno;
} else {
- getsockopt(so->s, SOL_SOCKET, SO_ERROR,
+ slirp_getsockopt(so->s, SOL_SOCKET, SO_ERROR,
&err, &elen);
}
}
@@ -232,7 +230,7 @@ soread(struct socket *so)
*/
if (n == 2 && nn == iov[0].iov_len) {
int ret;
- ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
+ ret = slirp_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
if (ret > 0)
nn += ret;
}
@@ -553,7 +551,7 @@ sorecvfrom(struct socket *so)
*/
len = M_FREEROOM(m);
/* if (so->so_fport != htons(53)) { */
- ioctlsocket(so->s, FIONREAD, &n);
+ slirp_ioctlsocket(so->s, FIONREAD, &n);
if (n > len) {
n = (m->m_data - m->m_dat) + m->m_len + n + 1;
@@ -718,14 +716,14 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
addr.sin_addr.s_addr = haddr;
addr.sin_port = hport;
- if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+ if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
(socket_set_fast_reuse(s) < 0) ||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
if (s >= 0) {
- closesocket(s);
+ slirp_closesocket(s);
}
sofree(so);
/* Restore the real errno */
@@ -736,9 +734,9 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
#endif
return NULL;
}
- qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
opt = 1;
- qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
+ slirp_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
getsockname(s,(struct sockaddr *)&addr,&addrlen);
so->so_ffamily = AF_INET;
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
static const u_char tcp_outflags[TCP_NSTATES] = {
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
/* patchable/settable parameters for tcp */
@@ -337,7 +336,7 @@ tcp_close(struct tcpcb *tp)
/* clobber input socket cache if we're closing the cached connection */
if (so == slirp->tcp_last_so)
slirp->tcp_last_so = &slirp->tcb;
- closesocket(so->s);
+ slirp_closesocket(so->s);
sbfree(&so->so_rcv);
sbfree(&so->so_snd);
sofree(so);
@@ -407,7 +406,7 @@ int tcp_fconnect(struct socket *so, unsigned short af)
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %p", so);
- ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
+ ret = so->s = slirp_socket(af, SOCK_STREAM, 0);
if (ret >= 0) {
int opt, s=so->s;
struct sockaddr_storage addr;
@@ -415,9 +414,9 @@ int tcp_fconnect(struct socket *so, unsigned short af)
so->slirp->cb->set_nonblock(s);
socket_set_fast_reuse(s);
opt = 1;
- qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+ slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
opt = 1;
- qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+ slirp_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
addr = so->fhost.ss;
DEBUG_CALL(" connect()ing");
@@ -487,7 +486,7 @@ void tcp_connect(struct socket *inso)
so->slirp->cb->set_nonblock(s);
socket_set_fast_reuse(s);
opt = 1;
- qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ slirp_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
socket_set_nodelay(s);
so->fhost.ss = addr;
@@ -496,7 +495,7 @@ void tcp_connect(struct socket *inso)
/* Close the accept() socket, set right state */
if (inso->so_state & SS_FACCEPTONCE) {
/* If we only accept once, close the accept() socket */
- closesocket(so->s);
+ slirp_closesocket(so->s);
/* Don't select it yet, even though we have an FD */
/* if it's not FACCEPTONCE, it's already NOFDREF */
@@ -30,7 +30,6 @@
* tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
*/
-#include "qemu/osdep.h"
#include "slirp.h"
static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
@@ -22,10 +22,11 @@
* THE SOFTWARE.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
-#include "qemu-common.h"
-#include "qemu/cutils.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
static inline int tftp_session_in_use(struct tftp_session *spt)
{
@@ -38,7 +38,6 @@
* terms and conditions of the copyright.
*/
-#include "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"
@@ -282,7 +281,7 @@ int udp_output(struct socket *so, struct mbuf *m,
int
udp_attach(struct socket *so, unsigned short af)
{
- so->s = qemu_socket(af, SOCK_DGRAM, 0);
+ so->s = slirp_socket(af, SOCK_DGRAM, 0);
if (so->s != -1) {
so->so_expire = curtime + SO_EXPIRE;
insque(so, &so->slirp->udb);
@@ -293,7 +292,7 @@ udp_attach(struct socket *so, unsigned short af)
void
udp_detach(struct socket *so)
{
- closesocket(so->s);
+ slirp_closesocket(so->s);
sofree(so);
}
@@ -328,7 +327,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
socklen_t addrlen = sizeof(struct sockaddr_in);
so = socreate(slirp);
- so->s = qemu_socket(AF_INET,SOCK_DGRAM,0);
+ so->s = slirp_socket(AF_INET,SOCK_DGRAM,0);
if (so->s < 0) {
sofree(so);
return NULL;
@@ -3,8 +3,6 @@
* Guillaume Subiron
*/
-#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "slirp.h"
#include "udp.h"
#include "dhcpv6.h"
new file mode 100644
@@ -0,0 +1,176 @@
+/*
+ * util.c (mostly based on QEMU os-win32.c)
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010-2016 Red Hat, Inc.
+ *
+ * QEMU library functions for win32 which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "util.h"
+
+#include <glib.h>
+#include <fcntl.h>
+#include <stdint.h>
+
+#ifdef _WIN32
+int inet_aton(const char *cp, struct in_addr *ia)
+{
+ uint32_t addr = inet_addr(cp);
+ if (addr == 0xffffffff) {
+ return 0;
+ }
+ ia->s_addr = addr;
+ return 1;
+}
+#endif
+
+static void slirp_set_cloexec(int fd)
+{
+#ifndef _WIN32
+ int f;
+ f = fcntl(fd, F_GETFD);
+ assert(f != -1);
+ f = fcntl(fd, F_SETFD, f | FD_CLOEXEC);
+ assert(f != -1);
+#endif
+}
+
+/*
+ * Opens a socket with FD_CLOEXEC set
+ */
+int slirp_socket(int domain, int type, int protocol)
+{
+ int ret;
+
+#ifdef SOCK_CLOEXEC
+ ret = socket(domain, type | SOCK_CLOEXEC, protocol);
+ if (ret != -1 || errno != EINVAL) {
+ return ret;
+ }
+#endif
+ ret = socket(domain, type, protocol);
+ if (ret >= 0) {
+ slirp_set_cloexec(ret);
+ }
+
+ return ret;
+}
+
+#ifdef _WIN32
+static int socket_error(void)
+{
+ switch (WSAGetLastError()) {
+ case 0:
+ return 0;
+ case WSAEINTR:
+ return EINTR;
+ case WSAEINVAL:
+ return EINVAL;
+ case WSA_INVALID_HANDLE:
+ return EBADF;
+ case WSA_NOT_ENOUGH_MEMORY:
+ return ENOMEM;
+ case WSA_INVALID_PARAMETER:
+ return EINVAL;
+ case WSAENAMETOOLONG:
+ return ENAMETOOLONG;
+ case WSAENOTEMPTY:
+ return ENOTEMPTY;
+ case WSAEWOULDBLOCK:
+ /* not using EWOULDBLOCK as we don't want code to have
+ * to check both EWOULDBLOCK and EAGAIN */
+ return EAGAIN;
+ case WSAEINPROGRESS:
+ return EINPROGRESS;
+ case WSAEALREADY:
+ return EALREADY;
+ case WSAENOTSOCK:
+ return ENOTSOCK;
+ case WSAEDESTADDRREQ:
+ return EDESTADDRREQ;
+ case WSAEMSGSIZE:
+ return EMSGSIZE;
+ case WSAEPROTOTYPE:
+ return EPROTOTYPE;
+ case WSAENOPROTOOPT:
+ return ENOPROTOOPT;
+ case WSAEPROTONOSUPPORT:
+ return EPROTONOSUPPORT;
+ case WSAEOPNOTSUPP:
+ return EOPNOTSUPP;
+ case WSAEAFNOSUPPORT:
+ return EAFNOSUPPORT;
+ case WSAEADDRINUSE:
+ return EADDRINUSE;
+ case WSAEADDRNOTAVAIL:
+ return EADDRNOTAVAIL;
+ case WSAENETDOWN:
+ return ENETDOWN;
+ case WSAENETUNREACH:
+ return ENETUNREACH;
+ case WSAENETRESET:
+ return ENETRESET;
+ case WSAECONNABORTED:
+ return ECONNABORTED;
+ case WSAECONNRESET:
+ return ECONNRESET;
+ case WSAENOBUFS:
+ return ENOBUFS;
+ case WSAEISCONN:
+ return EISCONN;
+ case WSAENOTCONN:
+ return ENOTCONN;
+ case WSAETIMEDOUT:
+ return ETIMEDOUT;
+ case WSAECONNREFUSED:
+ return ECONNREFUSED;
+ case WSAELOOP:
+ return ELOOP;
+ case WSAEHOSTUNREACH:
+ return EHOSTUNREACH;
+ default:
+ return EIO;
+ }
+}
+
+#undef ioctlsocket
+int slirp_ioctlsocket(int fd, int req, void *val)
+{
+ int ret;
+ ret = ioctlsocket(fd, req, val);
+ if (ret < 0) {
+ errno = socket_error();
+ }
+ return ret;
+}
+
+#undef closesocket
+int slirp_closesocket(int fd)
+{
+ int ret;
+ ret = closesocket(fd);
+ if (ret < 0) {
+ errno = socket_error();
+ }
+ return ret;
+}
+#endif /* WIN32 */
@@ -2,6 +2,6 @@ common-obj-y = cksum.o if.o ip_icmp.o ip6_icmp.o ip6_input.o ip6_output.o \
ip_input.o ip_output.o dnssearch.o dhcpv6.o
common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
common-obj-y += tcp_subr.o tcp_timer.o udp.o udp6.o bootp.o tftp.o arp_table.o \
- ndp_table.o ncsi.o state.o
+ ndp_table.o ncsi.o state.o util.o
slirp.o-cflags := -DWITH_STATE=1
Introduce utility header/object, and replace remaining qemu functions with SLIRP helpers. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- slirp/ip.h | 14 +-- slirp/ip6.h | 5 +- slirp/ip6_icmp.h | 16 ++-- slirp/libslirp.h | 12 ++- slirp/qtailq.h | 218 ++++++++++++++++++++++++++++++++++++++++++++ slirp/slirp.h | 12 +-- slirp/util.h | 145 +++++++++++++++++++++++++++++ slirp/arp_table.c | 1 - slirp/bootp.c | 1 - slirp/cksum.c | 1 - slirp/dhcpv6.c | 2 - slirp/dnssearch.c | 1 - slirp/if.c | 2 - slirp/ip6_icmp.c | 4 - slirp/ip6_input.c | 1 - slirp/ip6_output.c | 2 - slirp/ip_icmp.c | 7 +- slirp/ip_input.c | 1 - slirp/ip_output.c | 1 - slirp/mbuf.c | 1 - slirp/misc.c | 21 ++--- slirp/ncsi.c | 1 - slirp/ndp_table.c | 2 - slirp/sbuf.c | 2 - slirp/slirp.c | 8 -- slirp/socket.c | 18 ++-- slirp/tcp_input.c | 1 - slirp/tcp_output.c | 1 - slirp/tcp_subr.c | 13 ++- slirp/tcp_timer.c | 1 - slirp/tftp.c | 7 +- slirp/udp.c | 7 +- slirp/udp6.c | 2 - slirp/util.c | 176 +++++++++++++++++++++++++++++++++++ slirp/Makefile.objs | 2 +- 35 files changed, 606 insertions(+), 103 deletions(-) create mode 100644 slirp/qtailq.h create mode 100644 slirp/util.h create mode 100644 slirp/util.c