aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--slirp/bootp.c80
-rw-r--r--slirp/bootp.h7
-rw-r--r--slirp/if.c50
-rw-r--r--slirp/if.h6
-rw-r--r--slirp/ip.h3
-rw-r--r--slirp/ip_icmp.c19
-rw-r--r--slirp/ip_input.c80
-rw-r--r--slirp/ip_output.c7
-rw-r--r--slirp/libslirp.h3
-rw-r--r--slirp/main.h12
-rw-r--r--slirp/mbuf.c30
-rw-r--r--slirp/mbuf.h9
-rw-r--r--slirp/misc.c5
-rw-r--r--slirp/misc.h2
-rw-r--r--slirp/slirp.c182
-rw-r--r--slirp/slirp.h66
-rw-r--r--slirp/socket.c37
-rw-r--r--slirp/socket.h9
-rw-r--r--slirp/tcp.h4
-rw-r--r--slirp/tcp_input.c35
-rw-r--r--slirp/tcp_output.c4
-rw-r--r--slirp/tcp_subr.c74
-rw-r--r--slirp/tcp_timer.c18
-rw-r--r--slirp/tcp_timer.h4
-rw-r--r--slirp/tcp_var.h2
-rw-r--r--slirp/tftp.c65
-rw-r--r--slirp/tftp.h10
-rw-r--r--slirp/udp.c56
-rw-r--r--slirp/udp.h8
29 files changed, 479 insertions, 408 deletions
diff --git a/slirp/bootp.c b/slirp/bootp.c
index fec52c0a84..911ec712c5 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -25,19 +25,8 @@
/* XXX: only DHCP is supported */
-#define NB_ADDR 16
-
#define LEASE_TIME (24 * 3600)
-typedef struct {
- uint8_t allocated;
- uint8_t macaddr[6];
-} BOOTPClient;
-
-static BOOTPClient bootp_clients[NB_ADDR];
-
-char *bootp_filename;
-
static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
#ifdef DEBUG
@@ -47,35 +36,35 @@ do if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## __VA_ARGS__); fflush(dfd)
#define dprintf(fmt, ...)
#endif
-static BOOTPClient *get_new_addr(struct in_addr *paddr,
+static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr,
const uint8_t *macaddr)
{
BOOTPClient *bc;
int i;
- for(i = 0; i < NB_ADDR; i++) {
- bc = &bootp_clients[i];
+ for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
+ bc = &slirp->bootp_clients[i];
if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6))
goto found;
}
return NULL;
found:
- bc = &bootp_clients[i];
+ bc = &slirp->bootp_clients[i];
bc->allocated = 1;
- paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
+ paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
return bc;
}
-static BOOTPClient *request_addr(const struct in_addr *paddr,
+static BOOTPClient *request_addr(Slirp *slirp, const struct in_addr *paddr,
const uint8_t *macaddr)
{
uint32_t req_addr = ntohl(paddr->s_addr);
- uint32_t dhcp_addr = ntohl(vdhcp_startaddr.s_addr);
+ uint32_t dhcp_addr = ntohl(slirp->vdhcp_startaddr.s_addr);
BOOTPClient *bc;
if (req_addr >= dhcp_addr &&
- req_addr < (dhcp_addr + NB_ADDR)) {
- bc = &bootp_clients[req_addr - dhcp_addr];
+ req_addr < (dhcp_addr + NB_BOOTP_CLIENTS)) {
+ bc = &slirp->bootp_clients[req_addr - dhcp_addr];
if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) {
bc->allocated = 1;
return bc;
@@ -84,20 +73,21 @@ static BOOTPClient *request_addr(const struct in_addr *paddr,
return NULL;
}
-static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
+static BOOTPClient *find_addr(Slirp *slirp, struct in_addr *paddr,
+ const uint8_t *macaddr)
{
BOOTPClient *bc;
int i;
- for(i = 0; i < NB_ADDR; i++) {
- if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
+ for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
+ if (!memcmp(macaddr, slirp->bootp_clients[i].macaddr, 6))
goto found;
}
return NULL;
found:
- bc = &bootp_clients[i];
+ bc = &slirp->bootp_clients[i];
bc->allocated = 1;
- paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
+ paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
return bc;
}
@@ -148,7 +138,7 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
}
}
-static void bootp_reply(const struct bootp_t *bp)
+static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
{
BOOTPClient *bc = NULL;
struct mbuf *m;
@@ -173,10 +163,12 @@ static void bootp_reply(const struct bootp_t *bp)
dhcp_msg_type != DHCPREQUEST)
return;
/* XXX: this is a hack to get the client mac address */
- memcpy(client_ethaddr, bp->bp_hwaddr, 6);
+ memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6);
- if ((m = m_get()) == NULL)
+ m = m_get(slirp);
+ if (!m) {
return;
+ }
m->m_data += IF_MAXLINKHDR;
rbp = (struct bootp_t *)m->m_data;
m->m_data += sizeof(struct udpiphdr);
@@ -184,30 +176,30 @@ static void bootp_reply(const struct bootp_t *bp)
if (dhcp_msg_type == DHCPDISCOVER) {
if (preq_addr) {
- bc = request_addr(preq_addr, client_ethaddr);
+ bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
if (bc) {
daddr.sin_addr = *preq_addr;
}
}
if (!bc) {
new_addr:
- bc = get_new_addr(&daddr.sin_addr, client_ethaddr);
+ bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr);
if (!bc) {
dprintf("no address left\n");
return;
}
}
- memcpy(bc->macaddr, client_ethaddr, 6);
+ memcpy(bc->macaddr, slirp->client_ethaddr, 6);
} else if (preq_addr) {
- bc = request_addr(preq_addr, client_ethaddr);
+ bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
if (bc) {
daddr.sin_addr = *preq_addr;
- memcpy(bc->macaddr, client_ethaddr, 6);
+ memcpy(bc->macaddr, slirp->client_ethaddr, 6);
} else {
daddr.sin_addr.s_addr = 0;
}
} else {
- bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
+ bc = find_addr(slirp, &daddr.sin_addr, bp->bp_hwaddr);
if (!bc) {
/* if never assigned, behaves as if it was already
assigned (windows fix because it remembers its address) */
@@ -215,7 +207,7 @@ static void bootp_reply(const struct bootp_t *bp)
}
}
- saddr.sin_addr = vhost_addr;
+ saddr.sin_addr = slirp->vhost_addr;
saddr.sin_port = htons(BOOTP_SERVER);
daddr.sin_port = htons(BOOTP_CLIENT);
@@ -248,9 +240,9 @@ static void bootp_reply(const struct bootp_t *bp)
*q++ = DHCPACK;
}
- if (bootp_filename)
+ if (slirp->bootp_filename)
snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
- bootp_filename);
+ slirp->bootp_filename);
*q++ = RFC2132_SRV_ID;
*q++ = 4;
@@ -259,10 +251,10 @@ static void bootp_reply(const struct bootp_t *bp)
*q++ = RFC1533_NETMASK;
*q++ = 4;
- memcpy(q, &vnetwork_mask, 4);
+ memcpy(q, &slirp->vnetwork_mask, 4);
q += 4;
- if (!slirp_restrict) {
+ if (!slirp->restricted) {
*q++ = RFC1533_GATEWAY;
*q++ = 4;
memcpy(q, &saddr.sin_addr, 4);
@@ -270,7 +262,7 @@ static void bootp_reply(const struct bootp_t *bp)
*q++ = RFC1533_DNS;
*q++ = 4;
- memcpy(q, &vnameserver_addr, 4);
+ memcpy(q, &slirp->vnameserver_addr, 4);
q += 4;
}
@@ -280,11 +272,11 @@ static void bootp_reply(const struct bootp_t *bp)
memcpy(q, &val, 4);
q += 4;
- if (*slirp_hostname) {
- val = strlen(slirp_hostname);
+ if (*slirp->client_hostname) {
+ val = strlen(slirp->client_hostname);
*q++ = RFC1533_HOSTNAME;
*q++ = val;
- memcpy(q, slirp_hostname, val);
+ memcpy(q, slirp->client_hostname, val);
q += val;
}
} else {
@@ -315,6 +307,6 @@ void bootp_input(struct mbuf *m)
struct bootp_t *bp = mtod(m, struct bootp_t *);
if (bp->bp_op == BOOTP_REQUEST) {
- bootp_reply(bp);
+ bootp_reply(m->slirp, bp);
}
}
diff --git a/slirp/bootp.h b/slirp/bootp.h
index 3d80515c98..30c30ab863 100644
--- a/slirp/bootp.h
+++ b/slirp/bootp.h
@@ -112,4 +112,11 @@ struct bootp_t {
uint8_t bp_vend[DHCP_OPT_LEN];
};
+typedef struct {
+ uint16_t allocated;
+ uint8_t macaddr[6];
+} BOOTPClient;
+
+#define NB_BOOTP_CLIENTS 16
+
void bootp_input(struct mbuf *m);
diff --git a/slirp/if.c b/slirp/if.c
index 58ab4c7aca..75b15e400c 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -7,12 +7,6 @@
#include <slirp.h>
-int if_queued = 0; /* Number of packets queued so far */
-
-struct mbuf if_fastq; /* fast queue (for interactive data) */
-struct mbuf if_batchq; /* queue for non-interactive data */
-struct mbuf *next_m; /* Pointer to next mbuf to output */
-
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
static void
@@ -32,11 +26,11 @@ ifs_remque(struct mbuf *ifm)
}
void
-if_init(void)
+if_init(Slirp *slirp)
{
- if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
- if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
- next_m = &if_batchq;
+ slirp->if_fastq.ifq_next = slirp->if_fastq.ifq_prev = &slirp->if_fastq;
+ slirp->if_batchq.ifq_next = slirp->if_batchq.ifq_prev = &slirp->if_batchq;
+ slirp->next_m = &slirp->if_batchq;
}
/*
@@ -55,6 +49,7 @@ if_init(void)
void
if_output(struct socket *so, struct mbuf *ifm)
{
+ Slirp *slirp = ifm->slirp;
struct mbuf *ifq;
int on_fastq = 1;
@@ -79,7 +74,8 @@ if_output(struct socket *so, struct mbuf *ifm)
* We mustn't put this packet back on the fastq (or we'll send it out of order)
* XXX add cache here?
*/
- for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) {
+ for (ifq = slirp->if_batchq.ifq_prev; ifq != &slirp->if_batchq;
+ ifq = ifq->ifq_prev) {
if (so == ifq->ifq_so) {
/* A match! */
ifm->ifq_so = so;
@@ -90,7 +86,7 @@ if_output(struct socket *so, struct mbuf *ifm)
/* No match, check which queue to put it on */
if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
- ifq = if_fastq.ifq_prev;
+ ifq = slirp->if_fastq.ifq_prev;
on_fastq = 1;
/*
* Check if this packet is a part of the last
@@ -102,7 +98,7 @@ if_output(struct socket *so, struct mbuf *ifm)
goto diddit;
}
} else
- ifq = if_batchq.ifq_prev;
+ ifq = slirp->if_batchq.ifq_prev;
/* Create a new doubly linked list for this session */
ifm->ifq_so = so;
@@ -110,7 +106,7 @@ if_output(struct socket *so, struct mbuf *ifm)
insque(ifm, ifq);
diddit:
- ++if_queued;
+ slirp->if_queued++;
if (so) {
/* Update *_queued */
@@ -130,7 +126,7 @@ diddit:
remque(ifm->ifs_next);
/* ...And insert in the new. That'll teach ya! */
- insque(ifm->ifs_next, &if_batchq);
+ insque(ifm->ifs_next, &slirp->if_batchq);
}
}
@@ -138,7 +134,7 @@ diddit:
/*
* This prevents us from malloc()ing too many mbufs
*/
- if_start();
+ if_start(ifm->slirp);
#endif
}
@@ -155,13 +151,13 @@ diddit:
* to the first, etc. etc.
*/
void
-if_start(void)
+if_start(Slirp *slirp)
{
struct mbuf *ifm, *ifqt;
DEBUG_CALL("if_start");
- if (if_queued == 0)
+ if (slirp->if_queued == 0)
return; /* Nothing to do */
again:
@@ -173,22 +169,22 @@ if_start(void)
* See which queue to get next packet from
* If there's something in the fastq, select it immediately
*/
- if (if_fastq.ifq_next != &if_fastq) {
- ifm = if_fastq.ifq_next;
+ if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
+ ifm = slirp->if_fastq.ifq_next;
} else {
/* Nothing on fastq, see if next_m is valid */
- if (next_m != &if_batchq)
- ifm = next_m;
+ if (slirp->next_m != &slirp->if_batchq)
+ ifm = slirp->next_m;
else
- ifm = if_batchq.ifq_next;
+ ifm = slirp->if_batchq.ifq_next;
/* Set which packet to send on next iteration */
- next_m = ifm->ifq_next;
+ slirp->next_m = ifm->ifq_next;
}
/* Remove it from the queue */
ifqt = ifm->ifq_prev;
remque(ifm);
- --if_queued;
+ slirp->if_queued--;
/* If there are more packets for this session, re-queue them */
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
@@ -204,10 +200,10 @@ if_start(void)
}
/* Encapsulate the packet for sending */
- if_encap((uint8_t *)ifm->m_data, ifm->m_len);
+ if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len);
m_free(ifm);
- if (if_queued)
+ if (slirp->if_queued)
goto again;
}
diff --git a/slirp/if.h b/slirp/if.h
index 2fdc354508..2dac1c7a10 100644
--- a/slirp/if.h
+++ b/slirp/if.h
@@ -20,12 +20,6 @@
/* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
#define IF_MAXLINKHDR (2 + 14 + 40)
-extern int if_queued; /* Number of packets queued so far */
-
-extern struct mbuf if_fastq; /* fast queue (for interactive data) */
-extern struct mbuf if_batchq; /* queue for non-interactive data */
-extern struct mbuf *next_m;
-
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
#endif
diff --git a/slirp/ip.h b/slirp/ip.h
index e0d76748b2..574fc019ae 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -250,7 +250,4 @@ struct ipoption {
int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
};
-extern struct ipq ipq; /* ip reass. queue */
-extern u_int16_t ip_id; /* ip packet ctr, for ids */
-
#endif
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 66b4d2351b..95a4b39a4e 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -69,6 +69,7 @@ icmp_input(struct mbuf *m, int hlen)
register struct icmp *icp;
register struct ip *ip=mtod(m, struct ip *);
int icmplen=ip->ip_len;
+ Slirp *slirp = m->slirp;
DEBUG_CALL("icmp_input");
DEBUG_ARG("m = %lx", (long )m);
@@ -98,12 +99,12 @@ icmp_input(struct mbuf *m, int hlen)
case ICMP_ECHO:
icp->icmp_type = ICMP_ECHOREPLY;
ip->ip_len += hlen; /* since ip_input subtracts this */
- if (ip->ip_dst.s_addr == vhost_addr.s_addr) {
+ if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
icmp_reflect(m);
} else {
struct socket *so;
struct sockaddr_in addr;
- if ((so = socreate()) == NULL) goto freeit;
+ if ((so = socreate(slirp)) == NULL) goto freeit;
if(udp_attach(so) == -1) {
DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
errno,strerror(errno)));
@@ -122,10 +123,10 @@ icmp_input(struct mbuf *m, int hlen)
/* Send the packet */
addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
- vnetwork_addr.s_addr) {
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
/* It's an alias */
- if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
+ if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
addr.sin_addr = dns_addr;
} else {
addr.sin_addr = loopback_addr;
@@ -222,7 +223,11 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
}
/* make a copy */
- if(!(m=m_get())) goto end_error; /* get mbuf */
+ m = m_get(msrc->slirp);
+ if (!m) {
+ goto end_error;
+ }
+
{ int new_m_size;
new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
if(new_m_size>m->m_size) m_inc(m, new_m_size);
@@ -285,7 +290,7 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
ip->ip_ttl = MAXTTL;
ip->ip_p = IPPROTO_ICMP;
ip->ip_dst = ip->ip_src; /* ip adresses */
- ip->ip_src = vhost_addr;
+ ip->ip_src = m->slirp->vhost_addr;
(void ) ip_output((struct socket *)NULL, m);
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index b07d3d5d5d..35230f8d10 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -42,11 +42,8 @@
#include <osdep.h>
#include "ip_icmp.h"
-struct ipq ipq;
-
-static struct ip *ip_reass(register struct ip *ip,
- register struct ipq *fp);
-static void ip_freef(struct ipq *fp);
+static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp);
+static void ip_freef(Slirp *slirp, struct ipq *fp);
static void ip_enq(register struct ipasfrag *p,
register struct ipasfrag *prev);
static void ip_deq(register struct ipasfrag *p);
@@ -56,11 +53,11 @@ static void ip_deq(register struct ipasfrag *p);
* All protocols not implemented in kernel go to raw IP protocol handler.
*/
void
-ip_init(void)
+ip_init(Slirp *slirp)
{
- ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
- udp_init();
- tcp_init();
+ slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link;
+ udp_init(slirp);
+ tcp_init(slirp);
}
/*
@@ -70,6 +67,7 @@ ip_init(void)
void
ip_input(struct mbuf *m)
{
+ Slirp *slirp = m->slirp;
register struct ip *ip;
int hlen;
@@ -120,19 +118,19 @@ ip_input(struct mbuf *m)
goto bad;
}
- if (slirp_restrict) {
- if ((ip->ip_dst.s_addr & vnetwork_mask.s_addr) ==
- vnetwork_addr.s_addr) {
+ if (slirp->restricted) {
+ if ((ip->ip_dst.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
goto bad;
} else {
+ uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
struct ex_list *ex_ptr;
- if ((ip->ip_dst.s_addr & ~vnetwork_mask.s_addr) ==
- ~vnetwork_mask.s_addr)
+ if ((ip->ip_dst.s_addr & inv_mask) == inv_mask) {
goto bad;
-
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+ }
+ for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr)
break;
@@ -167,7 +165,8 @@ ip_input(struct mbuf *m)
* Look for queue of fragments
* of this datagram.
*/
- for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
+ for (l = slirp->ipq.ip_link.next; l != &slirp->ipq.ip_link;
+ l = l->next) {
fp = container_of(l, struct ipq, ip_link);
if (ip->ip_id == fp->ipq_id &&
ip->ip_src.s_addr == fp->ipq_src.s_addr &&
@@ -197,13 +196,13 @@ ip_input(struct mbuf *m)
* attempt reassembly; if it succeeds, proceed.
*/
if (ip->ip_tos & 1 || ip->ip_off) {
- ip = ip_reass(ip, fp);
+ ip = ip_reass(slirp, ip, fp);
if (ip == NULL)
return;
- m = dtom(ip);
+ m = dtom(slirp, ip);
} else
if (fp)
- ip_freef(fp);
+ ip_freef(slirp, fp);
} else
ip->ip_len -= hlen;
@@ -239,9 +238,9 @@ bad:
* is given as fp; otherwise have to make a chain.
*/
static struct ip *
-ip_reass(register struct ip *ip, register struct ipq *fp)
+ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
{
- register struct mbuf *m = dtom(ip);
+ register struct mbuf *m = dtom(slirp, ip);
register struct ipasfrag *q;
int hlen = ip->ip_hl << 2;
int i, next;
@@ -263,10 +262,13 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
* If first fragment to arrive, create a reassembly queue.
*/
if (fp == NULL) {
- struct mbuf *t;
- if ((t = m_get()) == NULL) goto dropfrag;
+ struct mbuf *t = m_get(slirp);
+
+ if (t == NULL) {
+ goto dropfrag;
+ }
fp = mtod(t, struct ipq *);
- insque(&fp->ip_link, &ipq.ip_link);
+ insque(&fp->ip_link, &slirp->ipq.ip_link);
fp->ipq_ttl = IPFRAGTTL;
fp->ipq_p = ip->ip_p;
fp->ipq_id = ip->ip_id;
@@ -296,7 +298,7 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
if (i > 0) {
if (i >= ip->ip_len)
goto dropfrag;
- m_adj(dtom(ip), i);
+ m_adj(dtom(slirp, ip), i);
ip->ip_off += i;
ip->ip_len -= i;
}
@@ -312,11 +314,11 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
if (i < q->ipf_len) {
q->ipf_len -= i;
q->ipf_off += i;
- m_adj(dtom(q), i);
+ m_adj(dtom(slirp, q), i);
break;
}
q = q->ipf_next;
- m_freem(dtom(q->ipf_prev));
+ m_freem(dtom(slirp, q->ipf_prev));
ip_deq(q->ipf_prev);
}
@@ -340,11 +342,11 @@ insert:
* Reassembly is complete; concatenate fragments.
*/
q = fp->frag_link.next;
- m = dtom(q);
+ m = dtom(slirp, q);
q = (struct ipasfrag *) q->ipf_next;
while (q != (struct ipasfrag*)&fp->frag_link) {
- struct mbuf *t = dtom(q);
+ struct mbuf *t = dtom(slirp, q);
q = (struct ipasfrag *) q->ipf_next;
m_cat(m, t);
}
@@ -375,7 +377,7 @@ insert:
ip->ip_src = fp->ipq_src;
ip->ip_dst = fp->ipq_dst;
remque(&fp->ip_link);
- (void) m_free(dtom(fp));
+ (void) m_free(dtom(slirp, fp));
m->m_len += (ip->ip_hl << 2);
m->m_data -= (ip->ip_hl << 2);
@@ -391,17 +393,17 @@ dropfrag:
* associated datagrams.
*/
static void
-ip_freef(struct ipq *fp)
+ip_freef(Slirp *slirp, struct ipq *fp)
{
register struct ipasfrag *q, *p;
for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
p = q->ipf_next;
ip_deq(q);
- m_freem(dtom(q));
+ m_freem(dtom(slirp, q));
}
remque(&fp->ip_link);
- (void) m_free(dtom(fp));
+ (void) m_free(dtom(slirp, fp));
}
/*
@@ -435,24 +437,24 @@ ip_deq(register struct ipasfrag *p)
* queue, discard it.
*/
void
-ip_slowtimo(void)
+ip_slowtimo(Slirp *slirp)
{
struct qlink *l;
DEBUG_CALL("ip_slowtimo");
- l = ipq.ip_link.next;
+ l = slirp->ipq.ip_link.next;
if (l == NULL)
return;
- while (l != &ipq.ip_link) {
+ while (l != &slirp->ipq.ip_link) {
struct ipq *fp = container_of(l, struct ipq, ip_link);
l = l->next;
if (--fp->ipq_ttl == 0) {
- ip_freef(fp);
+ ip_freef(slirp, fp);
}
- }
+ }
}
/*
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index 3031f4d112..dba278478b 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -40,8 +40,6 @@
#include <slirp.h>
-u_int16_t ip_id;
-
/* Number of packets queued before we start sending
* (to prevent allocing too many mbufs) */
#define IF_THRESH 10
@@ -55,6 +53,7 @@ u_int16_t ip_id;
int
ip_output(struct socket *so, struct mbuf *m0)
{
+ Slirp *slirp = m0->slirp;
register struct ip *ip;
register struct mbuf *m = m0;
register int hlen = sizeof(struct ip );
@@ -70,7 +69,7 @@ ip_output(struct socket *so, struct mbuf *m0)
*/
ip->ip_v = IPVERSION;
ip->ip_off &= IP_DF;
- ip->ip_id = htons(ip_id++);
+ ip->ip_id = htons(slirp->ip_id++);
ip->ip_hl = hlen >> 2;
/*
@@ -113,7 +112,7 @@ ip_output(struct socket *so, struct mbuf *m0)
mhlen = sizeof (struct ip);
for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
register struct ip *mhip;
- m = m_get();
+ m = m_get(slirp);
if (m == NULL) {
error = -1;
goto sendorfree;
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index b0496d546f..3bda69194e 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,9 @@
#ifdef CONFIG_SLIRP
+struct Slirp;
+typedef struct Slirp Slirp;
+
void slirp_init(int restricted, struct in_addr vnetwork,
struct in_addr vnetmask, struct in_addr vhost,
const char *vhostname, const char *tftp_path,
diff --git a/slirp/main.h b/slirp/main.h
index 6fd38f9b62..90deb58b27 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -31,11 +31,6 @@ extern char *slirp_tty;
extern char *exec_shell;
extern u_int curtime;
extern fd_set *global_readfds, *global_writefds, *global_xfds;
-extern struct in_addr vnetwork_addr;
-extern struct in_addr vnetwork_mask;
-extern struct in_addr vhost_addr;
-extern struct in_addr vdhcp_startaddr;
-extern struct in_addr vnameserver_addr;
extern struct in_addr our_addr;
extern struct in_addr loopback_addr;
extern struct in_addr dns_addr;
@@ -44,16 +39,11 @@ extern char *socket_path;
extern int towrite_max;
extern int ppp_exit;
extern int tcp_keepintvl;
-extern uint8_t client_ethaddr[6];
-extern int slirp_restrict;
-extern char slirp_hostname[33];
-extern char *tftp_prefix;
-extern char *bootp_filename;
#define PROTO_SLIP 0x1
#ifdef USE_PPP
#define PROTO_PPP 0x2
#endif
-void if_encap(const uint8_t *ip_data, int ip_data_len);
+void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len);
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 888de86e45..7652fea196 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -17,8 +17,6 @@
#include <slirp.h>
-static int mbuf_alloced;
-struct mbuf m_freelist, m_usedlist;
#define MBUF_THRESH 30
/*
@@ -28,10 +26,10 @@ struct mbuf m_freelist, m_usedlist;
#define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
void
-m_init(void)
+m_init(Slirp *slirp)
{
- m_freelist.m_next = m_freelist.m_prev = &m_freelist;
- m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
+ slirp->m_freelist.m_next = slirp->m_freelist.m_prev = &slirp->m_freelist;
+ slirp->m_usedlist.m_next = slirp->m_usedlist.m_prev = &slirp->m_usedlist;
}
/*
@@ -43,26 +41,27 @@ m_init(void)
* which tells m_free to actually free() it
*/
struct mbuf *
-m_get(void)
+m_get(Slirp *slirp)
{
register struct mbuf *m;
int flags = 0;
DEBUG_CALL("m_get");
- if (m_freelist.m_next == &m_freelist) {
+ if (slirp->m_freelist.m_next == &slirp->m_freelist) {
m = (struct mbuf *)malloc(SLIRP_MSIZE);
if (m == NULL) goto end_error;
- mbuf_alloced++;
- if (mbuf_alloced > MBUF_THRESH)
+ slirp->mbuf_alloced++;
+ if (slirp->mbuf_alloced > MBUF_THRESH)
flags = M_DOFREE;
+ m->slirp = slirp;
} else {
- m = m_freelist.m_next;
+ m = slirp->m_freelist.m_next;
remque(m);
}
/* Insert it in the used list */
- insque(m,&m_usedlist);
+ insque(m,&slirp->m_usedlist);
m->m_flags = (flags | M_USEDLIST);
/* Initialise it */
@@ -97,9 +96,9 @@ m_free(struct mbuf *m)
*/
if (m->m_flags & M_DOFREE) {
free(m);
- mbuf_alloced--;
+ m->slirp->mbuf_alloced--;
} else if ((m->m_flags & M_FREELIST) == 0) {
- insque(m,&m_freelist);
+ insque(m,&m->slirp->m_freelist);
m->m_flags = M_FREELIST; /* Clobber other flags */
}
} /* if(m) */
@@ -194,7 +193,7 @@ m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
* Fortunately, it's not used often
*/
struct mbuf *
-dtom(void *dat)
+dtom(Slirp *slirp, void *dat)
{
struct mbuf *m;
@@ -202,7 +201,8 @@ dtom(void *dat)
DEBUG_ARG("dat = %lx", (long )dat);
/* bug corrected for M_EXT buffers */
- for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
+ for (m = slirp->m_usedlist.m_next; m != &slirp->m_usedlist;
+ m = m->m_next) {
if (m->m_flags & M_EXT) {
if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
return m;
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index c482753fef..99fca43898 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -84,6 +84,7 @@ struct m_hdr {
struct mbuf {
struct m_hdr m_hdr;
+ Slirp *slirp;
union M_dat {
char m_dat_[1]; /* ANSI don't like 0 sized arrays */
char *m_ext_;
@@ -114,15 +115,13 @@ struct mbuf {
#define M_DOFREE 0x08 /* when m_free is called on the mbuf, free()
* it rather than putting it on the free list */
-extern struct mbuf m_freelist, m_usedlist;
-
-void m_init _P((void));
-struct mbuf * m_get _P((void));
+void m_init _P((Slirp *));
+struct mbuf * m_get _P((Slirp *));
void m_free _P((struct mbuf *));
void m_cat _P((register struct mbuf *, register struct mbuf *));
void m_inc _P((struct mbuf *, int));
void m_adj _P((struct mbuf *, int));
int m_copy _P((struct mbuf *, struct mbuf *, int, int));
-struct mbuf * dtom _P((void *));
+struct mbuf * dtom _P((Slirp *, void *));
#endif
diff --git a/slirp/misc.c b/slirp/misc.c
index ee14db5e38..c2b66fd967 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -385,6 +385,7 @@ void slirp_connection_info(Monitor *mon)
[TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
[TCPS_TIME_WAIT] = "TIME_WAIT",
};
+ Slirp *slirp = &slirp_instance;
struct in_addr dst_addr;
struct sockaddr_in src;
socklen_t src_len;
@@ -397,7 +398,7 @@ void slirp_connection_info(Monitor *mon)
monitor_printf(mon, " Protocol[State] FD Source Address Port "
"Dest. Address Port RecvQ SendQ\n");
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
+ for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
if (so->so_state & SS_HOSTFWD) {
state = "HOST_FORWARD";
} else if (so->so_tcpcb) {
@@ -427,7 +428,7 @@ void slirp_connection_info(Monitor *mon)
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
- for (so = udb.so_next; so != &udb; so = so->so_next) {
+ for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
if (so->so_state & SS_HOSTFWD) {
n = snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]");
src_len = sizeof(src);
diff --git a/slirp/misc.h b/slirp/misc.h
index 2f478885de..e43519dcba 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -16,8 +16,6 @@ struct ex_list {
struct ex_list *ex_next;
};
-extern struct ex_list *exec_list;
-
#ifndef HAVE_STRDUP
char *strdup _P((const char *));
#endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 71f79a3630..25bc8a4c57 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -33,27 +33,14 @@ struct in_addr dns_addr;
/* host loopback address */
struct in_addr loopback_addr;
-/* virtual network configuration */
-struct in_addr vnetwork_addr;
-struct in_addr vnetwork_mask;
-struct in_addr vhost_addr;
-struct in_addr vdhcp_startaddr;
-struct in_addr vnameserver_addr;
-
/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
static const uint8_t special_ethaddr[6] = {
0x52, 0x55, 0x00, 0x00, 0x00, 0x00
};
-/* ARP cache for the guest IP addresses (XXX: allow many entries) */
-uint8_t client_ethaddr[6];
-static struct in_addr client_ipaddr;
-
static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
-int slirp_restrict;
-int link_up;
-struct ex_list *exec_list;
+int link_up; // FIXME: kill this
/* XXX: suppress those select globals */
fd_set *global_readfds, *global_writefds, *global_xfds;
@@ -62,7 +49,7 @@ u_int curtime;
static u_int time_fasttimo, last_slowtimo;
static int do_slowtimo;
-char slirp_hostname[33];
+Slirp slirp_instance;
#ifdef _WIN32
@@ -206,37 +193,40 @@ void slirp_init(int restricted, struct in_addr vnetwork,
const char *bootfile, struct in_addr vdhcp_start,
struct in_addr vnameserver)
{
+ Slirp *slirp = &slirp_instance;
+
slirp_init_once();
link_up = 1;
- slirp_restrict = restricted;
+ slirp->restricted = restricted;
- if_init();
- ip_init();
+ if_init(slirp);
+ ip_init(slirp);
/* Initialise mbufs *after* setting the MTU */
- m_init();
+ m_init(slirp);
- vnetwork_addr = vnetwork;
- vnetwork_mask = vnetmask;
- vhost_addr = vhost;
+ slirp->vnetwork_addr = vnetwork;
+ slirp->vnetwork_mask = vnetmask;
+ slirp->vhost_addr = vhost;
if (vhostname) {
- pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);
+ pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
+ vhostname);
}
- qemu_free(tftp_prefix);
- tftp_prefix = NULL;
+ qemu_free(slirp->tftp_prefix);
+ slirp->tftp_prefix = NULL;
if (tftp_path) {
- tftp_prefix = qemu_strdup(tftp_path);
+ slirp->tftp_prefix = qemu_strdup(tftp_path);
}
- qemu_free(bootp_filename);
- bootp_filename = NULL;
+ qemu_free(slirp->bootp_filename);
+ slirp->bootp_filename = NULL;
if (bootfile) {
- bootp_filename = qemu_strdup(bootfile);
+ slirp->bootp_filename = qemu_strdup(bootfile);
}
- vdhcp_startaddr = vdhcp_start;
- vnameserver_addr = vnameserver;
+ slirp->vdhcp_startaddr = vdhcp_start;
+ slirp->vnameserver_addr = vnameserver;
- register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, NULL);
+ register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp);
}
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
@@ -269,6 +259,7 @@ static void updtime(void)
void slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
+ Slirp *slirp = &slirp_instance;
struct socket *so, *so_next;
int nfds;
@@ -291,10 +282,11 @@ void slirp_select_fill(int *pnfds,
* *_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));
+ do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
+ (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
- for (so = tcb.so_next; so != &tcb; so = so_next) {
+ for (so = slirp->tcb.so_next; so != &slirp->tcb;
+ so = so_next) {
so_next = so->so_next;
/*
@@ -351,7 +343,8 @@ void slirp_select_fill(int *pnfds,
/*
* UDP sockets
*/
- for (so = udb.so_next; so != &udb; so = so_next) {
+ for (so = slirp->udb.so_next; so != &slirp->udb;
+ so = so_next) {
so_next = so->so_next;
/*
@@ -387,6 +380,7 @@ void slirp_select_fill(int *pnfds,
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
int select_error)
{
+ Slirp *slirp = &slirp_instance;
struct socket *so, *so_next;
int ret;
@@ -405,12 +399,12 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
* See if anything has timed out
*/
if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
- tcp_fasttimo();
+ tcp_fasttimo(slirp);
time_fasttimo = 0;
}
if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
- ip_slowtimo();
- tcp_slowtimo();
+ ip_slowtimo(slirp);
+ tcp_slowtimo(slirp);
last_slowtimo = curtime;
}
@@ -421,7 +415,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
/*
* Check TCP sockets
*/
- for (so = tcb.so_next; so != &tcb; so = so_next) {
+ for (so = slirp->tcb.so_next; so != &slirp->tcb;
+ so = so_next) {
so_next = so->so_next;
/*
@@ -538,7 +533,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
* 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) {
+ for (so = slirp->udb.so_next; so != &slirp->udb;
+ so = so_next) {
so_next = so->so_next;
if (so->s != -1 && FD_ISSET(so->s, readfds)) {
@@ -550,8 +546,9 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
/*
* See if we can start outputting
*/
- if (if_queued)
- if_start();
+ if (slirp->if_queued) {
+ if_start(slirp);
+ }
/* clear global file descriptor sets.
* these reside on the stack in vl.c
@@ -596,7 +593,7 @@ struct arphdr
uint32_t ar_tip ; /* target IP address */
} __attribute__((packed));
-static void arp_input(const uint8_t *pkt, int pkt_len)
+static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
{
struct ethhdr *eh = (struct ethhdr *)pkt;
struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
@@ -609,18 +606,19 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
ar_op = ntohs(ah->ar_op);
switch(ar_op) {
case ARPOP_REQUEST:
- if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
- if (ah->ar_tip == vnameserver_addr.s_addr ||
- ah->ar_tip == vhost_addr.s_addr)
+ if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
+ if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
+ ah->ar_tip == slirp->vhost_addr.s_addr)
goto arp_ok;
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
goto arp_ok;
}
return;
arp_ok:
/* XXX: make an ARP request to have the client address */
- memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
+ memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
/* ARP request for alias/dns mac address */
memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
@@ -642,9 +640,9 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
break;
case ARPOP_REPLY:
/* reply to request of client mac address ? */
- if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
- ah->ar_sip == client_ipaddr.s_addr) {
- memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
+ if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
+ ah->ar_sip == slirp->client_ipaddr.s_addr) {
+ memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
}
break;
default:
@@ -654,6 +652,7 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
void slirp_input(const uint8_t *pkt, int pkt_len)
{
+ Slirp *slirp = &slirp_instance;
struct mbuf *m;
int proto;
@@ -663,10 +662,10 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
proto = ntohs(*(uint16_t *)(pkt + 12));
switch(proto) {
case ETH_P_ARP:
- arp_input(pkt, pkt_len);
+ arp_input(slirp, pkt, pkt_len);
break;
case ETH_P_IP:
- m = m_get();
+ m = m_get(slirp);
if (!m)
return;
/* Note: we add to align the IP header */
@@ -687,7 +686,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
}
/* output the IP packet to the ethernet device */
-void if_encap(const uint8_t *ip_data, int ip_data_len)
+void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
{
uint8_t buf[1600];
struct ethhdr *eh = (struct ethhdr *)buf;
@@ -695,7 +694,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
if (ip_data_len + ETH_HLEN > sizeof(buf))
return;
- if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
+ if (!memcmp(slirp->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);
@@ -708,7 +707,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
will retry sending its packet. */
memset(reh->h_dest, 0xff, ETH_ALEN);
memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
- memcpy(&reh->h_source[2], &vhost_addr, 4);
+ memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
reh->h_proto = htons(ETH_P_ARP);
rah->ar_hrd = htons(1);
rah->ar_pro = htons(ETH_P_IP);
@@ -717,20 +716,20 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
rah->ar_op = htons(ARPOP_REQUEST);
/* source hw addr */
memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
- memcpy(&rah->ar_sha[2], &vhost_addr, 4);
+ memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
/* source IP */
- rah->ar_sip = vhost_addr.s_addr;
+ rah->ar_sip = slirp->vhost_addr.s_addr;
/* target hw addr (none) */
memset(rah->ar_tha, 0, ETH_ALEN);
/* target IP */
rah->ar_tip = iph->ip_dst.s_addr;
- client_ipaddr = iph->ip_dst;
+ slirp->client_ipaddr = iph->ip_dst;
slirp_output(arp_req, sizeof(arp_req));
} else {
- memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
+ memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
/* XXX: not correct */
- memcpy(&eh->h_source[2], &vhost_addr, 4);
+ memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
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);
@@ -740,8 +739,9 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
/* Drop host forwarding rule, return 0 if found. */
int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
{
+ Slirp *slirp = &slirp_instance;
struct socket *so;
- struct socket *head = (is_udp ? &udb : &tcb);
+ struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
struct sockaddr_in addr;
int port = htons(host_port);
socklen_t addr_len;
@@ -764,16 +764,18 @@ int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
struct in_addr guest_addr, int guest_port)
{
+ Slirp *slirp = &slirp_instance;
+
if (!guest_addr.s_addr) {
- guest_addr = vdhcp_startaddr;
+ guest_addr = slirp->vdhcp_startaddr;
}
if (is_udp) {
- if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
- htons(guest_port), SS_HOSTFWD))
+ if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
+ guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
return -1;
} else {
- if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
- htons(guest_port), SS_HOSTFWD))
+ if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
+ guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
return -1;
}
return 0;
@@ -782,16 +784,19 @@ int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
int guest_port)
{
+ Slirp *slirp = &slirp_instance;
+
if (!guest_addr.s_addr) {
- guest_addr.s_addr =
- vnetwork_addr.s_addr | (htonl(0x0204) & ~vnetwork_mask.s_addr);
+ guest_addr.s_addr = slirp->vnetwork_addr.s_addr |
+ (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
}
- if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
- guest_addr.s_addr == vhost_addr.s_addr ||
- guest_addr.s_addr == vnameserver_addr.s_addr) {
+ if ((guest_addr.s_addr & slirp->vnetwork_mask.s_addr) !=
+ slirp->vnetwork_addr.s_addr ||
+ guest_addr.s_addr == slirp->vhost_addr.s_addr ||
+ guest_addr.s_addr == slirp->vnameserver_addr.s_addr) {
return -1;
}
- return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
+ return add_exec(&slirp->exec_list, do_pty, (char *)args, guest_addr,
htons(guest_port));
}
@@ -806,11 +811,11 @@ ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
}
static struct socket *
-slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
+slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
{
struct socket *so;
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
+ for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
if (so->so_faddr.s_addr == guest_addr.s_addr &&
htons(so->so_fport) == guest_port) {
return so;
@@ -821,10 +826,11 @@ slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
{
+ Slirp *slirp = &slirp_instance;
struct iovec iov[2];
struct socket *so;
- so = slirp_find_ctl_socket(guest_addr, guest_port);
+ so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
if (!so || so->so_state & SS_NOFDREF)
return 0;
@@ -838,8 +844,9 @@ size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
const uint8_t *buf, int size)
{
+ Slirp *slirp = &slirp_instance;
int ret;
- struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
+ struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
if (!so)
return;
@@ -928,12 +935,14 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
static void slirp_state_save(QEMUFile *f, void *opaque)
{
+ Slirp *slirp = opaque;
struct ex_list *ex_ptr;
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+ for (ex_ptr = slirp->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));
+ so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
+ ntohs(ex_ptr->ex_fport));
if (!so)
continue;
@@ -942,7 +951,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
}
qemu_put_byte(f, 0);
- qemu_put_be16(f, ip_id);
+ qemu_put_be16(f, slirp->ip_id);
}
static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
@@ -1041,12 +1050,13 @@ static int slirp_socket_load(QEMUFile *f, struct socket *so)
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
{
+ Slirp *slirp = opaque;
struct ex_list *ex_ptr;
int r;
while ((r = qemu_get_byte(f))) {
int ret;
- struct socket *so = socreate();
+ struct socket *so = socreate(slirp);
if (!so)
return -ENOMEM;
@@ -1056,11 +1066,11 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
if (ret < 0)
return ret;
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
- vnetwork_addr.s_addr) {
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
+ slirp->vnetwork_addr.s_addr) {
return -EINVAL;
}
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_pty == 3 &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
so->so_fport == ex_ptr->ex_fport) {
@@ -1074,7 +1084,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
}
if (version_id >= 2) {
- ip_id = qemu_get_be16(f);
+ slirp->ip_id = qemu_get_be16(f);
}
return 0;
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 063e5f6c18..b1e8d4e6c6 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -185,6 +185,7 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
#include "debug.h"
+#include "libslirp.h"
#include "ip.h"
#include "tcp.h"
#include "tcp_timer.h"
@@ -204,14 +205,67 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
#include "bootp.h"
#include "tftp.h"
-#include "libslirp.h"
+
+struct Slirp {
+ /* virtual network configuration */
+ struct in_addr vnetwork_addr;
+ struct in_addr vnetwork_mask;
+ struct in_addr vhost_addr;
+ struct in_addr vdhcp_startaddr;
+ struct in_addr vnameserver_addr;
+
+ /* ARP cache for the guest IP addresses (XXX: allow many entries) */
+ uint8_t client_ethaddr[6];
+
+ struct in_addr client_ipaddr;
+ char client_hostname[33];
+
+ int restricted;
+ struct timeval tt;
+ struct ex_list *exec_list;
+
+ /* mbuf states */
+ struct mbuf m_freelist, m_usedlist;
+ int mbuf_alloced;
+
+ /* if states */
+ int if_queued; /* number of packets queued so far */
+ struct mbuf if_fastq; /* fast queue (for interactive data) */
+ struct mbuf if_batchq; /* queue for non-interactive data */
+ struct mbuf *next_m; /* pointer to next mbuf to output */
+
+ /* ip states */
+ struct ipq ipq; /* ip reass. queue */
+ u_int16_t ip_id; /* ip packet ctr, for ids */
+
+ /* bootp/dhcp states */
+ BOOTPClient bootp_clients[NB_BOOTP_CLIENTS];
+ char *bootp_filename;
+
+ /* tcp states */
+ struct socket tcb;
+ struct socket *tcp_last_so;
+ tcp_seq tcp_iss; /* tcp initial send seq # */
+ u_int32_t tcp_now; /* for RFC 1323 timestamps */
+
+ /* udp states */
+ struct socket udb;
+ struct socket *udp_last_so;
+
+ /* tftp states */
+ char *tftp_prefix;
+ struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
+
+};
+
+extern Slirp slirp_instance;
#ifndef NULL
#define NULL (void *)0
#endif
#ifndef FULL_BOLT
-void if_start _P((void));
+void if_start _P((Slirp *));
#else
void if_start _P((struct ttys *));
#endif
@@ -257,13 +311,13 @@ void lprint _P((const char *, ...));
int cksum(struct mbuf *m, int len);
/* if.c */
-void if_init _P((void));
+void if_init _P((Slirp *));
void if_output _P((struct socket *, struct mbuf *));
/* ip_input.c */
-void ip_init _P((void));
+void ip_init _P((Slirp *));
void ip_input _P((struct mbuf *));
-void ip_slowtimo _P((void));
+void ip_slowtimo _P((Slirp *));
void ip_stripoptions _P((register struct mbuf *, struct mbuf *));
/* ip_output.c */
@@ -278,7 +332,7 @@ int tcp_output _P((register struct tcpcb *));
void tcp_setpersist _P((register struct tcpcb *));
/* tcp_subr.c */
-void tcp_init _P((void));
+void tcp_init _P((Slirp *));
void tcp_template _P((struct tcpcb *));
void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int));
struct tcpcb * tcp_newtcpcb _P((struct socket *));
diff --git a/slirp/socket.c b/slirp/socket.c
index f7b212fba8..d8fbe89a74 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -41,7 +41,7 @@ solookup(struct socket *head, struct in_addr laddr, u_int lport,
* insque() it into the correct linked-list
*/
struct socket *
-socreate(void)
+socreate(Slirp *slirp)
{
struct socket *so;
@@ -50,6 +50,7 @@ socreate(void)
memset(so, 0, sizeof(struct socket));
so->so_state = SS_NOFDREF;
so->s = -1;
+ so->slirp = slirp;
}
return(so);
}
@@ -60,15 +61,17 @@ socreate(void)
void
sofree(struct socket *so)
{
+ Slirp *slirp = so->slirp;
+
if (so->so_emu==EMU_RSH && so->extra) {
sofree(so->extra);
so->extra=NULL;
}
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
- else if (so == udp_last_so)
- udp_last_so = &udb;
-
+ if (so == slirp->tcp_last_so) {
+ slirp->tcp_last_so = &slirp->tcb;
+ } else if (so == slirp->udp_last_so) {
+ slirp->udp_last_so = &slirp->udb;
+ }
m_free(so->so_m);
if(so->so_next && so->so_prev)
@@ -473,7 +476,10 @@ sorecvfrom(struct socket *so)
int n;
#endif
- if (!(m = m_get())) return;
+ m = m_get(so->slirp);
+ if (!m) {
+ return;
+ }
m->m_data += IF_MAXLINKHDR;
/*
@@ -533,6 +539,7 @@ sorecvfrom(struct socket *so)
int
sosendto(struct socket *so, struct mbuf *m)
{
+ Slirp *slirp = so->slirp;
int ret;
struct sockaddr_in addr;
@@ -541,10 +548,10 @@ sosendto(struct socket *so, struct mbuf *m)
DEBUG_ARG("m = %lx", (long)m);
addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
- vnetwork_addr.s_addr) {
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
/* It's an alias */
- if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
+ if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
addr.sin_addr = dns_addr;
} else {
addr.sin_addr = loopback_addr;
@@ -576,7 +583,8 @@ sosendto(struct socket *so, struct mbuf *m)
* Listen for incoming TCP connections
*/
struct socket *
-tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags)
+tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
+ u_int lport, int flags)
{
struct sockaddr_in addr;
struct socket *so;
@@ -590,7 +598,8 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
DEBUG_ARG("lport = %d", lport);
DEBUG_ARG("flags = %x", flags);
- if ((so = socreate()) == NULL) {
+ so = socreate(slirp);
+ if (!so) {
return NULL;
}
@@ -599,7 +608,7 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
free(so);
return NULL;
}
- insque(so,&tcb);
+ insque(so, &slirp->tcb);
/*
* SS_FACCEPTONCE sockets must time out.
@@ -637,7 +646,7 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
getsockname(s,(struct sockaddr *)&addr,&addrlen);
so->so_fport = addr.sin_port;
if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
- so->so_faddr = vhost_addr;
+ so->so_faddr = slirp->vhost_addr;
else
so->so_faddr = addr.sin_addr;
diff --git a/slirp/socket.h b/slirp/socket.h
index 4db2147aa8..dcf27430b2 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -20,6 +20,8 @@ struct socket {
int s; /* The actual socket */
+ Slirp *slirp; /* managing slirp instance */
+
/* XXX union these with not-yet-used sbuf params */
struct mbuf *so_m; /* Pointer to the original SYN packet,
* for non-blocking connect()'s, and
@@ -72,10 +74,8 @@ struct socket {
#define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */
#define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */
-extern struct socket tcb;
-
struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
-struct socket * socreate _P((void));
+struct socket * socreate _P((Slirp *));
void sofree _P((struct socket *));
int soread _P((struct socket *));
void sorecvoob _P((struct socket *));
@@ -83,7 +83,8 @@ int sosendoob _P((struct socket *));
int sowrite _P((struct socket *));
void sorecvfrom _P((struct socket *));
int sosendto _P((struct socket *, struct mbuf *));
-struct socket * tcp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int));
+struct socket * tcp_listen _P((Slirp *, u_int32_t, u_int, u_int32_t, u_int,
+ int));
void soisfconnecting _P((register struct socket *));
void soisfconnected _P((register struct socket *));
void sofwdrain _P((struct socket *));
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 4a18ed8821..c65ed43423 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -38,8 +38,6 @@ typedef u_int32_t tcp_seq;
#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */
#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */
-extern struct socket *tcp_last_so;
-
#define TCP_SNDSPACE 8192
#define TCP_RCVSPACE 8192
@@ -163,6 +161,4 @@ struct tcphdr {
#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
-extern tcp_seq tcp_iss; /* tcp initial send seq # */
-
#endif
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index b7a67e561f..47cf0ad8c7 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -41,12 +41,7 @@
#include <slirp.h>
#include "ip_icmp.h"
-struct socket tcb;
-
#define TCPREXMTTHRESH 3
-struct socket *tcp_last_so = &tcb;
-
-tcp_seq tcp_iss; /* tcp initial send seq # */
#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
@@ -233,6 +228,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
u_long tiwin;
int ret;
struct ex_list *ex_ptr;
+ Slirp *slirp;
DEBUG_CALL("tcp_input");
DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
@@ -243,6 +239,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
*/
if (m == NULL) {
so = inso;
+ slirp = so->slirp;
/* Re-set a few variables */
tp = sototcpcb(so);
@@ -254,6 +251,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
goto cont_conn;
}
+ slirp = m->slirp;
/*
* Get IP and TCP header together in first mbuf.
@@ -318,8 +316,8 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- if (slirp_restrict) {
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ if (slirp->restricted) {
+ for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == ti->ti_dport &&
ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
break;
@@ -332,15 +330,15 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
* Locate pcb for segment.
*/
findso:
- so = tcp_last_so;
+ so = slirp->tcp_last_so;
if (so->so_fport != ti->ti_dport ||
so->so_lport != ti->ti_sport ||
so->so_laddr.s_addr != ti->ti_src.s_addr ||
so->so_faddr.s_addr != ti->ti_dst.s_addr) {
- so = solookup(&tcb, ti->ti_src, ti->ti_sport,
+ so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport,
ti->ti_dst, ti->ti_dport);
if (so)
- tcp_last_so = so;
+ slirp->tcp_last_so = so;
}
/*
@@ -360,7 +358,7 @@ findso:
if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
goto dropwithreset;
- if ((so = socreate()) == NULL)
+ if ((so = socreate(slirp)) == NULL)
goto dropwithreset;
if (tcp_attach(so) < 0) {
free(so); /* Not sofree (if it failed, it's not insqued) */
@@ -555,12 +553,13 @@ findso:
* If this is destined for the control address, then flag to
* tcp_ctl once connected, otherwise connect
*/
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
- vnetwork_addr.s_addr) {
- if (so->so_faddr.s_addr != vhost_addr.s_addr &&
- so->so_faddr.s_addr != vnameserver_addr.s_addr) {
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
+ if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
+ so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
/* May be an add exec */
- for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->exec_list; ex_ptr;
+ ex_ptr = ex_ptr->ex_next) {
if(ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
so->so_state |= SS_CTL;
@@ -631,8 +630,8 @@ findso:
if (iss)
tp->iss = iss;
else
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
+ tp->iss = slirp->tcp_iss;
+ slirp->tcp_iss += TCP_ISSINCR/2;
tp->irs = ti->ti_seq;
tcp_sendseqinit(tp);
tcp_rcvseqinit(tp);
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 686e90dc0e..0d6011ac64 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -290,7 +290,7 @@ send:
* the template for sends on this connection.
*/
if (len) {
- m = m_get();
+ m = m_get(so->slirp);
if (m == NULL) {
error = 1;
goto out;
@@ -310,7 +310,7 @@ send:
if (off + len == so->so_snd.sb_cc)
flags |= TH_PUSH;
} else {
- m = m_get();
+ m = m_get(so->slirp);
if (m == NULL) {
error = 1;
goto out;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 868382a6c2..51b38344ef 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -48,10 +48,11 @@
* Tcp initialization
*/
void
-tcp_init(void)
+tcp_init(Slirp *slirp)
{
- tcp_iss = 1; /* wrong */
- tcb.so_next = tcb.so_prev = &tcb;
+ slirp->tcp_iss = 1; /* wrong */
+ slirp->tcb.so_next = slirp->tcb.so_prev = &slirp->tcb;
+ slirp->tcp_last_so = &slirp->tcb;
}
/*
@@ -116,7 +117,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
if (tp)
win = sbspace(&tp->t_socket->so_rcv);
if (m == NULL) {
- if ((m = m_get()) == NULL)
+ if ((m = m_get(tp->t_socket->slirp)) == NULL)
return;
tlen = 0;
m->m_data += IF_MAXLINKHDR;
@@ -237,6 +238,7 @@ tcp_close(struct tcpcb *tp)
{
register struct tcpiphdr *t;
struct socket *so = tp->t_socket;
+ Slirp *slirp = so->slirp;
register struct mbuf *m;
DEBUG_CALL("tcp_close");
@@ -253,8 +255,8 @@ tcp_close(struct tcpcb *tp)
free(tp);
so->so_tcpcb = NULL;
/* clobber input socket cache if we're closing the cached connection */
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
+ if (so == slirp->tcp_last_so)
+ slirp->tcp_last_so = &slirp->tcb;
closesocket(so->s);
sbfree(&so->so_rcv);
sbfree(&so->so_snd);
@@ -317,6 +319,7 @@ tcp_sockclosed(struct tcpcb *tp)
*/
int tcp_fconnect(struct socket *so)
{
+ Slirp *slirp = so->slirp;
int ret=0;
DEBUG_CALL("tcp_fconnect");
@@ -333,9 +336,10 @@ int tcp_fconnect(struct socket *so)
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
/* It's an alias */
- if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
+ if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
addr.sin_addr = dns_addr;
} else {
addr.sin_addr = loopback_addr;
@@ -375,6 +379,7 @@ int tcp_fconnect(struct socket *so)
void
tcp_connect(struct socket *inso)
{
+ Slirp *slirp = inso->slirp;
struct socket *so;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
@@ -392,7 +397,7 @@ tcp_connect(struct socket *inso)
/* FACCEPTONCE already have a tcpcb */
so = inso;
} else {
- if ((so = socreate()) == NULL) {
+ if ((so = socreate(slirp)) == NULL) {
/* If it failed, get rid of the pending connection */
closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen));
return;
@@ -423,7 +428,7 @@ tcp_connect(struct socket *inso)
so->so_faddr = addr.sin_addr;
/* Translate connections from localhost to the real hostname */
if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
- so->so_faddr = vhost_addr;
+ so->so_faddr = slirp->vhost_addr;
/* Close the accept() socket, set right state */
if (inso->so_state & SS_FACCEPTONCE) {
@@ -441,8 +446,8 @@ tcp_connect(struct socket *inso)
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
+ tp->iss = slirp->tcp_iss;
+ slirp->tcp_iss += TCP_ISSINCR/2;
tcp_sendseqinit(tp);
tcp_output(tp);
}
@@ -456,7 +461,7 @@ tcp_attach(struct socket *so)
if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
return -1;
- insque(so, &tcb);
+ insque(so, &so->slirp->tcb);
return 0;
}
@@ -539,6 +544,7 @@ tcp_tos(struct socket *so)
int
tcp_emu(struct socket *so, struct mbuf *m)
{
+ Slirp *slirp = so->slirp;
u_int n1, n2, n3, n4, n5, n6;
char buff[257];
u_int32_t laddr;
@@ -572,7 +578,9 @@ tcp_emu(struct socket *so, struct mbuf *m)
HTONS(n1);
HTONS(n2);
/* n2 is the one on our host */
- for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
+ for (tmpso = slirp->tcb.so_next;
+ tmpso != &slirp->tcb;
+ tmpso = tmpso->so_next) {
if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
tmpso->so_lport == n2 &&
tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
@@ -608,9 +616,10 @@ tcp_emu(struct socket *so, struct mbuf *m)
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
lport = htons((n5 << 8) | (n6));
- if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
+ if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
+ lport, SS_FACCEPTONCE)) == NULL) {
return 1;
-
+ }
n6 = ntohs(so->so_fport);
n5 = (n6 >> 8) & 0xff;
@@ -640,9 +649,10 @@ tcp_emu(struct socket *so, struct mbuf *m)
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
lport = htons((n5 << 8) | (n6));
- if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
+ if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
+ lport, SS_FACCEPTONCE)) == NULL) {
return 1;
-
+ }
n6 = ntohs(so->so_fport);
n5 = (n6 >> 8) & 0xff;
@@ -680,7 +690,8 @@ tcp_emu(struct socket *so, struct mbuf *m)
lport += m->m_data[i] - '0';
}
if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
- (so = tcp_listen(INADDR_ANY, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
+ (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr,
+ htons(lport), SS_FACCEPTONCE)) != NULL)
m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d",
ntohs(so->so_fport)) + 1;
return 1;
@@ -695,27 +706,33 @@ tcp_emu(struct socket *so, struct mbuf *m)
/* The %256s is for the broken mIRC */
if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
- if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+ if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+ htonl(laddr), htons(lport),
+ SS_FACCEPTONCE)) == NULL) {
return 1;
-
+ }
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
"DCC CHAT chat %lu %u%c\n",
(unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), 1);
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+ if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+ htonl(laddr), htons(lport),
+ SS_FACCEPTONCE)) == NULL) {
return 1;
-
+ }
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
"DCC SEND %s %lu %u %u%c\n", buff,
(unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), n1, 1);
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+ if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+ htonl(laddr), htons(lport),
+ SS_FACCEPTONCE)) == NULL) {
return 1;
-
+ }
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
"DCC MOVE %s %lu %u %u%c\n", buff,
@@ -828,7 +845,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
/* try to get udp port between 6970 - 7170 */
for (p = 6970; p < 7071; p++) {
- if (udp_listen(INADDR_ANY,
+ if (udp_listen(slirp, INADDR_ANY,
htons(p),
so->so_laddr.s_addr,
htons(lport),
@@ -865,6 +882,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
*/
int tcp_ctl(struct socket *so)
{
+ Slirp *slirp = so->slirp;
struct sbuf *sb = &so->so_snd;
struct ex_list *ex_ptr;
int do_pty;
@@ -872,9 +890,9 @@ int tcp_ctl(struct socket *so)
DEBUG_CALL("tcp_ctl");
DEBUG_ARG("so = %lx", (long )so);
- if (so->so_faddr.s_addr != vhost_addr.s_addr) {
+ if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
/* Check if it's pty_exec */
- for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
if (ex_ptr->ex_pty == 3) {
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index cd71572bbf..556e32eadd 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -32,24 +32,22 @@
#include <slirp.h>
-u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
/*
* Fast timeout routine for processing delayed acks
*/
void
-tcp_fasttimo(void)
+tcp_fasttimo(Slirp *slirp)
{
register struct socket *so;
register struct tcpcb *tp;
DEBUG_CALL("tcp_fasttimo");
- so = tcb.so_next;
+ so = slirp->tcb.so_next;
if (so)
- for (; so != &tcb; so = so->so_next)
+ for (; so != &slirp->tcb; so = so->so_next)
if ((tp = (struct tcpcb *)so->so_tcpcb) &&
(tp->t_flags & TF_DELACK)) {
tp->t_flags &= ~TF_DELACK;
@@ -64,7 +62,7 @@ tcp_fasttimo(void)
* causes finite state machine actions if timers expire.
*/
void
-tcp_slowtimo(void)
+tcp_slowtimo(Slirp *slirp)
{
register struct socket *ip, *ipnxt;
register struct tcpcb *tp;
@@ -75,10 +73,10 @@ tcp_slowtimo(void)
/*
* Search through tcb's and update active timers.
*/
- ip = tcb.so_next;
+ ip = slirp->tcb.so_next;
if (ip == 0)
return;
- for (; ip != &tcb; ip = ipnxt) {
+ for (; ip != &slirp->tcb; ip = ipnxt) {
ipnxt = ip->so_next;
tp = sototcpcb(ip);
if (tp == 0)
@@ -96,8 +94,8 @@ tcp_slowtimo(void)
tpgone:
;
}
- tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
- tcp_now++; /* for timestamps */
+ slirp->tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
+ slirp->tcp_now++; /* for timestamps */
}
/*
diff --git a/slirp/tcp_timer.h b/slirp/tcp_timer.h
index f648ed0de7..cfb06ffc87 100644
--- a/slirp/tcp_timer.h
+++ b/slirp/tcp_timer.h
@@ -120,8 +120,8 @@ extern const int tcp_backoff[];
struct tcpcb;
-void tcp_fasttimo _P((void));
-void tcp_slowtimo _P((void));
+void tcp_fasttimo _P((Slirp *));
+void tcp_slowtimo _P((Slirp *));
void tcp_canceltimers _P((struct tcpcb *));
#endif
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
index db0a9c986d..4ffbe04a18 100644
--- a/slirp/tcp_var.h
+++ b/slirp/tcp_var.h
@@ -158,6 +158,4 @@ struct tcpcb {
#define TCP_REXMTVAL(tp) \
(((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
-extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
#endif
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 31a1e258cd..3b8643b8d8 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -25,41 +25,31 @@
#include <slirp.h>
#include "qemu-common.h"
-struct tftp_session {
- int in_use;
- char *filename;
-
- struct in_addr client_ip;
- u_int16_t client_port;
-
- int timestamp;
-};
-
-static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
-
-char *tftp_prefix;
+static inline int tftp_session_in_use(struct tftp_session *spt)
+{
+ return (spt->slirp != NULL);
+}
-static void tftp_session_update(struct tftp_session *spt)
+static inline void tftp_session_update(struct tftp_session *spt)
{
spt->timestamp = curtime;
- spt->in_use = 1;
}
static void tftp_session_terminate(struct tftp_session *spt)
{
- qemu_free(spt->filename);
- spt->in_use = 0;
+ qemu_free(spt->filename);
+ spt->slirp = NULL;
}
-static int tftp_session_allocate(struct tftp_t *tp)
+static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp)
{
struct tftp_session *spt;
int k;
for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
+ spt = &slirp->tftp_sessions[k];
- if (!spt->in_use)
+ if (!tftp_session_in_use(spt))
goto found;
/* sessions time out after 5 inactive seconds */
@@ -75,21 +65,22 @@ static int tftp_session_allocate(struct tftp_t *tp)
memset(spt, 0, sizeof(*spt));
memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
spt->client_port = tp->udp.uh_sport;
+ spt->slirp = slirp;
tftp_session_update(spt);
return k;
}
-static int tftp_session_find(struct tftp_t *tp)
+static int tftp_session_find(Slirp *slirp, struct tftp_t *tp)
{
struct tftp_session *spt;
int k;
for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
+ spt = &slirp->tftp_sessions[k];
- if (spt->in_use) {
+ if (tftp_session_in_use(spt)) {
if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) {
if (spt->client_port == tp->udp.uh_sport) {
return k;
@@ -133,7 +124,7 @@ static int tftp_send_oack(struct tftp_session *spt,
struct tftp_t *tp;
int n = 0;
- m = m_get();
+ m = m_get(spt->slirp);
if (!m)
return -1;
@@ -172,7 +163,7 @@ static void tftp_send_error(struct tftp_session *spt,
struct tftp_t *tp;
int nobytes;
- m = m_get();
+ m = m_get(spt->slirp);
if (!m) {
goto out;
@@ -218,7 +209,7 @@ static int tftp_send_data(struct tftp_session *spt,
return -1;
}
- m = m_get();
+ m = m_get(spt->slirp);
if (!m) {
return -1;
@@ -266,23 +257,23 @@ static int tftp_send_data(struct tftp_session *spt,
return 0;
}
-static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
+static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
{
struct tftp_session *spt;
int s, k;
size_t prefix_len;
char *req_fname;
- s = tftp_session_allocate(tp);
+ s = tftp_session_allocate(slirp, tp);
if (s < 0) {
return;
}
- spt = &tftp_sessions[s];
+ spt = &slirp->tftp_sessions[s];
/* unspecifed prefix means service disabled */
- if (!tftp_prefix) {
+ if (!slirp->tftp_prefix) {
tftp_send_error(spt, 2, "Access violation", tp);
return;
}
@@ -292,9 +283,9 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
pktlen -= ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
/* prepend tftp_prefix */
- prefix_len = strlen(tftp_prefix);
+ prefix_len = strlen(slirp->tftp_prefix);
spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 1);
- memcpy(spt->filename, tftp_prefix, prefix_len);
+ memcpy(spt->filename, slirp->tftp_prefix, prefix_len);
/* get name */
req_fname = spt->filename + prefix_len;
@@ -375,17 +366,17 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
tftp_send_data(spt, 1, tp);
}
-static void tftp_handle_ack(struct tftp_t *tp, int pktlen)
+static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
{
int s;
- s = tftp_session_find(tp);
+ s = tftp_session_find(slirp, tp);
if (s < 0) {
return;
}
- if (tftp_send_data(&tftp_sessions[s],
+ if (tftp_send_data(&slirp->tftp_sessions[s],
ntohs(tp->x.tp_data.tp_block_nr) + 1,
tp) < 0) {
return;
@@ -398,11 +389,11 @@ void tftp_input(struct mbuf *m)
switch(ntohs(tp->tp_op)) {
case TFTP_RRQ:
- tftp_handle_rrq(tp, m->m_len);
+ tftp_handle_rrq(m->slirp, tp, m->m_len);
break;
case TFTP_ACK:
- tftp_handle_ack(tp, m->m_len);
+ tftp_handle_ack(m->slirp, tp, m->m_len);
break;
}
}
diff --git a/slirp/tftp.h b/slirp/tftp.h
index 8f2675e077..1415c8527b 100644
--- a/slirp/tftp.h
+++ b/slirp/tftp.h
@@ -30,4 +30,14 @@ struct tftp_t {
} x;
};
+struct tftp_session {
+ Slirp *slirp;
+ char *filename;
+
+ struct in_addr client_ip;
+ u_int16_t client_port;
+
+ int timestamp;
+};
+
void tftp_input(struct mbuf *m);
diff --git a/slirp/udp.c b/slirp/udp.c
index 240e1bf38a..e0a669359b 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -41,17 +41,14 @@
#include <slirp.h>
#include "ip_icmp.h"
-struct socket udb;
-
static u_int8_t udp_tos(struct socket *so);
static void udp_emu(struct socket *so, struct mbuf *m);
-struct socket *udp_last_so = &udb;
-
void
-udp_init(void)
+udp_init(Slirp *slirp)
{
- udb.so_next = udb.so_prev = &udb;
+ slirp->udb.so_next = slirp->udb.so_prev = &slirp->udb;
+ slirp->udp_last_so = &slirp->udb;
}
/* m->m_data points at ip packet header
* m->m_len length ip packet
@@ -60,6 +57,7 @@ udp_init(void)
void
udp_input(register struct mbuf *m, int iphlen)
{
+ Slirp *slirp = m->slirp;
register struct ip *ip;
register struct udphdr *uh;
int len;
@@ -128,8 +126,9 @@ udp_input(register struct mbuf *m, int iphlen)
goto bad;
}
- if (slirp_restrict)
+ if (slirp->restricted) {
goto bad;
+ }
/*
* handle TFTP
@@ -142,22 +141,23 @@ udp_input(register struct mbuf *m, int iphlen)
/*
* Locate pcb for datagram.
*/
- so = udp_last_so;
+ so = slirp->udp_last_so;
if (so->so_lport != uh->uh_sport ||
so->so_laddr.s_addr != ip->ip_src.s_addr) {
struct socket *tmp;
- for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
+ for (tmp = slirp->udb.so_next; tmp != &slirp->udb;
+ tmp = tmp->so_next) {
if (tmp->so_lport == uh->uh_sport &&
tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
so = tmp;
break;
}
}
- if (tmp == &udb) {
+ if (tmp == &slirp->udb) {
so = NULL;
} else {
- udp_last_so = so;
+ slirp->udp_last_so = so;
}
}
@@ -166,7 +166,10 @@ udp_input(register struct mbuf *m, int iphlen)
* If there's no socket for this packet,
* create one
*/
- if ((so = socreate()) == NULL) goto bad;
+ so = socreate(slirp);
+ if (!so) {
+ goto bad;
+ }
if(udp_attach(so) == -1) {
DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
errno,strerror(errno)));
@@ -279,15 +282,18 @@ int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *addr)
{
+ Slirp *slirp = so->slirp;
struct sockaddr_in saddr, daddr;
saddr = *addr;
- if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
- if ((so->so_faddr.s_addr & ~vnetwork_mask.s_addr) ==
- ~vnetwork_mask.s_addr) {
- saddr.sin_addr = vhost_addr;
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
+ uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
+
+ if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
+ saddr.sin_addr = slirp->vhost_addr;
} else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
- so->so_faddr.s_addr != vhost_addr.s_addr) {
+ so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
saddr.sin_addr = so->so_faddr;
}
}
@@ -323,7 +329,7 @@ udp_attach(struct socket *so)
} else {
/* success, insert in queue */
so->so_expire = curtime + SO_EXPIRE;
- insque(so,&udb);
+ insque(so, &so->slirp->udb);
}
}
return(so->s);
@@ -595,20 +601,20 @@ struct cu_header {
}
struct socket *
-udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport,
- int flags)
+udp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
+ u_int lport, int flags)
{
struct sockaddr_in addr;
struct socket *so;
socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1;
- if ((so = socreate()) == NULL) {
- free(so);
- return NULL;
+ so = socreate(slirp);
+ if (!so) {
+ return NULL;
}
so->s = socket(AF_INET,SOCK_DGRAM,0);
so->so_expire = curtime + SO_EXPIRE;
- insque(so,&udb);
+ insque(so, &slirp->udb);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = haddr;
@@ -624,7 +630,7 @@ udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport,
so->so_fport = addr.sin_port;
if (addr.sin_addr.s_addr == 0 ||
addr.sin_addr.s_addr == loopback_addr.s_addr) {
- so->so_faddr = vhost_addr;
+ so->so_faddr = slirp->vhost_addr;
} else {
so->so_faddr = addr.sin_addr;
}
diff --git a/slirp/udp.h b/slirp/udp.h
index 3eed14a677..cc814a3f48 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -36,8 +36,6 @@
#define UDP_TTL 0x60
#define UDP_UDPDATALEN 16192
-extern struct socket *udp_last_so;
-
/*
* Udp protocol header.
* Per RFC 768, September, 1981.
@@ -73,15 +71,15 @@ struct udpiphdr {
#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
#define UDPCTL_MAXID 2
-extern struct socket udb;
struct mbuf;
-void udp_init _P((void));
+void udp_init _P((Slirp *));
void udp_input _P((register struct mbuf *, int));
int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *));
int udp_attach _P((struct socket *));
void udp_detach _P((struct socket *));
-struct socket * udp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int));
+struct socket * udp_listen _P((Slirp *, u_int32_t, u_int, u_int32_t, u_int,
+ int));
int udp_output2(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos);