diff mbox series

[v2,for-3.2,v2,29/30] slirp: replace remaining QEMU dependency

Message ID 20181121220647.18844-30-marcandre.lureau@redhat.com
State New
Headers show
Series slirp: make it again a standalone project | expand

Commit Message

Marc-André Lureau Nov. 21, 2018, 10:06 p.m. UTC
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        | 148 ++++++++++++++++++++++++++++++
 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       |   7 --
 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 |   1 +
 35 files changed, 609 insertions(+), 101 deletions(-)
 create mode 100644 slirp/qtailq.h
 create mode 100644 slirp/util.h
 create mode 100644 slirp/util.c

Comments

Marc-André Lureau Dec. 6, 2018, 12:03 p.m. UTC | #1
Hi

On Thu, Nov 22, 2018 at 2:38 AM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Introduce utility header/object, and replace remaining qemu functions
> with SLIRP helpers.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

self-nack,

not only this patch deserves to be split, but it also introduces regression.


> ---
>  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        | 148 ++++++++++++++++++++++++++++++
>  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       |   7 --
>  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 |   1 +
>  35 files changed, 609 insertions(+), 101 deletions(-)
>  create mode 100644 slirp/qtailq.h
>  create mode 100644 slirp/util.h
>  create mode 100644 slirp/util.c
>
> diff --git a/slirp/ip.h b/slirp/ip.h
> index 243b6c8b24..cd6ddf2bb7 100644
> --- a/slirp/ip.h
> +++ b/slirp/ip.h
> @@ -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
> diff --git a/slirp/ip6.h b/slirp/ip6.h
> index 14e9c78735..e0a13dec1c 100644
> --- a/slirp/ip6.h
> +++ b/slirp/ip6.h
> @@ -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
> diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
> index 32b0914055..1f09b485e3 100644
> --- a/slirp/ip6_icmp.h
> +++ b/slirp/ip6_icmp.h
> @@ -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 */
> diff --git a/slirp/libslirp.h b/slirp/libslirp.h
> index f2d71bd1f6..2c90738f89 100644
> --- a/slirp/libslirp.h
> +++ b/slirp/libslirp.h
> @@ -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;
>
> diff --git a/slirp/qtailq.h b/slirp/qtailq.h
> new file mode 100644
> index 0000000000..7c1d73a5bd
> --- /dev/null
> +++ b/slirp/qtailq.h
> @@ -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 */
> diff --git a/slirp/slirp.h b/slirp/slirp.h
> index 6e7a663b6f..08ec331ee5 100644
> --- a/slirp/slirp.h
> +++ b/slirp/slirp.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
>
> diff --git a/slirp/util.h b/slirp/util.h
> new file mode 100644
> index 0000000000..daf652d3e6
> --- /dev/null
> +++ b/slirp/util.h
> @@ -0,0 +1,148 @@
> +/*
> + * 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>
> +#include <inttypes.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 */
> +# if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */
> +struct iovec {
> +    void *iov_base;
> +    size_t iov_len;
> +};
> +# endif
> +#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
> diff --git a/slirp/arp_table.c b/slirp/arp_table.c
> index bf71b984ad..8ea655f79d 100644
> --- a/slirp/arp_table.c
> +++ b/slirp/arp_table.c
> @@ -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])
> diff --git a/slirp/bootp.c b/slirp/bootp.c
> index 4c9a77eb98..d396849a05 100644
> --- a/slirp/bootp.c
> +++ b/slirp/bootp.c
> @@ -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)
> diff --git a/slirp/cksum.c b/slirp/cksum.c
> index 84c858fafb..25bfa67348 100644
> --- a/slirp/cksum.c
> +++ b/slirp/cksum.c
> @@ -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"
>
>  /*
> diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
> index 752df40536..9ffba38e8f 100644
> --- a/slirp/dhcpv6.c
> +++ b/slirp/dhcpv6.c
> @@ -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"
>
> diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
> index 8fb563321b..c459cece8d 100644
> --- a/slirp/dnssearch.c
> +++ b/slirp/dnssearch.c
> @@ -22,7 +22,6 @@
>   * THE SOFTWARE.
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>
>  static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
> diff --git a/slirp/if.c b/slirp/if.c
> index 73e3705740..2ad03b8a79 100644
> --- a/slirp/if.c
> +++ b/slirp/if.c
> @@ -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)
> diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
> index e72c57a81d..2a432ebbd4 100644
> --- a/slirp/ip6_icmp.c
> +++ b/slirp/ip6_icmp.c
> @@ -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)
> diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
> index ab656a0a9d..1b8c003c66 100644
> --- a/slirp/ip6_input.c
> +++ b/slirp/ip6_input.c
> @@ -3,7 +3,6 @@
>   * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>  #include "ip6_icmp.h"
>
> diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
> index 52c88ad691..19d1ae7748 100644
> --- a/slirp/ip6_output.c
> +++ b/slirp/ip6_output.c
> @@ -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
> diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
> index 7c7e042049..e2e673ceaa 100644
> --- a/slirp/ip_icmp.c
> +++ b/slirp/ip_icmp.c
> @@ -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"
>
> @@ -83,7 +82,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;
>      }
> @@ -114,7 +113,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);
>  }
>
> @@ -421,7 +420,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
> diff --git a/slirp/ip_input.c b/slirp/ip_input.c
> index 6831526320..cfda30fccd 100644
> --- a/slirp/ip_input.c
> +++ b/slirp/ip_input.c
> @@ -38,7 +38,6 @@
>   * terms and conditions of the copyright.
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>  #include "ip_icmp.h"
>
> diff --git a/slirp/ip_output.c b/slirp/ip_output.c
> index db403f04c1..f6ec141df5 100644
> --- a/slirp/ip_output.c
> +++ b/slirp/ip_output.c
> @@ -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
> diff --git a/slirp/mbuf.c b/slirp/mbuf.c
> index d8d275e0e7..521c02c967 100644
> --- a/slirp/mbuf.c
> +++ b/slirp/mbuf.c
> @@ -15,7 +15,6 @@
>   * the flags
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>
>  #define MBUF_THRESH 30
> diff --git a/slirp/misc.c b/slirp/misc.c
> index 7789cefefa..5b1c526f17 100644
> --- a/slirp/misc.c
> +++ b/slirp/misc.c
> @@ -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"
>
>  inline void
>  insque(void *a, void *b)
> @@ -83,14 +80,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;
>      }
> @@ -113,16 +110,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;
>  }
> @@ -162,16 +159,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;
>  }
> diff --git a/slirp/ncsi.c b/slirp/ncsi.c
> index 8594382270..327f17543c 100644
> --- a/slirp/ncsi.c
> +++ b/slirp/ncsi.c
> @@ -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"
> diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
> index b7b73722f7..34ea4fdf1f 100644
> --- a/slirp/ndp_table.c
> +++ b/slirp/ndp_table.c
> @@ -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,
> diff --git a/slirp/sbuf.c b/slirp/sbuf.c
> index 17f28e97a6..51a9f0cc7d 100644
> --- a/slirp/sbuf.c
> +++ b/slirp/sbuf.c
> @@ -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);
>
> diff --git a/slirp/slirp.c b/slirp/slirp.c
> index a1f42c8b19..39c0370e19 100644
> --- a/slirp/slirp.c
> +++ b/slirp/slirp.c
> @@ -21,14 +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 "migration/register.h"
>  #include "slirp.h"
> -#include "hw/hw.h"
> -#include "qemu/cutils.h"
>
>  #ifdef WITH_QEMU
>  #include "state.h"
> diff --git a/slirp/socket.c b/slirp/socket.c
> index 4d5be38747..7ae88b8e87 100644
> --- a/slirp/socket.c
> +++ b/slirp/socket.c
> @@ -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);
>                                 }
>                         }
> @@ -233,7 +231,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;
>          }
> @@ -554,7 +552,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;
> @@ -719,14 +717,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 */
> @@ -737,9 +735,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;
> diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
> index f205a1e6cb..3cd6277672 100644
> --- a/slirp/tcp_input.c
> +++ b/slirp/tcp_input.c
> @@ -38,7 +38,6 @@
>   * terms and conditions of the copyright.
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>  #include "ip_icmp.h"
>
> diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
> index 2f7f90d67e..f02b94b8f0 100644
> --- a/slirp/tcp_output.c
> +++ b/slirp/tcp_output.c
> @@ -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] = {
> diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
> index 3b15148187..4e486093c0 100644
> --- a/slirp/tcp_subr.c
> +++ b/slirp/tcp_subr.c
> @@ -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 */
> diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
> index d953a16386..ebc9d16f06 100644
> --- a/slirp/tcp_timer.c
> +++ b/slirp/tcp_timer.c
> @@ -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);
> diff --git a/slirp/tftp.c b/slirp/tftp.c
> index 6fb381ef33..eae7f7c7f2 100644
> --- a/slirp/tftp.c
> +++ b/slirp/tftp.c
> @@ -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)
>  {
> diff --git a/slirp/udp.c b/slirp/udp.c
> index 4cf0d34d64..e49a8862d4 100644
> --- a/slirp/udp.c
> +++ b/slirp/udp.c
> @@ -38,7 +38,6 @@
>   * terms and conditions of the copyright.
>   */
>
> -#include "qemu/osdep.h"
>  #include "slirp.h"
>  #include "ip_icmp.h"
>
> @@ -281,7 +280,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);
> @@ -292,7 +291,7 @@ udp_attach(struct socket *so, unsigned short af)
>  void
>  udp_detach(struct socket *so)
>  {
> -       closesocket(so->s);
> +       slirp_closesocket(so->s);
>         sofree(so);
>  }
>
> @@ -327,7 +326,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;
> diff --git a/slirp/udp6.c b/slirp/udp6.c
> index fa531e03c4..be5cba1f54 100644
> --- a/slirp/udp6.c
> +++ b/slirp/udp6.c
> @@ -3,8 +3,6 @@
>   * Guillaume Subiron
>   */
>
> -#include "qemu/osdep.h"
> -#include "qemu-common.h"
>  #include "slirp.h"
>  #include "udp.h"
>  #include "dhcpv6.h"
> diff --git a/slirp/util.c b/slirp/util.c
> new file mode 100644
> index 0000000000..b1a36b27bc
> --- /dev/null
> +++ b/slirp/util.c
> @@ -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>
> +
> +#if defined(_WIN32) && !defined(WITH_QEMU)
> +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 */
> diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
> index 7abc7549ab..61cdcc6877 100644
> --- a/slirp/Makefile.objs
> +++ b/slirp/Makefile.objs
> @@ -28,6 +28,7 @@ slirp.mo-objs = \
>         tftp.o \
>         udp.o \
>         udp6.o \
> +       util.o \
>         $(NULL)
>
>  slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU=1
> --
> 2.20.0.rc1
>
>
diff mbox series

Patch

diff --git a/slirp/ip.h b/slirp/ip.h
index 243b6c8b24..cd6ddf2bb7 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -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
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 14e9c78735..e0a13dec1c 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -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
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index 32b0914055..1f09b485e3 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -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 */
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index f2d71bd1f6..2c90738f89 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -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;
 
diff --git a/slirp/qtailq.h b/slirp/qtailq.h
new file mode 100644
index 0000000000..7c1d73a5bd
--- /dev/null
+++ b/slirp/qtailq.h
@@ -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 */
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 6e7a663b6f..08ec331ee5 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.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
 
diff --git a/slirp/util.h b/slirp/util.h
new file mode 100644
index 0000000000..daf652d3e6
--- /dev/null
+++ b/slirp/util.h
@@ -0,0 +1,148 @@ 
+/*
+ * 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>
+#include <inttypes.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 */
+# if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */
+struct iovec {
+    void *iov_base;
+    size_t iov_len;
+};
+# endif
+#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
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf71b984ad..8ea655f79d 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -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])
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 4c9a77eb98..d396849a05 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -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)
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 84c858fafb..25bfa67348 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -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"
 
 /*
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 752df40536..9ffba38e8f 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -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"
 
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 8fb563321b..c459cece8d 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -22,7 +22,6 @@ 
  * THE SOFTWARE.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
diff --git a/slirp/if.c b/slirp/if.c
index 73e3705740..2ad03b8a79 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -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)
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index e72c57a81d..2a432ebbd4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -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)
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ab656a0a9d..1b8c003c66 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -3,7 +3,6 @@ 
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip6_icmp.h"
 
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 52c88ad691..19d1ae7748 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -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
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 7c7e042049..e2e673ceaa 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -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"
 
@@ -83,7 +82,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;
     }
@@ -114,7 +113,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);
 }
 
@@ -421,7 +420,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
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 6831526320..cfda30fccd 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -38,7 +38,6 @@ 
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index db403f04c1..f6ec141df5 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -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
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index d8d275e0e7..521c02c967 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -15,7 +15,6 @@ 
  * the flags
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 
 #define MBUF_THRESH 30
diff --git a/slirp/misc.c b/slirp/misc.c
index 7789cefefa..5b1c526f17 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -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"
 
 inline void
 insque(void *a, void *b)
@@ -83,14 +80,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;
     }
@@ -113,16 +110,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;
 }
@@ -162,16 +159,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;
 }
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 8594382270..327f17543c 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -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"
diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
index b7b73722f7..34ea4fdf1f 100644
--- a/slirp/ndp_table.c
+++ b/slirp/ndp_table.c
@@ -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,
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 17f28e97a6..51a9f0cc7d 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -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);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index a1f42c8b19..39c0370e19 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -21,14 +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 "migration/register.h"
 #include "slirp.h"
-#include "hw/hw.h"
-#include "qemu/cutils.h"
 
 #ifdef WITH_QEMU
 #include "state.h"
diff --git a/slirp/socket.c b/slirp/socket.c
index 4d5be38747..7ae88b8e87 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -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);
 				}
 			}
@@ -233,7 +231,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;
         }
@@ -554,7 +552,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;
@@ -719,14 +717,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 */
@@ -737,9 +735,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;
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index f205a1e6cb..3cd6277672 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -38,7 +38,6 @@ 
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 2f7f90d67e..f02b94b8f0 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -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] = {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 3b15148187..4e486093c0 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -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 */
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index d953a16386..ebc9d16f06 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -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);
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 6fb381ef33..eae7f7c7f2 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -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)
 {
diff --git a/slirp/udp.c b/slirp/udp.c
index 4cf0d34d64..e49a8862d4 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -38,7 +38,6 @@ 
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
 #include "ip_icmp.h"
 
@@ -281,7 +280,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);
@@ -292,7 +291,7 @@  udp_attach(struct socket *so, unsigned short af)
 void
 udp_detach(struct socket *so)
 {
-	closesocket(so->s);
+	slirp_closesocket(so->s);
 	sofree(so);
 }
 
@@ -327,7 +326,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;
diff --git a/slirp/udp6.c b/slirp/udp6.c
index fa531e03c4..be5cba1f54 100644
--- a/slirp/udp6.c
+++ b/slirp/udp6.c
@@ -3,8 +3,6 @@ 
  * Guillaume Subiron
  */
 
-#include "qemu/osdep.h"
-#include "qemu-common.h"
 #include "slirp.h"
 #include "udp.h"
 #include "dhcpv6.h"
diff --git a/slirp/util.c b/slirp/util.c
new file mode 100644
index 0000000000..b1a36b27bc
--- /dev/null
+++ b/slirp/util.c
@@ -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>
+
+#if defined(_WIN32) && !defined(WITH_QEMU)
+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 */
diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 7abc7549ab..61cdcc6877 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -28,6 +28,7 @@  slirp.mo-objs = \
 	tftp.o \
 	udp.o \
 	udp6.o \
+	util.o \
 	$(NULL)
 
 slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU=1