/*
 * libslirp glue
 *
 * Copyright (c) 2004-2008 Fabrice Bellard
 *
 * 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 "qemu-common.h"
#include "sysemu/char.h"
#include "slirp.h"
#include "proxy_common.h"
#include "hw/hw.h"

#include "android/utils/debug.h"  /* for dprint */
#include "android/utils/bufprint.h"
#include "android/android.h"
#include "android/sockets.h"

#include "qemu/queue.h"

/* proto types */
static void slirp_net_forward_init(void);


#define  D(...)   VERBOSE_PRINT(slirp,__VA_ARGS__)
#define  DN(...)  do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)

/* host address */
uint32_t our_addr_ip;
/* host dns address */
uint32_t dns_addr[DNS_ADDR_MAX];
int      dns_addr_count;

/* host loopback address */
uint32_t loopback_addr_ip;

/* address for slirp virtual addresses */
uint32_t  special_addr_ip;

/* virtual address alias for host */
uint32_t alias_addr_ip;

static const uint8_t special_ethaddr[6] = {
    0x52, 0x54, 0x00, 0x12, 0x35, 0x00
};

/* ARP cache for the guest IP addresses (XXX: allow many entries) */
uint8_t client_ethaddr[6];
static ipaddr_t  client_ip;

static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };

const char *slirp_special_ip = CTL_SPECIAL;
int slirp_restrict;
static int do_slowtimo;
int link_up;
struct timeval tt;
FILE *lfd;
struct ex_list *exec_list;

/* XXX: suppress those select globals */
fd_set *global_readfds, *global_writefds, *global_xfds;

char slirp_hostname[33];

int slirp_add_dns_server(const SockAddress*  new_dns_addr)
{
    int   dns_ip;

    if (dns_addr_count >= DNS_ADDR_MAX)
        return -1;

    dns_ip = sock_address_get_ip(new_dns_addr);
    if (dns_ip == -1)
        return -1;

    dns_addr[dns_addr_count++] = dns_ip;
    return 0;
}


#ifdef _WIN32

int slirp_get_system_dns_servers(void)
{
    FIXED_INFO *FixedInfo=NULL;
    ULONG    BufLen;
    DWORD    ret;
    IP_ADDR_STRING *pIPAddr;

    if (dns_addr_count > 0)
        return dns_addr_count;

    FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
    BufLen = sizeof(FIXED_INFO);

    if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
        if (FixedInfo) {
            GlobalFree(FixedInfo);
            FixedInfo = NULL;
        }
        FixedInfo = GlobalAlloc(GPTR, BufLen);
    }

    if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
        printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
        if (FixedInfo) {
            GlobalFree(FixedInfo);
            FixedInfo = NULL;
        }
        return -1;
    }

    D( "DNS Servers:");
    pIPAddr = &(FixedInfo->DnsServerList);
    while (pIPAddr && dns_addr_count < DNS_ADDR_MAX) {
        uint32_t  ip;
        D( "  %s", pIPAddr->IpAddress.String );
        if (inet_strtoip(pIPAddr->IpAddress.String, &ip) == 0) {
            if (ip == loopback_addr_ip)
                ip = our_addr_ip;
            if (dns_addr_count < DNS_ADDR_MAX)
                dns_addr[dns_addr_count++] = ip;
        }
        pIPAddr = pIPAddr->Next;
    }

    if (FixedInfo) {
        GlobalFree(FixedInfo);
        FixedInfo = NULL;
    }
    if (dns_addr_count <= 0)
        return -1;

    return dns_addr_count;
}

#else

int slirp_get_system_dns_servers(void)
{
    char buff[512];
    char buff2[257];
    FILE *f;

    if (dns_addr_count > 0)
        return dns_addr_count;

#ifdef CONFIG_DARWIN
    /* on Darwin /etc/resolv.conf is a symlink to /private/var/run/resolv.conf
     * in some siutations, the symlink can be destroyed and the system will not
     * re-create it. Darwin-aware applications will continue to run, but "legacy"
     * Unix ones will not.
     */
     f = fopen("/private/var/run/resolv.conf", "r");
     if (!f)
        f = fopen("/etc/resolv.conf", "r");  /* desperate attempt to sanity */
#else
    f = fopen("/etc/resolv.conf", "r");
#endif
    if (!f)
        return -1;

    DN("emulator: IP address of your DNS(s): ");
    while (fgets(buff, 512, f) != NULL) {
        if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
            uint32_t  tmp_ip;

            if (inet_strtoip(buff2, &tmp_ip) < 0)
                continue;
            if (tmp_ip == loopback_addr_ip)
                tmp_ip = our_addr_ip;
            if (dns_addr_count < DNS_ADDR_MAX) {
                dns_addr[dns_addr_count++] = tmp_ip;
                if (dns_addr_count > 1)
                    DN(", ");
                DN("%s", inet_iptostr(tmp_ip));
            } else {
                DN("(more)");
                break;
            }
        }
    }
    DN("\n");
    fclose(f);

    if (!dns_addr_count)
        return -1;

    return dns_addr_count;
}

#endif

static void slirp_state_save(QEMUFile *f, void *opaque);
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);

void slirp_init(int restricted, const char *special_ip)
{
#if DEBUG
    int   slirp_logmask = 0;
    char  slirp_logfile[512];
    {
        const char*  env = getenv( "ANDROID_SLIRP_LOGMASK" );
        if (env != NULL)
            slirp_logmask = atoi(env);
         else if (VERBOSE_CHECK(slirp))
            slirp_logmask = DEBUG_DEFAULT;
    }

    {
        char*  p   = slirp_logfile;
        char*  end = p + sizeof(slirp_logfile);

        p = bufprint_temp_file( p, end, "slirp.log" );
        if (p >= end) {
            dprint( "cannot create slirp log file in temporary directory" );
            slirp_logmask = 0;
        }
    }
    if (slirp_logmask) {
        dprint( "sending slirp logs with mask %x to %s", slirp_logmask, slirp_logfile );
        debug_init( slirp_logfile, slirp_logmask );
    }
#endif

    link_up = 1;
    slirp_restrict = restricted;

    if_init();
    ip_init();

    /* Initialise mbufs *after* setting the MTU */
    m_init();

    /* set default addresses */
    inet_strtoip("127.0.0.1", &loopback_addr_ip);

    if (dns_addr_count == 0) {
        if (slirp_get_system_dns_servers() < 0) {
            dns_addr[0]    = loopback_addr_ip;
            dns_addr_count = 1;
            fprintf (stderr, "Warning: No DNS servers found\n");
        }
    }

    inet_strtoip(CTL_SPECIAL, &special_addr_ip);

    alias_addr_ip = special_addr_ip | CTL_ALIAS;
    getouraddr();
    register_savevm(NULL, "slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);

    slirp_net_forward_init();
}

#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)

/*
 * curtime kept to an accuracy of 1ms
 */
#ifdef _WIN32
static void updtime(void)
{
    struct _timeb tb;

    _ftime(&tb);
    curtime = (u_int)tb.time * (u_int)1000;
    curtime += (u_int)tb.millitm;
}
#else
static void updtime(void)
{
        gettimeofday(&tt, NULL);

	curtime = (u_int)tt.tv_sec * (u_int)1000;
	curtime += (u_int)tt.tv_usec / (u_int)1000;

	if ((tt.tv_usec % 1000) >= 500)
	   curtime++;
}
#endif

void slirp_select_fill(int *pnfds,
                       fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
    struct socket *so, *so_next;
    struct timeval timeout;
    int nfds;
    int tmp_time;

    /* fail safe */
    global_readfds = NULL;
    global_writefds = NULL;
    global_xfds = NULL;

    nfds = *pnfds;
	/*
	 * First, TCP sockets
	 */
	do_slowtimo = 0;
	if (link_up) {
		/*
		 * *_slowtimo needs calling if there are IP fragments
		 * in the fragment queue, or there are TCP connections active
		 */
		do_slowtimo = ((tcb.so_next != &tcb) ||
                (&ipq.ip_link != ipq.ip_link.next));

		for (so = tcb.so_next; so != &tcb; so = so_next) {
			so_next = so->so_next;

			/*
			 * See if we need a tcp_fasttimo
			 */
			if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
			   time_fasttimo = curtime; /* Flag when we want a fasttimo */

			/*
			 * NOFDREF can include still connecting to local-host,
			 * newly socreated() sockets etc. Don't want to select these.
	 		 */
			if (so->so_state & SS_NOFDREF || so->s == -1)
			   continue;

            /*
             * don't register proxified socked connections here
             */
            if ((so->so_state & SS_PROXIFIED) != 0)
	            continue;

			/*
			 * Set for reading sockets which are accepting
			 */
			if (so->so_state & SS_FACCEPTCONN) {
                                FD_SET(so->s, readfds);
				UPD_NFDS(so->s);
				continue;
			}

			/*
			 * Set for writing sockets which are connecting
			 */
			if (so->so_state & SS_ISFCONNECTING) {
				FD_SET(so->s, writefds);
				UPD_NFDS(so->s);
				continue;
			}

			/*
			 * Set for writing if we are connected, can send more, and
			 * we have something to send
			 */
			if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
				FD_SET(so->s, writefds);
				UPD_NFDS(so->s);
			}

			/*
			 * Set for reading (and urgent data) if we are connected, can
			 * receive more, and we have room for it XXX /2 ?
			 */
			if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
				FD_SET(so->s, readfds);
				FD_SET(so->s, xfds);
				UPD_NFDS(so->s);
			}
		}

		/*
		 * UDP sockets
		 */
		for (so = udb.so_next; so != &udb; so = so_next) {
			so_next = so->so_next;

            if ((so->so_state & SS_PROXIFIED) != 0)
                continue;

			/*
			 * See if it's timed out
			 */
			if (so->so_expire) {
				if (so->so_expire <= curtime) {
					udp_detach(so);
					continue;
				} else
					do_slowtimo = 1; /* Let socket expire */
			}

			/*
			 * When UDP packets are received from over the
			 * link, they're sendto()'d straight away, so
			 * no need for setting for writing
			 * Limit the number of packets queued by this session
			 * to 4.  Note that even though we try and limit this
			 * to 4 packets, the session could have more queued
			 * if the packets needed to be fragmented
			 * (XXX <= 4 ?)
			 */
			if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
				FD_SET(so->s, readfds);
				UPD_NFDS(so->s);
			}
		}
	}

	/*
	 * Setup timeout to use minimum CPU usage, especially when idle
	 */

	/*
	 * First, see the timeout needed by *timo
	 */
	timeout.tv_sec = 0;
	timeout.tv_usec = -1;
	/*
	 * If a slowtimo is needed, set timeout to 500ms from the last
	 * slow timeout. If a fast timeout is needed, set timeout within
	 * 200ms of when it was requested.
	 */
	if (do_slowtimo) {
		/* XXX + 10000 because some select()'s aren't that accurate */
		timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
		if (timeout.tv_usec < 0)
		   timeout.tv_usec = 0;
		else if (timeout.tv_usec > 510000)
		   timeout.tv_usec = 510000;

		/* Can only fasttimo if we also slowtimo */
		if (time_fasttimo) {
			tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
			if (tmp_time < 0)
			   tmp_time = 0;

			/* Choose the smallest of the 2 */
			if (tmp_time < timeout.tv_usec)
			   timeout.tv_usec = (u_int)tmp_time;
		}
	}
    /*
     * now, the proxified sockets
     */
    proxy_manager_select_fill(&nfds, readfds, writefds, xfds);

        *pnfds = nfds;
}

void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
    struct socket *so, *so_next;
    int ret;

    global_readfds = readfds;
    global_writefds = writefds;
    global_xfds = xfds;

	/* Update time */
	updtime();

	/*
	 * See if anything has timed out
	 */
	if (link_up) {
		if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
			tcp_fasttimo();
			time_fasttimo = 0;
		}
		if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
			ip_slowtimo();
			tcp_slowtimo();
			last_slowtimo = curtime;
		}
	}

	/*
	 * Check sockets
	 */
	if (link_up) {
		/*
		 * Check TCP sockets
		 */
		for (so = tcb.so_next; so != &tcb; so = so_next) {
			so_next = so->so_next;

			/*
			 * FD_ISSET is meaningless on these sockets
			 * (and they can crash the program)
			 */
			if (so->so_state & SS_NOFDREF || so->s == -1)
			   continue;

            /*
             * proxified sockets are polled later in this
             * function.
             */
            if ((so->so_state & SS_PROXIFIED) != 0)
                continue;

			/*
			 * Check for URG data
			 * This will soread as well, so no need to
			 * test for readfds below if this succeeds
			 */
			if (FD_ISSET(so->s, xfds))
			   sorecvoob(so);
			/*
			 * Check sockets for reading
			 */
			else if (FD_ISSET(so->s, readfds)) {
				/*
				 * Check for incoming connections
				 */
				if (so->so_state & SS_FACCEPTCONN) {
					tcp_connect(so);
					continue;
				} /* else */
				ret = soread(so);

				/* Output it if we read something */
				if (ret > 0)
				   tcp_output(sototcpcb(so));
			}

			/*
			 * Check sockets for writing
			 */
			if (FD_ISSET(so->s, writefds)) {
			  /*
			   * Check for non-blocking, still-connecting sockets
			   */
			  if (so->so_state & SS_ISFCONNECTING) {
			    /* Connected */
			    so->so_state &= ~SS_ISFCONNECTING;

			    ret = socket_send(so->s, (const void *)&ret, 0);
			    if (ret < 0) {
			      /* XXXXX Must fix, zero bytes is a NOP */
			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
				  errno == EINPROGRESS || errno == ENOTCONN)
				continue;

			      /* else failed */
			      so->so_state = SS_NOFDREF;
			    }
			    /* else so->so_state &= ~SS_ISFCONNECTING; */

			    /*
			     * Continue tcp_input
			     */
			    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
			    /* continue; */
			  } else
			    ret = sowrite(so);
			  /*
			   * XXXXX If we wrote something (a lot), there
			   * could be a need for a window update.
			   * In the worst case, the remote will send
			   * a window probe to get things going again
			   */
			}

			/*
			 * Probe a still-connecting, non-blocking socket
			 * to check if it's still alive
	 	 	 */
#ifdef PROBE_CONN
			if (so->so_state & SS_ISFCONNECTING) {
			  ret = socket_recv(so->s, (char *)&ret, 0);

			  if (ret < 0) {
			    /* XXX */
			    if (errno == EAGAIN || errno == EWOULDBLOCK ||
				errno == EINPROGRESS || errno == ENOTCONN)
			      continue; /* Still connecting, continue */

			    /* else failed */
			    so->so_state = SS_NOFDREF;

			    /* tcp_input will take care of it */
			  } else {
			    ret = socket_send(so->s, &ret, 0);
			    if (ret < 0) {
			      /* XXX */
			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
				  errno == EINPROGRESS || errno == ENOTCONN)
				continue;
			      /* else failed */
			      so->so_state = SS_NOFDREF;
			    } else
			      so->so_state &= ~SS_ISFCONNECTING;

			  }
			  tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
			} /* SS_ISFCONNECTING */
#endif
		}

		/*
		 * Now UDP sockets.
		 * Incoming packets are sent straight away, they're not buffered.
		 * Incoming UDP data isn't buffered either.
		 */
		for (so = udb.so_next; so != &udb; so = so_next) {
			so_next = so->so_next;

            if ((so->so_state & SS_PROXIFIED) != 0)
                continue;

			if (so->s != -1 && FD_ISSET(so->s, readfds)) {
                            sorecvfrom(so);
                        }
		}
	}

    /*
     * Now the proxified sockets
     */
    proxy_manager_poll(readfds, writefds, xfds);

	/*
	 * See if we can start outputting
	 */
	if (if_queued && link_up)
	   if_start();

	/* clear global file descriptor sets.
	 * these reside on the stack in vl.c
	 * so they're unusable if we're not in
	 * slirp_select_fill or slirp_select_poll.
	 */
	 global_readfds = NULL;
	 global_writefds = NULL;
	 global_xfds = NULL;
}

#define ETH_ALEN 6
#define ETH_HLEN 14

#define ETH_P_IP	0x0800		/* Internet Protocol packet	*/
#define ETH_P_ARP	0x0806		/* Address Resolution packet	*/

#define	ARPOP_REQUEST	1		/* ARP request			*/
#define	ARPOP_REPLY	2		/* ARP reply			*/

struct ethhdr
{
	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
	unsigned short	h_proto;		/* packet type ID field	*/
};

struct arphdr
{
	unsigned short	ar_hrd;		/* format of hardware address	*/
	unsigned short	ar_pro;		/* format of protocol address	*/
	unsigned char	ar_hln;		/* length of hardware address	*/
	unsigned char	ar_pln;		/* length of protocol address	*/
	unsigned short	ar_op;		/* ARP opcode (command)		*/

	 /*
	  *	 Ethernet looks like this : This bit is variable sized however...
	  */
	unsigned char		ar_sha[ETH_ALEN];	/* sender hardware address	*/
	unsigned char		ar_sip[4];		/* sender IP address		*/
	unsigned char		ar_tha[ETH_ALEN];	/* target hardware address	*/
	unsigned char		ar_tip[4];		/* target IP address		*/
};

static void arp_input(const uint8_t *pkt, int pkt_len)
{
    struct ethhdr *eh = (struct ethhdr *)pkt;
    struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
    uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
    struct ethhdr *reh = (struct ethhdr *)arp_reply;
    struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
    int ar_op;
    struct ex_list *ex_ptr;

    ar_op = ntohs(ah->ar_op);
    switch(ar_op) {
        uint32_t    ar_tip_ip;

    case ARPOP_REQUEST:
        ar_tip_ip = ip_read32h(ah->ar_tip);
        if ((ar_tip_ip & 0xffffff00) == special_addr_ip) {
            uint32_t  ar_tip_low = ar_tip_ip & 0xff;
            if ( CTL_IS_DNS(ar_tip_low) || ar_tip_low == CTL_ALIAS)
                goto arp_ok;
            for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
                if ((uint32_t)ex_ptr->ex_addr == ar_tip_low)
                    goto arp_ok;
            }
            return;
        arp_ok:
            /* XXX: make an ARP request to have the client address */
            memcpy(client_ethaddr, eh->h_source, ETH_ALEN);

            /* ARP request for alias/dns mac address */
            memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
            memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
            reh->h_source[5] = ar_tip_low;
            reh->h_proto = htons(ETH_P_ARP);

            rah->ar_hrd = htons(1);
            rah->ar_pro = htons(ETH_P_IP);
            rah->ar_hln = ETH_ALEN;
            rah->ar_pln = 4;
            rah->ar_op = htons(ARPOP_REPLY);
            memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
            memcpy(rah->ar_sip, ah->ar_tip, 4);
            memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
            memcpy(rah->ar_tip, ah->ar_sip, 4);
            slirp_output(arp_reply, sizeof(arp_reply));
        }
        break;
    case ARPOP_REPLY:
        /* reply to request of client mac address ? */
        if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
            ip_equal( ip_read(ah->ar_sip), client_ip )) {
            memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
        }
        break;
    default:
        break;
    }
}

void slirp_input(const uint8_t *pkt, int pkt_len)
{
    struct mbuf *m;
    int proto;

    if (pkt_len < ETH_HLEN)
        return;

    proto = ntohs(*(uint16_t *)(pkt + 12));
    switch(proto) {
    case ETH_P_ARP:
        arp_input(pkt, pkt_len);
        break;
    case ETH_P_IP:
        m = m_get();
        if (!m)
            return;
        /* Note: we add to align the IP header */
        if (M_FREEROOM(m) < pkt_len + 2) {
            m_inc(m, pkt_len + 2);
        }
        m->m_len = pkt_len + 2;
        memcpy(m->m_data + 2, pkt, pkt_len);

        m->m_data += 2 + ETH_HLEN;
        m->m_len -= 2 + ETH_HLEN;

        ip_input(m);
        break;
    default:
        break;
    }
}

/* output the IP packet to the ethernet device */
void if_encap(const uint8_t *ip_data, int ip_data_len)
{
    uint8_t buf[1600];
    struct ethhdr *eh = (struct ethhdr *)buf;

    if (ip_data_len + ETH_HLEN > (int)sizeof(buf))
        return;

    if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
        uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
        struct ethhdr *reh = (struct ethhdr *)arp_req;
        struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
        const struct ip *iph = (const struct ip *)ip_data;

        /* If the client addr is not known, there is no point in
           sending the packet to it. Normally the sender should have
           done an ARP request to get its MAC address. Here we do it
           in place of sending the packet and we hope that the sender
           will retry sending its packet. */
        memset(reh->h_dest, 0xff, ETH_ALEN);
        memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
        reh->h_source[5] = CTL_ALIAS;
        reh->h_proto = htons(ETH_P_ARP);
        rah->ar_hrd = htons(1);
        rah->ar_pro = htons(ETH_P_IP);
        rah->ar_hln = ETH_ALEN;
        rah->ar_pln = 4;
        rah->ar_op = htons(ARPOP_REQUEST);
        /* source hw addr */
        memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
        rah->ar_sha[5] = CTL_ALIAS;
        /* source IP */
        ip_write32h(alias_addr_ip, rah->ar_sip);
        /* target hw addr (none) */
        memset(rah->ar_tha, 0, ETH_ALEN);
        /* target IP */
        ip_write( iph->ip_dst, rah->ar_tip );
        client_ip   = iph->ip_dst;
        slirp_output(arp_req, sizeof(arp_req));
    } else {
        memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
        memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
        /* XXX: not correct */
        eh->h_source[5] = CTL_ALIAS;
        eh->h_proto = htons(ETH_P_IP);
        memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
        slirp_output(buf, ip_data_len + ETH_HLEN);
    }
}


/*---------------------------------------------------*/
/* User mode network stack restrictions */
struct fw_allow_entry {
    struct fw_allow_entry* next;
    unsigned long dst_addr;   /* host byte order */
    /* Allowed port range. dst_lport should be the same as dst_hport for a
     * single port. */
    unsigned short dst_lport; /* host byte order */
    unsigned short dst_hport; /* host byte order */
};

static int drop_udp = 0;
static int drop_tcp = 0;
static struct fw_allow_entry* allow_tcp_entries = NULL;
static struct fw_allow_entry* allow_udp_entries = NULL;
static FILE* drop_log_fd = NULL;
static FILE* dns_log_fd = NULL;
static int max_dns_conns = -1;   /* unlimited max DNS connections by default */
static int slirp_net_forward_inited = 0;

void slirp_drop_udp() {
    drop_udp = 1;
}

void slirp_drop_tcp() {
    drop_tcp = 1;
}

/* TCP traffic forwarding to a sink - If enabled, all TCP traffic to any
 * ip/port that is not explicitly forwared using '-net-forward', and which would
 * otherwise be dropped if '-drop-tcp' has been specified, is redirected to the
 * specified ip:port
 */
int forward_dropped_tcp2sink = 0;
static unsigned long tcp_sink_ip;
int tcp_sink_port;

void slirp_forward_dropped_tcp2sink(unsigned long sink_ip, int sink_port) {
    tcp_sink_ip = sink_ip;
    tcp_sink_port = sink_port;
    forward_dropped_tcp2sink = 1;
}

int slirp_should_forward_dropped_tcp2sink() {
    return forward_dropped_tcp2sink;
}

unsigned long slirp_get_tcp_sink_ip() {
    return tcp_sink_ip;
}
int slirp_get_tcp_sink_port() {
    return tcp_sink_port;
}

/* Fill in the firewall rules. dst_lport and dst_hport are in host byte order */
void slirp_add_allow(unsigned long dst_addr,
                     int dst_lport, int dst_hport,
                     u_int8_t proto) {

    struct fw_allow_entry** ate;
    switch (proto) {
      case IPPROTO_TCP:
          ate = &allow_tcp_entries;
          break;
      case IPPROTO_UDP:
          ate = &allow_udp_entries;
          break;
      default:
          return; // unknown protocol for the FW
    }

    while(*ate != NULL)
        ate = &(*ate)->next;

    *ate = malloc(sizeof(**ate));
    if (*ate == NULL) {
        DEBUG_MISC((dfd,
                    "Unable to create new firewall record, malloc failed\n"));
        exit(-1);
    }

    (*ate)->next = NULL;
    (*ate)->dst_addr = dst_addr;
    (*ate)->dst_lport = dst_lport;
    (*ate)->dst_hport = dst_hport;
}

void slirp_drop_log_fd(FILE* fd) {
    drop_log_fd = fd;
}

void slirp_dns_log_fd(FILE* fd) {
    dns_log_fd = fd;
}

FILE* get_slirp_drop_log_fd(void) {
  return drop_log_fd;
}

FILE* get_slirp_dns_log_fd(void) {
  return dns_log_fd;
}

/* Address and ports are in host byte order */
int slirp_should_drop(unsigned long dst_addr,
                      int dst_port,
                      u_int8_t proto) {

    struct fw_allow_entry* ate;

    switch (proto) {
        case IPPROTO_TCP:
            if (drop_tcp != 0)
                ate = allow_tcp_entries;
            else
                return 0;
            break;
        case IPPROTO_UDP:
            if (drop_udp != 0)
                ate = allow_udp_entries;
            else
                return 0;
            break;
        default:
            return 1;  // unknown protocol for the FW
    }

    while(ate) {
        if ((ate->dst_lport <= dst_port) && (dst_port <= ate->dst_hport)) {
            // allow any destination if 0
            if (ate->dst_addr == 0 || ate->dst_addr == dst_addr)
                return 0;
        }
        ate = ate->next;
    }

    return 1;
}

/*
 * log DNS requests in a separate log
 */
int
slirp_log_dns(struct mbuf* m, int dropped) {
    char dns_query[256];  // max allowable dns name size
    int c = 0;
    int i= 0;
    int index = 0;
    int offset = 40 + 1;  // udp/ip headers length + 1;
    int trim_bytes = 4;

    if (!dns_log_fd)
        return -1;

    /* We assume one DNS name per query: 300 = 255 (max dns name length)
     * + 40 (udp/ip hdr) + 1 byte DNS peamble + 4 bytes DNS suffix
     */
    if (m->m_len < offset || m->m_len > 300) {
        DEBUG_MISC((dfd,"Malformed DNS qeury, length %d \n", (int)m->m_len));
        return -1;
    }
    for (i = offset; i < m->m_len - trim_bytes && index < (int)sizeof(dns_query); i++, index++) {
        c = m->m_data[i];
        if (c < ' ' || c > '~')
            c = '.';

        dns_query[index] = (char)c;
    }
    dns_query[index] = '\0';
    if (!dropped) {
        fprintf(dns_log_fd, "Sent DNS query for, %s\n" , dns_query);
    } else {
        fprintf(dns_log_fd, "Dropped DNS query for, %s\n" , dns_query);
    }
    fflush(dns_log_fd);
    return 1;
}

/*
 * log DNS requests in a separate log
 */
int
slirp_dump_dns(struct mbuf* m) {

    if (!dns_log_fd)
        return 0;
    // first we write the length of the record then the record (IP packet)
    if (!fwrite(&(m->m_len), sizeof(int), 1, dns_log_fd) ||
        !fwrite(m->m_data, m->m_len, 1, dns_log_fd)) {
        return 0;
    }

    fflush(dns_log_fd);
    return 1;
}

/* Log dropped/accepted packet info */
int slirp_drop_log(const char* format, ...) {
    va_list args;

    if (!drop_log_fd)
        return 0;

    va_start(args, format);
    vfprintf(drop_log_fd, format, args);
    va_end(args);

    fflush(drop_log_fd);

    return 1;
}


/* Set max DNS requests allowed to be issued from the VM */
void slirp_set_max_dns_conns(int num_conns) {
    max_dns_conns = num_conns;
}

int slirp_get_max_dns_conns() {
    return max_dns_conns;
}

/* generic guest network redirection functionality for ipv4 */
struct net_forward_entry {
    QTAILQ_ENTRY(net_forward_entry) next;
    /* ip addresses are also in host byte order */
    unsigned long dest_ip;            /* the destination address they try to contact */
    unsigned long dest_mask;          /* the mask to apply to the address for matching */
    /* Range of ports they were trying to contact. In case of a single port,
     * dest_lport should be the same as dest_hport */
    int dest_lport; /* Host byte order */
    int dest_hport; /* Host byte order */

    unsigned long  redirect_ip;
    int redirect_port; /* Host byte order */
};

static QTAILQ_HEAD(net_forwardq, net_forward_entry) net_forwards;

static void slirp_net_forward_init(void)
{
    if (!slirp_net_forward_inited) {
      QTAILQ_INIT(&net_forwards);
      slirp_net_forward_inited = 1;
    }
}

/* all addresses and ports ae in host byte order */
void slirp_add_net_forward(unsigned long dest_ip, unsigned long dest_mask,
                           int dest_lport, int dest_hport,
                           unsigned long redirect_ip, int redirect_port)
{
    slirp_net_forward_init();

    struct net_forward_entry *entry = malloc(sizeof(*entry));
    if (entry == NULL) {
        DEBUG_MISC((dfd, "Unable to create new forwarding entry, malloc failed\n"));
        exit(-1);
    }

    entry->dest_ip = dest_ip;
    entry->dest_mask = dest_mask;
    entry->dest_lport = dest_lport;
    entry->dest_hport = dest_hport;
    entry->redirect_ip = redirect_ip;
    entry->redirect_port = redirect_port;

    QTAILQ_INSERT_TAIL(&net_forwards, entry, next);
}

/* remote_port and redir_port arguments
 * are in network byte order (tcp_subr.c) */
int slirp_should_net_forward(unsigned long remote_ip, int remote_port,
                             unsigned long *redirect_ip, int *redirect_port)
{
    struct net_forward_entry *entry;

    for (entry = net_forwards.tqh_first;
         entry != NULL; entry = entry->next.tqe_next) {

        if ((entry->dest_lport <= remote_port)
            && (remote_port <= entry->dest_hport)) {
            if ((entry->dest_ip & entry->dest_mask)
                == (remote_ip & entry->dest_mask)) {
              *redirect_ip = entry->redirect_ip;
              *redirect_port = entry->redirect_port;
              return 1;
            }
        }
    }

    return 0;
}

/*---------------------------------------------------*/




static void _slirp_redir_loop(void (*func)(void *opaque, int is_udp,
                                           const SockAddress *laddr,
                                           const SockAddress *faddr),
                              void *opaque, int is_udp)
{
    struct socket *head = (is_udp ? &udb : &tcb);
    struct socket *so;

    for (so = head->so_next; so != head; so = so->so_next) {
        SockAddress  local, foreign;

		sock_address_init_inet(&local, so->so_laddr_ip, so->so_laddr_port);
		sock_address_init_inet(&foreign, so->so_faddr_ip, so->so_faddr_port);
        func(opaque, is_udp,
             &local, &foreign);
    }
}

void slirp_redir_loop(void (*func)(void *opaque, int is_udp,
                                   const SockAddress *laddr,
                                   const SockAddress *faddr),
                     void *opaque)
{
    _slirp_redir_loop(func, opaque, 0);
    _slirp_redir_loop(func, opaque, 1);
}

/* Unlistens a redirection
 *
 * Return value: number of redirs removed */
int slirp_redir_rm(int is_udp, int host_port)
{
    struct socket *so;
    struct socket *head = (is_udp ? &udb : &tcb);
    int n = 0;

 loop_again:
    for (so = head->so_next; so != head; so = so->so_next) {
        if (so->so_faddr_port == host_port) {
            close(so->s);
            sofree(so);
            n++;
            goto loop_again;
        }
    }

    return n;
}

int slirp_redir(int is_udp, int host_port,
                uint32_t  guest_ip, int guest_port)
{
    if (is_udp) {
        if (!udp_listen(host_port,
                        guest_ip,
                        guest_port, 0))
            return -1;
    } else {
        if (!solisten(host_port, guest_ip, guest_port, 0))
            return -1;
    }
    return 0;
}

int  slirp_unredir(int  is_udp, int  host_port)
{
    if (is_udp)
        return udp_unlisten( host_port );
    else
        return sounlisten( host_port );
}

int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
                  int guest_port)
{
    return add_exec(&exec_list, do_pty, (char *)args,
                    addr_low_byte, htons(guest_port));
}

ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
{
	if (so->s == -1 && so->extra) {
		qemu_chr_write(so->extra, buf, len);
		return len;
	}

	return send(so->s, buf, len, flags);
}

static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
{
	struct socket *so;

	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
		if ((so->so_faddr_ip & 0xffffff00) ==
				special_addr_ip
				&& ((so->so_faddr_port & 0xff) ==
				addr_low_byte)
				&& so->so_faddr_port == guest_port)
			return so;
	}

	return NULL;
}

size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
{
	struct iovec iov[2];
	struct socket *so;

    if (!link_up)
        return 0;

	so = slirp_find_ctl_socket(addr_low_byte, guest_port);

	if (!so || so->so_state & SS_NOFDREF)
		return 0;

	if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
		return 0;

	return sopreprbuf(so, iov, NULL);
}

void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
        int size)
{
    int ret;
    struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);

    if (!so)
        return;

    ret = soreadbuf(so, (const char *)buf, size);

    if (ret > 0)
        tcp_output(sototcpcb(so));
}

static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
{
    int i;

    qemu_put_sbe16(f, tp->t_state);
    for (i = 0; i < TCPT_NTIMERS; i++)
        qemu_put_sbe16(f, tp->t_timer[i]);
    qemu_put_sbe16(f, tp->t_rxtshift);
    qemu_put_sbe16(f, tp->t_rxtcur);
    qemu_put_sbe16(f, tp->t_dupacks);
    qemu_put_be16(f, tp->t_maxseg);
    qemu_put_sbyte(f, tp->t_force);
    qemu_put_be16(f, tp->t_flags);
    qemu_put_be32(f, tp->snd_una);
    qemu_put_be32(f, tp->snd_nxt);
    qemu_put_be32(f, tp->snd_up);
    qemu_put_be32(f, tp->snd_wl1);
    qemu_put_be32(f, tp->snd_wl2);
    qemu_put_be32(f, tp->iss);
    qemu_put_be32(f, tp->snd_wnd);
    qemu_put_be32(f, tp->rcv_wnd);
    qemu_put_be32(f, tp->rcv_nxt);
    qemu_put_be32(f, tp->rcv_up);
    qemu_put_be32(f, tp->irs);
    qemu_put_be32(f, tp->rcv_adv);
    qemu_put_be32(f, tp->snd_max);
    qemu_put_be32(f, tp->snd_cwnd);
    qemu_put_be32(f, tp->snd_ssthresh);
    qemu_put_sbe16(f, tp->t_idle);
    qemu_put_sbe16(f, tp->t_rtt);
    qemu_put_be32(f, tp->t_rtseq);
    qemu_put_sbe16(f, tp->t_srtt);
    qemu_put_sbe16(f, tp->t_rttvar);
    qemu_put_be16(f, tp->t_rttmin);
    qemu_put_be32(f, tp->max_sndwnd);
    qemu_put_byte(f, tp->t_oobflags);
    qemu_put_byte(f, tp->t_iobc);
    qemu_put_sbe16(f, tp->t_softerror);
    qemu_put_byte(f, tp->snd_scale);
    qemu_put_byte(f, tp->rcv_scale);
    qemu_put_byte(f, tp->request_r_scale);
    qemu_put_byte(f, tp->requested_s_scale);
    qemu_put_be32(f, tp->ts_recent);
    qemu_put_be32(f, tp->ts_recent_age);
    qemu_put_be32(f, tp->last_ack_sent);
}

static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
{
    uint32_t off;

    qemu_put_be32(f, sbuf->sb_cc);
    qemu_put_be32(f, sbuf->sb_datalen);
    off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
    qemu_put_sbe32(f, off);
    off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
    qemu_put_sbe32(f, off);
    qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
}

static void slirp_socket_save(QEMUFile *f, struct socket *so)
{
    qemu_put_be32(f, so->so_urgc);
    qemu_put_be32(f, so->so_faddr_ip);
    qemu_put_be32(f, so->so_laddr_ip);
    qemu_put_be16(f, so->so_faddr_port);
    qemu_put_be16(f, so->so_laddr_port);
    qemu_put_byte(f, so->so_iptos);
    qemu_put_byte(f, so->so_emu);
    qemu_put_byte(f, so->so_type);
    qemu_put_be32(f, so->so_state);
    slirp_sbuf_save(f, &so->so_rcv);
    slirp_sbuf_save(f, &so->so_snd);
    slirp_tcp_save(f, so->so_tcpcb);
}

static void slirp_state_save(QEMUFile *f, void *opaque)
{
    struct ex_list *ex_ptr;

    for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
        if (ex_ptr->ex_pty == 3) {
            struct socket *so;
            so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
            if (!so)
                continue;

            qemu_put_byte(f, 42);
            slirp_socket_save(f, so);
        }
    qemu_put_byte(f, 0);
}

static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
{
    int i;

    tp->t_state = qemu_get_sbe16(f);
    for (i = 0; i < TCPT_NTIMERS; i++)
        tp->t_timer[i] = qemu_get_sbe16(f);
    tp->t_rxtshift = qemu_get_sbe16(f);
    tp->t_rxtcur = qemu_get_sbe16(f);
    tp->t_dupacks = qemu_get_sbe16(f);
    tp->t_maxseg = qemu_get_be16(f);
    tp->t_force = qemu_get_sbyte(f);
    tp->t_flags = qemu_get_be16(f);
    tp->snd_una = qemu_get_be32(f);
    tp->snd_nxt = qemu_get_be32(f);
    tp->snd_up = qemu_get_be32(f);
    tp->snd_wl1 = qemu_get_be32(f);
    tp->snd_wl2 = qemu_get_be32(f);
    tp->iss = qemu_get_be32(f);
    tp->snd_wnd = qemu_get_be32(f);
    tp->rcv_wnd = qemu_get_be32(f);
    tp->rcv_nxt = qemu_get_be32(f);
    tp->rcv_up = qemu_get_be32(f);
    tp->irs = qemu_get_be32(f);
    tp->rcv_adv = qemu_get_be32(f);
    tp->snd_max = qemu_get_be32(f);
    tp->snd_cwnd = qemu_get_be32(f);
    tp->snd_ssthresh = qemu_get_be32(f);
    tp->t_idle = qemu_get_sbe16(f);
    tp->t_rtt = qemu_get_sbe16(f);
    tp->t_rtseq = qemu_get_be32(f);
    tp->t_srtt = qemu_get_sbe16(f);
    tp->t_rttvar = qemu_get_sbe16(f);
    tp->t_rttmin = qemu_get_be16(f);
    tp->max_sndwnd = qemu_get_be32(f);
    tp->t_oobflags = qemu_get_byte(f);
    tp->t_iobc = qemu_get_byte(f);
    tp->t_softerror = qemu_get_sbe16(f);
    tp->snd_scale = qemu_get_byte(f);
    tp->rcv_scale = qemu_get_byte(f);
    tp->request_r_scale = qemu_get_byte(f);
    tp->requested_s_scale = qemu_get_byte(f);
    tp->ts_recent = qemu_get_be32(f);
    tp->ts_recent_age = qemu_get_be32(f);
    tp->last_ack_sent = qemu_get_be32(f);
    tcp_template(tp);
}

static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
{
    uint32_t off, sb_cc, sb_datalen;

    sb_cc = qemu_get_be32(f);
    sb_datalen = qemu_get_be32(f);

    sbreserve(sbuf, sb_datalen);

    if (sbuf->sb_datalen != sb_datalen)
        return -ENOMEM;

    sbuf->sb_cc = sb_cc;

    off = qemu_get_sbe32(f);
    sbuf->sb_wptr = sbuf->sb_data + off;
    off = qemu_get_sbe32(f);
    sbuf->sb_rptr = sbuf->sb_data + off;
    qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);

    return 0;
}

static int slirp_socket_load(QEMUFile *f, struct socket *so)
{
    if (tcp_attach(so) < 0)
        return -ENOMEM;

    so->so_urgc = qemu_get_be32(f);
    so->so_faddr_ip = qemu_get_be32(f);
    so->so_laddr_ip = qemu_get_be32(f);
    so->so_faddr_port = qemu_get_be16(f);
    so->so_laddr_port = qemu_get_be16(f);
    so->so_iptos = qemu_get_byte(f);
    so->so_emu = qemu_get_byte(f);
    so->so_type = qemu_get_byte(f);
    so->so_state = qemu_get_be32(f);
    if (slirp_sbuf_load(f, &so->so_rcv) < 0)
        return -ENOMEM;
    if (slirp_sbuf_load(f, &so->so_snd) < 0)
        return -ENOMEM;
    slirp_tcp_load(f, so->so_tcpcb);

    return 0;
}

static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
{
    struct ex_list *ex_ptr;
    int r;

    while ((r = qemu_get_byte(f))) {
        int ret;
        struct socket *so = socreate();

        if (!so)
            return -ENOMEM;

        ret = slirp_socket_load(f, so);

        if (ret < 0)
            return ret;

        if ((so->so_faddr_ip & 0xffffff00) != special_addr_ip)
            return -EINVAL;

        for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
            if (ex_ptr->ex_pty == 3 &&
                    (so->so_faddr_ip & 0xff) == ex_ptr->ex_addr &&
                    so->so_faddr_port == ex_ptr->ex_fport)
                break;

        if (!ex_ptr)
            return -EINVAL;

        so->extra = (void *)ex_ptr->ex_exec;
    }

    return 0;
}
