Commit 460fec67ee3807bb2eb189587ffe803a48f317e5

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent b5302e1a

slirp: Factor out internal state structure

The essence of this patch is to stuff (almost) all global variables of
the slirp stack into the structure Slirp. In this step, we still keep
the structure as global variable, directly accessible by the whole
stack. Changes to the external interface of slirp will be applied in
the following patches.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
slirp/bootp.c
... ... @@ -25,19 +25,8 @@
25 25  
26 26 /* XXX: only DHCP is supported */
27 27  
28   -#define NB_ADDR 16
29   -
30 28 #define LEASE_TIME (24 * 3600)
31 29  
32   -typedef struct {
33   - uint8_t allocated;
34   - uint8_t macaddr[6];
35   -} BOOTPClient;
36   -
37   -static BOOTPClient bootp_clients[NB_ADDR];
38   -
39   -char *bootp_filename;
40   -
41 30 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
42 31  
43 32 #ifdef DEBUG
... ... @@ -47,35 +36,35 @@ do if (slirp_debug &amp; DBG_CALL) { fprintf(dfd, fmt, ## __VA_ARGS__); fflush(dfd)
47 36 #define dprintf(fmt, ...)
48 37 #endif
49 38  
50   -static BOOTPClient *get_new_addr(struct in_addr *paddr,
  39 +static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr,
51 40 const uint8_t *macaddr)
52 41 {
53 42 BOOTPClient *bc;
54 43 int i;
55 44  
56   - for(i = 0; i < NB_ADDR; i++) {
57   - bc = &bootp_clients[i];
  45 + for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
  46 + bc = &slirp->bootp_clients[i];
58 47 if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6))
59 48 goto found;
60 49 }
61 50 return NULL;
62 51 found:
63   - bc = &bootp_clients[i];
  52 + bc = &slirp->bootp_clients[i];
64 53 bc->allocated = 1;
65   - paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
  54 + paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
66 55 return bc;
67 56 }
68 57  
69   -static BOOTPClient *request_addr(const struct in_addr *paddr,
  58 +static BOOTPClient *request_addr(Slirp *slirp, const struct in_addr *paddr,
70 59 const uint8_t *macaddr)
71 60 {
72 61 uint32_t req_addr = ntohl(paddr->s_addr);
73   - uint32_t dhcp_addr = ntohl(vdhcp_startaddr.s_addr);
  62 + uint32_t dhcp_addr = ntohl(slirp->vdhcp_startaddr.s_addr);
74 63 BOOTPClient *bc;
75 64  
76 65 if (req_addr >= dhcp_addr &&
77   - req_addr < (dhcp_addr + NB_ADDR)) {
78   - bc = &bootp_clients[req_addr - dhcp_addr];
  66 + req_addr < (dhcp_addr + NB_BOOTP_CLIENTS)) {
  67 + bc = &slirp->bootp_clients[req_addr - dhcp_addr];
79 68 if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) {
80 69 bc->allocated = 1;
81 70 return bc;
... ... @@ -84,20 +73,21 @@ static BOOTPClient *request_addr(const struct in_addr *paddr,
84 73 return NULL;
85 74 }
86 75  
87   -static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
  76 +static BOOTPClient *find_addr(Slirp *slirp, struct in_addr *paddr,
  77 + const uint8_t *macaddr)
88 78 {
89 79 BOOTPClient *bc;
90 80 int i;
91 81  
92   - for(i = 0; i < NB_ADDR; i++) {
93   - if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
  82 + for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
  83 + if (!memcmp(macaddr, slirp->bootp_clients[i].macaddr, 6))
94 84 goto found;
95 85 }
96 86 return NULL;
97 87 found:
98   - bc = &bootp_clients[i];
  88 + bc = &slirp->bootp_clients[i];
99 89 bc->allocated = 1;
100   - paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
  90 + paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
101 91 return bc;
102 92 }
103 93  
... ... @@ -148,7 +138,7 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
148 138 }
149 139 }
150 140  
151   -static void bootp_reply(const struct bootp_t *bp)
  141 +static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
152 142 {
153 143 BOOTPClient *bc = NULL;
154 144 struct mbuf *m;
... ... @@ -173,10 +163,12 @@ static void bootp_reply(const struct bootp_t *bp)
173 163 dhcp_msg_type != DHCPREQUEST)
174 164 return;
175 165 /* XXX: this is a hack to get the client mac address */
176   - memcpy(client_ethaddr, bp->bp_hwaddr, 6);
  166 + memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6);
177 167  
178   - if ((m = m_get()) == NULL)
  168 + m = m_get(slirp);
  169 + if (!m) {
179 170 return;
  171 + }
180 172 m->m_data += IF_MAXLINKHDR;
181 173 rbp = (struct bootp_t *)m->m_data;
182 174 m->m_data += sizeof(struct udpiphdr);
... ... @@ -184,30 +176,30 @@ static void bootp_reply(const struct bootp_t *bp)
184 176  
185 177 if (dhcp_msg_type == DHCPDISCOVER) {
186 178 if (preq_addr) {
187   - bc = request_addr(preq_addr, client_ethaddr);
  179 + bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
188 180 if (bc) {
189 181 daddr.sin_addr = *preq_addr;
190 182 }
191 183 }
192 184 if (!bc) {
193 185 new_addr:
194   - bc = get_new_addr(&daddr.sin_addr, client_ethaddr);
  186 + bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr);
195 187 if (!bc) {
196 188 dprintf("no address left\n");
197 189 return;
198 190 }
199 191 }
200   - memcpy(bc->macaddr, client_ethaddr, 6);
  192 + memcpy(bc->macaddr, slirp->client_ethaddr, 6);
201 193 } else if (preq_addr) {
202   - bc = request_addr(preq_addr, client_ethaddr);
  194 + bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
203 195 if (bc) {
204 196 daddr.sin_addr = *preq_addr;
205   - memcpy(bc->macaddr, client_ethaddr, 6);
  197 + memcpy(bc->macaddr, slirp->client_ethaddr, 6);
206 198 } else {
207 199 daddr.sin_addr.s_addr = 0;
208 200 }
209 201 } else {
210   - bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
  202 + bc = find_addr(slirp, &daddr.sin_addr, bp->bp_hwaddr);
211 203 if (!bc) {
212 204 /* if never assigned, behaves as if it was already
213 205 assigned (windows fix because it remembers its address) */
... ... @@ -215,7 +207,7 @@ static void bootp_reply(const struct bootp_t *bp)
215 207 }
216 208 }
217 209  
218   - saddr.sin_addr = vhost_addr;
  210 + saddr.sin_addr = slirp->vhost_addr;
219 211 saddr.sin_port = htons(BOOTP_SERVER);
220 212  
221 213 daddr.sin_port = htons(BOOTP_CLIENT);
... ... @@ -248,9 +240,9 @@ static void bootp_reply(const struct bootp_t *bp)
248 240 *q++ = DHCPACK;
249 241 }
250 242  
251   - if (bootp_filename)
  243 + if (slirp->bootp_filename)
252 244 snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
253   - bootp_filename);
  245 + slirp->bootp_filename);
254 246  
255 247 *q++ = RFC2132_SRV_ID;
256 248 *q++ = 4;
... ... @@ -259,10 +251,10 @@ static void bootp_reply(const struct bootp_t *bp)
259 251  
260 252 *q++ = RFC1533_NETMASK;
261 253 *q++ = 4;
262   - memcpy(q, &vnetwork_mask, 4);
  254 + memcpy(q, &slirp->vnetwork_mask, 4);
263 255 q += 4;
264 256  
265   - if (!slirp_restrict) {
  257 + if (!slirp->restricted) {
266 258 *q++ = RFC1533_GATEWAY;
267 259 *q++ = 4;
268 260 memcpy(q, &saddr.sin_addr, 4);
... ... @@ -270,7 +262,7 @@ static void bootp_reply(const struct bootp_t *bp)
270 262  
271 263 *q++ = RFC1533_DNS;
272 264 *q++ = 4;
273   - memcpy(q, &vnameserver_addr, 4);
  265 + memcpy(q, &slirp->vnameserver_addr, 4);
274 266 q += 4;
275 267 }
276 268  
... ... @@ -280,11 +272,11 @@ static void bootp_reply(const struct bootp_t *bp)
280 272 memcpy(q, &val, 4);
281 273 q += 4;
282 274  
283   - if (*slirp_hostname) {
284   - val = strlen(slirp_hostname);
  275 + if (*slirp->client_hostname) {
  276 + val = strlen(slirp->client_hostname);
285 277 *q++ = RFC1533_HOSTNAME;
286 278 *q++ = val;
287   - memcpy(q, slirp_hostname, val);
  279 + memcpy(q, slirp->client_hostname, val);
288 280 q += val;
289 281 }
290 282 } else {
... ... @@ -315,6 +307,6 @@ void bootp_input(struct mbuf *m)
315 307 struct bootp_t *bp = mtod(m, struct bootp_t *);
316 308  
317 309 if (bp->bp_op == BOOTP_REQUEST) {
318   - bootp_reply(bp);
  310 + bootp_reply(m->slirp, bp);
319 311 }
320 312 }
... ...
slirp/bootp.h
... ... @@ -112,4 +112,11 @@ struct bootp_t {
112 112 uint8_t bp_vend[DHCP_OPT_LEN];
113 113 };
114 114  
  115 +typedef struct {
  116 + uint16_t allocated;
  117 + uint8_t macaddr[6];
  118 +} BOOTPClient;
  119 +
  120 +#define NB_BOOTP_CLIENTS 16
  121 +
115 122 void bootp_input(struct mbuf *m);
... ...
slirp/if.c
... ... @@ -7,12 +7,6 @@
7 7  
8 8 #include <slirp.h>
9 9  
10   -int if_queued = 0; /* Number of packets queued so far */
11   -
12   -struct mbuf if_fastq; /* fast queue (for interactive data) */
13   -struct mbuf if_batchq; /* queue for non-interactive data */
14   -struct mbuf *next_m; /* Pointer to next mbuf to output */
15   -
16 10 #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
17 11  
18 12 static void
... ... @@ -32,11 +26,11 @@ ifs_remque(struct mbuf *ifm)
32 26 }
33 27  
34 28 void
35   -if_init(void)
  29 +if_init(Slirp *slirp)
36 30 {
37   - if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
38   - if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
39   - next_m = &if_batchq;
  31 + slirp->if_fastq.ifq_next = slirp->if_fastq.ifq_prev = &slirp->if_fastq;
  32 + slirp->if_batchq.ifq_next = slirp->if_batchq.ifq_prev = &slirp->if_batchq;
  33 + slirp->next_m = &slirp->if_batchq;
40 34 }
41 35  
42 36 /*
... ... @@ -55,6 +49,7 @@ if_init(void)
55 49 void
56 50 if_output(struct socket *so, struct mbuf *ifm)
57 51 {
  52 + Slirp *slirp = ifm->slirp;
58 53 struct mbuf *ifq;
59 54 int on_fastq = 1;
60 55  
... ... @@ -79,7 +74,8 @@ if_output(struct socket *so, struct mbuf *ifm)
79 74 * We mustn't put this packet back on the fastq (or we'll send it out of order)
80 75 * XXX add cache here?
81 76 */
82   - for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) {
  77 + for (ifq = slirp->if_batchq.ifq_prev; ifq != &slirp->if_batchq;
  78 + ifq = ifq->ifq_prev) {
83 79 if (so == ifq->ifq_so) {
84 80 /* A match! */
85 81 ifm->ifq_so = so;
... ... @@ -90,7 +86,7 @@ if_output(struct socket *so, struct mbuf *ifm)
90 86  
91 87 /* No match, check which queue to put it on */
92 88 if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
93   - ifq = if_fastq.ifq_prev;
  89 + ifq = slirp->if_fastq.ifq_prev;
94 90 on_fastq = 1;
95 91 /*
96 92 * Check if this packet is a part of the last
... ... @@ -102,7 +98,7 @@ if_output(struct socket *so, struct mbuf *ifm)
102 98 goto diddit;
103 99 }
104 100 } else
105   - ifq = if_batchq.ifq_prev;
  101 + ifq = slirp->if_batchq.ifq_prev;
106 102  
107 103 /* Create a new doubly linked list for this session */
108 104 ifm->ifq_so = so;
... ... @@ -110,7 +106,7 @@ if_output(struct socket *so, struct mbuf *ifm)
110 106 insque(ifm, ifq);
111 107  
112 108 diddit:
113   - ++if_queued;
  109 + slirp->if_queued++;
114 110  
115 111 if (so) {
116 112 /* Update *_queued */
... ... @@ -130,7 +126,7 @@ diddit:
130 126 remque(ifm->ifs_next);
131 127  
132 128 /* ...And insert in the new. That'll teach ya! */
133   - insque(ifm->ifs_next, &if_batchq);
  129 + insque(ifm->ifs_next, &slirp->if_batchq);
134 130 }
135 131 }
136 132  
... ... @@ -138,7 +134,7 @@ diddit:
138 134 /*
139 135 * This prevents us from malloc()ing too many mbufs
140 136 */
141   - if_start();
  137 + if_start(ifm->slirp);
142 138 #endif
143 139 }
144 140  
... ... @@ -155,13 +151,13 @@ diddit:
155 151 * to the first, etc. etc.
156 152 */
157 153 void
158   -if_start(void)
  154 +if_start(Slirp *slirp)
159 155 {
160 156 struct mbuf *ifm, *ifqt;
161 157  
162 158 DEBUG_CALL("if_start");
163 159  
164   - if (if_queued == 0)
  160 + if (slirp->if_queued == 0)
165 161 return; /* Nothing to do */
166 162  
167 163 again:
... ... @@ -173,22 +169,22 @@ if_start(void)
173 169 * See which queue to get next packet from
174 170 * If there's something in the fastq, select it immediately
175 171 */
176   - if (if_fastq.ifq_next != &if_fastq) {
177   - ifm = if_fastq.ifq_next;
  172 + if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
  173 + ifm = slirp->if_fastq.ifq_next;
178 174 } else {
179 175 /* Nothing on fastq, see if next_m is valid */
180   - if (next_m != &if_batchq)
181   - ifm = next_m;
  176 + if (slirp->next_m != &slirp->if_batchq)
  177 + ifm = slirp->next_m;
182 178 else
183   - ifm = if_batchq.ifq_next;
  179 + ifm = slirp->if_batchq.ifq_next;
184 180  
185 181 /* Set which packet to send on next iteration */
186   - next_m = ifm->ifq_next;
  182 + slirp->next_m = ifm->ifq_next;
187 183 }
188 184 /* Remove it from the queue */
189 185 ifqt = ifm->ifq_prev;
190 186 remque(ifm);
191   - --if_queued;
  187 + slirp->if_queued--;
192 188  
193 189 /* If there are more packets for this session, re-queue them */
194 190 if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
... ... @@ -204,10 +200,10 @@ if_start(void)
204 200 }
205 201  
206 202 /* Encapsulate the packet for sending */
207   - if_encap((uint8_t *)ifm->m_data, ifm->m_len);
  203 + if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len);
208 204  
209 205 m_free(ifm);
210 206  
211   - if (if_queued)
  207 + if (slirp->if_queued)
212 208 goto again;
213 209 }
... ...
slirp/if.h
... ... @@ -20,12 +20,6 @@
20 20 /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
21 21 #define IF_MAXLINKHDR (2 + 14 + 40)
22 22  
23   -extern int if_queued; /* Number of packets queued so far */
24   -
25   -extern struct mbuf if_fastq; /* fast queue (for interactive data) */
26   -extern struct mbuf if_batchq; /* queue for non-interactive data */
27   -extern struct mbuf *next_m;
28   -
29 23 #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
30 24  
31 25 #endif
... ...
slirp/ip.h
... ... @@ -250,7 +250,4 @@ struct ipoption {
250 250 int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
251 251 };
252 252  
253   -extern struct ipq ipq; /* ip reass. queue */
254   -extern u_int16_t ip_id; /* ip packet ctr, for ids */
255   -
256 253 #endif
... ...
slirp/ip_icmp.c
... ... @@ -69,6 +69,7 @@ icmp_input(struct mbuf *m, int hlen)
69 69 register struct icmp *icp;
70 70 register struct ip *ip=mtod(m, struct ip *);
71 71 int icmplen=ip->ip_len;
  72 + Slirp *slirp = m->slirp;
72 73  
73 74 DEBUG_CALL("icmp_input");
74 75 DEBUG_ARG("m = %lx", (long )m);
... ... @@ -98,12 +99,12 @@ icmp_input(struct mbuf *m, int hlen)
98 99 case ICMP_ECHO:
99 100 icp->icmp_type = ICMP_ECHOREPLY;
100 101 ip->ip_len += hlen; /* since ip_input subtracts this */
101   - if (ip->ip_dst.s_addr == vhost_addr.s_addr) {
  102 + if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
102 103 icmp_reflect(m);
103 104 } else {
104 105 struct socket *so;
105 106 struct sockaddr_in addr;
106   - if ((so = socreate()) == NULL) goto freeit;
  107 + if ((so = socreate(slirp)) == NULL) goto freeit;
107 108 if(udp_attach(so) == -1) {
108 109 DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
109 110 errno,strerror(errno)));
... ... @@ -122,10 +123,10 @@ icmp_input(struct mbuf *m, int hlen)
122 123  
123 124 /* Send the packet */
124 125 addr.sin_family = AF_INET;
125   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
126   - vnetwork_addr.s_addr) {
  126 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  127 + slirp->vnetwork_addr.s_addr) {
127 128 /* It's an alias */
128   - if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
  129 + if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
129 130 addr.sin_addr = dns_addr;
130 131 } else {
131 132 addr.sin_addr = loopback_addr;
... ... @@ -222,7 +223,11 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
222 223 }
223 224  
224 225 /* make a copy */
225   - if(!(m=m_get())) goto end_error; /* get mbuf */
  226 + m = m_get(msrc->slirp);
  227 + if (!m) {
  228 + goto end_error;
  229 + }
  230 +
226 231 { int new_m_size;
227 232 new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
228 233 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,
285 290 ip->ip_ttl = MAXTTL;
286 291 ip->ip_p = IPPROTO_ICMP;
287 292 ip->ip_dst = ip->ip_src; /* ip adresses */
288   - ip->ip_src = vhost_addr;
  293 + ip->ip_src = m->slirp->vhost_addr;
289 294  
290 295 (void ) ip_output((struct socket *)NULL, m);
291 296  
... ...
slirp/ip_input.c
... ... @@ -42,11 +42,8 @@
42 42 #include <osdep.h>
43 43 #include "ip_icmp.h"
44 44  
45   -struct ipq ipq;
46   -
47   -static struct ip *ip_reass(register struct ip *ip,
48   - register struct ipq *fp);
49   -static void ip_freef(struct ipq *fp);
  45 +static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp);
  46 +static void ip_freef(Slirp *slirp, struct ipq *fp);
50 47 static void ip_enq(register struct ipasfrag *p,
51 48 register struct ipasfrag *prev);
52 49 static void ip_deq(register struct ipasfrag *p);
... ... @@ -56,11 +53,11 @@ static void ip_deq(register struct ipasfrag *p);
56 53 * All protocols not implemented in kernel go to raw IP protocol handler.
57 54 */
58 55 void
59   -ip_init(void)
  56 +ip_init(Slirp *slirp)
60 57 {
61   - ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
62   - udp_init();
63   - tcp_init();
  58 + slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link;
  59 + udp_init(slirp);
  60 + tcp_init(slirp);
64 61 }
65 62  
66 63 /*
... ... @@ -70,6 +67,7 @@ ip_init(void)
70 67 void
71 68 ip_input(struct mbuf *m)
72 69 {
  70 + Slirp *slirp = m->slirp;
73 71 register struct ip *ip;
74 72 int hlen;
75 73  
... ... @@ -120,19 +118,19 @@ ip_input(struct mbuf *m)
120 118 goto bad;
121 119 }
122 120  
123   - if (slirp_restrict) {
124   - if ((ip->ip_dst.s_addr & vnetwork_mask.s_addr) ==
125   - vnetwork_addr.s_addr) {
  121 + if (slirp->restricted) {
  122 + if ((ip->ip_dst.s_addr & slirp->vnetwork_mask.s_addr) ==
  123 + slirp->vnetwork_addr.s_addr) {
126 124 if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
127 125 goto bad;
128 126 } else {
  127 + uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
129 128 struct ex_list *ex_ptr;
130 129  
131   - if ((ip->ip_dst.s_addr & ~vnetwork_mask.s_addr) ==
132   - ~vnetwork_mask.s_addr)
  130 + if ((ip->ip_dst.s_addr & inv_mask) == inv_mask) {
133 131 goto bad;
134   -
135   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
  132 + }
  133 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
136 134 if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr)
137 135 break;
138 136  
... ... @@ -167,7 +165,8 @@ ip_input(struct mbuf *m)
167 165 * Look for queue of fragments
168 166 * of this datagram.
169 167 */
170   - for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
  168 + for (l = slirp->ipq.ip_link.next; l != &slirp->ipq.ip_link;
  169 + l = l->next) {
171 170 fp = container_of(l, struct ipq, ip_link);
172 171 if (ip->ip_id == fp->ipq_id &&
173 172 ip->ip_src.s_addr == fp->ipq_src.s_addr &&
... ... @@ -197,13 +196,13 @@ ip_input(struct mbuf *m)
197 196 * attempt reassembly; if it succeeds, proceed.
198 197 */
199 198 if (ip->ip_tos & 1 || ip->ip_off) {
200   - ip = ip_reass(ip, fp);
  199 + ip = ip_reass(slirp, ip, fp);
201 200 if (ip == NULL)
202 201 return;
203   - m = dtom(ip);
  202 + m = dtom(slirp, ip);
204 203 } else
205 204 if (fp)
206   - ip_freef(fp);
  205 + ip_freef(slirp, fp);
207 206  
208 207 } else
209 208 ip->ip_len -= hlen;
... ... @@ -239,9 +238,9 @@ bad:
239 238 * is given as fp; otherwise have to make a chain.
240 239 */
241 240 static struct ip *
242   -ip_reass(register struct ip *ip, register struct ipq *fp)
  241 +ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
243 242 {
244   - register struct mbuf *m = dtom(ip);
  243 + register struct mbuf *m = dtom(slirp, ip);
245 244 register struct ipasfrag *q;
246 245 int hlen = ip->ip_hl << 2;
247 246 int i, next;
... ... @@ -263,10 +262,13 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
263 262 * If first fragment to arrive, create a reassembly queue.
264 263 */
265 264 if (fp == NULL) {
266   - struct mbuf *t;
267   - if ((t = m_get()) == NULL) goto dropfrag;
  265 + struct mbuf *t = m_get(slirp);
  266 +
  267 + if (t == NULL) {
  268 + goto dropfrag;
  269 + }
268 270 fp = mtod(t, struct ipq *);
269   - insque(&fp->ip_link, &ipq.ip_link);
  271 + insque(&fp->ip_link, &slirp->ipq.ip_link);
270 272 fp->ipq_ttl = IPFRAGTTL;
271 273 fp->ipq_p = ip->ip_p;
272 274 fp->ipq_id = ip->ip_id;
... ... @@ -296,7 +298,7 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
296 298 if (i > 0) {
297 299 if (i >= ip->ip_len)
298 300 goto dropfrag;
299   - m_adj(dtom(ip), i);
  301 + m_adj(dtom(slirp, ip), i);
300 302 ip->ip_off += i;
301 303 ip->ip_len -= i;
302 304 }
... ... @@ -312,11 +314,11 @@ ip_reass(register struct ip *ip, register struct ipq *fp)
312 314 if (i < q->ipf_len) {
313 315 q->ipf_len -= i;
314 316 q->ipf_off += i;
315   - m_adj(dtom(q), i);
  317 + m_adj(dtom(slirp, q), i);
316 318 break;
317 319 }
318 320 q = q->ipf_next;
319   - m_freem(dtom(q->ipf_prev));
  321 + m_freem(dtom(slirp, q->ipf_prev));
320 322 ip_deq(q->ipf_prev);
321 323 }
322 324  
... ... @@ -340,11 +342,11 @@ insert:
340 342 * Reassembly is complete; concatenate fragments.
341 343 */
342 344 q = fp->frag_link.next;
343   - m = dtom(q);
  345 + m = dtom(slirp, q);
344 346  
345 347 q = (struct ipasfrag *) q->ipf_next;
346 348 while (q != (struct ipasfrag*)&fp->frag_link) {
347   - struct mbuf *t = dtom(q);
  349 + struct mbuf *t = dtom(slirp, q);
348 350 q = (struct ipasfrag *) q->ipf_next;
349 351 m_cat(m, t);
350 352 }
... ... @@ -375,7 +377,7 @@ insert:
375 377 ip->ip_src = fp->ipq_src;
376 378 ip->ip_dst = fp->ipq_dst;
377 379 remque(&fp->ip_link);
378   - (void) m_free(dtom(fp));
  380 + (void) m_free(dtom(slirp, fp));
379 381 m->m_len += (ip->ip_hl << 2);
380 382 m->m_data -= (ip->ip_hl << 2);
381 383  
... ... @@ -391,17 +393,17 @@ dropfrag:
391 393 * associated datagrams.
392 394 */
393 395 static void
394   -ip_freef(struct ipq *fp)
  396 +ip_freef(Slirp *slirp, struct ipq *fp)
395 397 {
396 398 register struct ipasfrag *q, *p;
397 399  
398 400 for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
399 401 p = q->ipf_next;
400 402 ip_deq(q);
401   - m_freem(dtom(q));
  403 + m_freem(dtom(slirp, q));
402 404 }
403 405 remque(&fp->ip_link);
404   - (void) m_free(dtom(fp));
  406 + (void) m_free(dtom(slirp, fp));
405 407 }
406 408  
407 409 /*
... ... @@ -435,24 +437,24 @@ ip_deq(register struct ipasfrag *p)
435 437 * queue, discard it.
436 438 */
437 439 void
438   -ip_slowtimo(void)
  440 +ip_slowtimo(Slirp *slirp)
439 441 {
440 442 struct qlink *l;
441 443  
442 444 DEBUG_CALL("ip_slowtimo");
443 445  
444   - l = ipq.ip_link.next;
  446 + l = slirp->ipq.ip_link.next;
445 447  
446 448 if (l == NULL)
447 449 return;
448 450  
449   - while (l != &ipq.ip_link) {
  451 + while (l != &slirp->ipq.ip_link) {
450 452 struct ipq *fp = container_of(l, struct ipq, ip_link);
451 453 l = l->next;
452 454 if (--fp->ipq_ttl == 0) {
453   - ip_freef(fp);
  455 + ip_freef(slirp, fp);
454 456 }
455   - }
  457 + }
456 458 }
457 459  
458 460 /*
... ...
slirp/ip_output.c
... ... @@ -40,8 +40,6 @@
40 40  
41 41 #include <slirp.h>
42 42  
43   -u_int16_t ip_id;
44   -
45 43 /* Number of packets queued before we start sending
46 44 * (to prevent allocing too many mbufs) */
47 45 #define IF_THRESH 10
... ... @@ -55,6 +53,7 @@ u_int16_t ip_id;
55 53 int
56 54 ip_output(struct socket *so, struct mbuf *m0)
57 55 {
  56 + Slirp *slirp = m0->slirp;
58 57 register struct ip *ip;
59 58 register struct mbuf *m = m0;
60 59 register int hlen = sizeof(struct ip );
... ... @@ -70,7 +69,7 @@ ip_output(struct socket *so, struct mbuf *m0)
70 69 */
71 70 ip->ip_v = IPVERSION;
72 71 ip->ip_off &= IP_DF;
73   - ip->ip_id = htons(ip_id++);
  72 + ip->ip_id = htons(slirp->ip_id++);
74 73 ip->ip_hl = hlen >> 2;
75 74  
76 75 /*
... ... @@ -113,7 +112,7 @@ ip_output(struct socket *so, struct mbuf *m0)
113 112 mhlen = sizeof (struct ip);
114 113 for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
115 114 register struct ip *mhip;
116   - m = m_get();
  115 + m = m_get(slirp);
117 116 if (m == NULL) {
118 117 error = -1;
119 118 goto sendorfree;
... ...
slirp/libslirp.h
... ... @@ -5,6 +5,9 @@
5 5  
6 6 #ifdef CONFIG_SLIRP
7 7  
  8 +struct Slirp;
  9 +typedef struct Slirp Slirp;
  10 +
8 11 void slirp_init(int restricted, struct in_addr vnetwork,
9 12 struct in_addr vnetmask, struct in_addr vhost,
10 13 const char *vhostname, const char *tftp_path,
... ...
slirp/main.h
... ... @@ -31,11 +31,6 @@ extern char *slirp_tty;
31 31 extern char *exec_shell;
32 32 extern u_int curtime;
33 33 extern fd_set *global_readfds, *global_writefds, *global_xfds;
34   -extern struct in_addr vnetwork_addr;
35   -extern struct in_addr vnetwork_mask;
36   -extern struct in_addr vhost_addr;
37   -extern struct in_addr vdhcp_startaddr;
38   -extern struct in_addr vnameserver_addr;
39 34 extern struct in_addr our_addr;
40 35 extern struct in_addr loopback_addr;
41 36 extern struct in_addr dns_addr;
... ... @@ -44,16 +39,11 @@ extern char *socket_path;
44 39 extern int towrite_max;
45 40 extern int ppp_exit;
46 41 extern int tcp_keepintvl;
47   -extern uint8_t client_ethaddr[6];
48   -extern int slirp_restrict;
49   -extern char slirp_hostname[33];
50   -extern char *tftp_prefix;
51   -extern char *bootp_filename;
52 42  
53 43 #define PROTO_SLIP 0x1
54 44 #ifdef USE_PPP
55 45 #define PROTO_PPP 0x2
56 46 #endif
57 47  
58   -void if_encap(const uint8_t *ip_data, int ip_data_len);
  48 +void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len);
59 49 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
... ...
slirp/mbuf.c
... ... @@ -17,8 +17,6 @@
17 17  
18 18 #include <slirp.h>
19 19  
20   -static int mbuf_alloced;
21   -struct mbuf m_freelist, m_usedlist;
22 20 #define MBUF_THRESH 30
23 21  
24 22 /*
... ... @@ -28,10 +26,10 @@ struct mbuf m_freelist, m_usedlist;
28 26 #define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
29 27  
30 28 void
31   -m_init(void)
  29 +m_init(Slirp *slirp)
32 30 {
33   - m_freelist.m_next = m_freelist.m_prev = &m_freelist;
34   - m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
  31 + slirp->m_freelist.m_next = slirp->m_freelist.m_prev = &slirp->m_freelist;
  32 + slirp->m_usedlist.m_next = slirp->m_usedlist.m_prev = &slirp->m_usedlist;
35 33 }
36 34  
37 35 /*
... ... @@ -43,26 +41,27 @@ m_init(void)
43 41 * which tells m_free to actually free() it
44 42 */
45 43 struct mbuf *
46   -m_get(void)
  44 +m_get(Slirp *slirp)
47 45 {
48 46 register struct mbuf *m;
49 47 int flags = 0;
50 48  
51 49 DEBUG_CALL("m_get");
52 50  
53   - if (m_freelist.m_next == &m_freelist) {
  51 + if (slirp->m_freelist.m_next == &slirp->m_freelist) {
54 52 m = (struct mbuf *)malloc(SLIRP_MSIZE);
55 53 if (m == NULL) goto end_error;
56   - mbuf_alloced++;
57   - if (mbuf_alloced > MBUF_THRESH)
  54 + slirp->mbuf_alloced++;
  55 + if (slirp->mbuf_alloced > MBUF_THRESH)
58 56 flags = M_DOFREE;
  57 + m->slirp = slirp;
59 58 } else {
60   - m = m_freelist.m_next;
  59 + m = slirp->m_freelist.m_next;
61 60 remque(m);
62 61 }
63 62  
64 63 /* Insert it in the used list */
65   - insque(m,&m_usedlist);
  64 + insque(m,&slirp->m_usedlist);
66 65 m->m_flags = (flags | M_USEDLIST);
67 66  
68 67 /* Initialise it */
... ... @@ -97,9 +96,9 @@ m_free(struct mbuf *m)
97 96 */
98 97 if (m->m_flags & M_DOFREE) {
99 98 free(m);
100   - mbuf_alloced--;
  99 + m->slirp->mbuf_alloced--;
101 100 } else if ((m->m_flags & M_FREELIST) == 0) {
102   - insque(m,&m_freelist);
  101 + insque(m,&m->slirp->m_freelist);
103 102 m->m_flags = M_FREELIST; /* Clobber other flags */
104 103 }
105 104 } /* if(m) */
... ... @@ -194,7 +193,7 @@ m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
194 193 * Fortunately, it's not used often
195 194 */
196 195 struct mbuf *
197   -dtom(void *dat)
  196 +dtom(Slirp *slirp, void *dat)
198 197 {
199 198 struct mbuf *m;
200 199  
... ... @@ -202,7 +201,8 @@ dtom(void *dat)
202 201 DEBUG_ARG("dat = %lx", (long )dat);
203 202  
204 203 /* bug corrected for M_EXT buffers */
205   - for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
  204 + for (m = slirp->m_usedlist.m_next; m != &slirp->m_usedlist;
  205 + m = m->m_next) {
206 206 if (m->m_flags & M_EXT) {
207 207 if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
208 208 return m;
... ...
slirp/mbuf.h
... ... @@ -84,6 +84,7 @@ struct m_hdr {
84 84  
85 85 struct mbuf {
86 86 struct m_hdr m_hdr;
  87 + Slirp *slirp;
87 88 union M_dat {
88 89 char m_dat_[1]; /* ANSI don't like 0 sized arrays */
89 90 char *m_ext_;
... ... @@ -114,15 +115,13 @@ struct mbuf {
114 115 #define M_DOFREE 0x08 /* when m_free is called on the mbuf, free()
115 116 * it rather than putting it on the free list */
116 117  
117   -extern struct mbuf m_freelist, m_usedlist;
118   -
119   -void m_init _P((void));
120   -struct mbuf * m_get _P((void));
  118 +void m_init _P((Slirp *));
  119 +struct mbuf * m_get _P((Slirp *));
121 120 void m_free _P((struct mbuf *));
122 121 void m_cat _P((register struct mbuf *, register struct mbuf *));
123 122 void m_inc _P((struct mbuf *, int));
124 123 void m_adj _P((struct mbuf *, int));
125 124 int m_copy _P((struct mbuf *, struct mbuf *, int, int));
126   -struct mbuf * dtom _P((void *));
  125 +struct mbuf * dtom _P((Slirp *, void *));
127 126  
128 127 #endif
... ...
slirp/misc.c
... ... @@ -385,6 +385,7 @@ void slirp_connection_info(Monitor *mon)
385 385 [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
386 386 [TCPS_TIME_WAIT] = "TIME_WAIT",
387 387 };
  388 + Slirp *slirp = &slirp_instance;
388 389 struct in_addr dst_addr;
389 390 struct sockaddr_in src;
390 391 socklen_t src_len;
... ... @@ -397,7 +398,7 @@ void slirp_connection_info(Monitor *mon)
397 398 monitor_printf(mon, " Protocol[State] FD Source Address Port "
398 399 "Dest. Address Port RecvQ SendQ\n");
399 400  
400   - for (so = tcb.so_next; so != &tcb; so = so->so_next) {
  401 + for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
401 402 if (so->so_state & SS_HOSTFWD) {
402 403 state = "HOST_FORWARD";
403 404 } else if (so->so_tcpcb) {
... ... @@ -427,7 +428,7 @@ void slirp_connection_info(Monitor *mon)
427 428 so->so_rcv.sb_cc, so->so_snd.sb_cc);
428 429 }
429 430  
430   - for (so = udb.so_next; so != &udb; so = so->so_next) {
  431 + for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
431 432 if (so->so_state & SS_HOSTFWD) {
432 433 n = snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]");
433 434 src_len = sizeof(src);
... ...
slirp/misc.h
... ... @@ -16,8 +16,6 @@ struct ex_list {
16 16 struct ex_list *ex_next;
17 17 };
18 18  
19   -extern struct ex_list *exec_list;
20   -
21 19 #ifndef HAVE_STRDUP
22 20 char *strdup _P((const char *));
23 21 #endif
... ...
slirp/slirp.c
... ... @@ -33,27 +33,14 @@ struct in_addr dns_addr;
33 33 /* host loopback address */
34 34 struct in_addr loopback_addr;
35 35  
36   -/* virtual network configuration */
37   -struct in_addr vnetwork_addr;
38   -struct in_addr vnetwork_mask;
39   -struct in_addr vhost_addr;
40   -struct in_addr vdhcp_startaddr;
41   -struct in_addr vnameserver_addr;
42   -
43 36 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
44 37 static const uint8_t special_ethaddr[6] = {
45 38 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
46 39 };
47 40  
48   -/* ARP cache for the guest IP addresses (XXX: allow many entries) */
49   -uint8_t client_ethaddr[6];
50   -static struct in_addr client_ipaddr;
51   -
52 41 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
53 42  
54   -int slirp_restrict;
55   -int link_up;
56   -struct ex_list *exec_list;
  43 +int link_up; // FIXME: kill this
57 44  
58 45 /* XXX: suppress those select globals */
59 46 fd_set *global_readfds, *global_writefds, *global_xfds;
... ... @@ -62,7 +49,7 @@ u_int curtime;
62 49 static u_int time_fasttimo, last_slowtimo;
63 50 static int do_slowtimo;
64 51  
65   -char slirp_hostname[33];
  52 +Slirp slirp_instance;
66 53  
67 54 #ifdef _WIN32
68 55  
... ... @@ -206,37 +193,40 @@ void slirp_init(int restricted, struct in_addr vnetwork,
206 193 const char *bootfile, struct in_addr vdhcp_start,
207 194 struct in_addr vnameserver)
208 195 {
  196 + Slirp *slirp = &slirp_instance;
  197 +
209 198 slirp_init_once();
210 199  
211 200 link_up = 1;
212   - slirp_restrict = restricted;
  201 + slirp->restricted = restricted;
213 202  
214   - if_init();
215   - ip_init();
  203 + if_init(slirp);
  204 + ip_init(slirp);
216 205  
217 206 /* Initialise mbufs *after* setting the MTU */
218   - m_init();
  207 + m_init(slirp);
219 208  
220   - vnetwork_addr = vnetwork;
221   - vnetwork_mask = vnetmask;
222   - vhost_addr = vhost;
  209 + slirp->vnetwork_addr = vnetwork;
  210 + slirp->vnetwork_mask = vnetmask;
  211 + slirp->vhost_addr = vhost;
223 212 if (vhostname) {
224   - pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);
  213 + pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
  214 + vhostname);
225 215 }
226   - qemu_free(tftp_prefix);
227   - tftp_prefix = NULL;
  216 + qemu_free(slirp->tftp_prefix);
  217 + slirp->tftp_prefix = NULL;
228 218 if (tftp_path) {
229   - tftp_prefix = qemu_strdup(tftp_path);
  219 + slirp->tftp_prefix = qemu_strdup(tftp_path);
230 220 }
231   - qemu_free(bootp_filename);
232   - bootp_filename = NULL;
  221 + qemu_free(slirp->bootp_filename);
  222 + slirp->bootp_filename = NULL;
233 223 if (bootfile) {
234   - bootp_filename = qemu_strdup(bootfile);
  224 + slirp->bootp_filename = qemu_strdup(bootfile);
235 225 }
236   - vdhcp_startaddr = vdhcp_start;
237   - vnameserver_addr = vnameserver;
  226 + slirp->vdhcp_startaddr = vdhcp_start;
  227 + slirp->vnameserver_addr = vnameserver;
238 228  
239   - register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, NULL);
  229 + register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp);
240 230 }
241 231  
242 232 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
... ... @@ -269,6 +259,7 @@ static void updtime(void)
269 259 void slirp_select_fill(int *pnfds,
270 260 fd_set *readfds, fd_set *writefds, fd_set *xfds)
271 261 {
  262 + Slirp *slirp = &slirp_instance;
272 263 struct socket *so, *so_next;
273 264 int nfds;
274 265  
... ... @@ -291,10 +282,11 @@ void slirp_select_fill(int *pnfds,
291 282 * *_slowtimo needs calling if there are IP fragments
292 283 * in the fragment queue, or there are TCP connections active
293 284 */
294   - do_slowtimo = ((tcb.so_next != &tcb) ||
295   - (&ipq.ip_link != ipq.ip_link.next));
  285 + do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
  286 + (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
296 287  
297   - for (so = tcb.so_next; so != &tcb; so = so_next) {
  288 + for (so = slirp->tcb.so_next; so != &slirp->tcb;
  289 + so = so_next) {
298 290 so_next = so->so_next;
299 291  
300 292 /*
... ... @@ -351,7 +343,8 @@ void slirp_select_fill(int *pnfds,
351 343 /*
352 344 * UDP sockets
353 345 */
354   - for (so = udb.so_next; so != &udb; so = so_next) {
  346 + for (so = slirp->udb.so_next; so != &slirp->udb;
  347 + so = so_next) {
355 348 so_next = so->so_next;
356 349  
357 350 /*
... ... @@ -387,6 +380,7 @@ void slirp_select_fill(int *pnfds,
387 380 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
388 381 int select_error)
389 382 {
  383 + Slirp *slirp = &slirp_instance;
390 384 struct socket *so, *so_next;
391 385 int ret;
392 386  
... ... @@ -405,12 +399,12 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
405 399 * See if anything has timed out
406 400 */
407 401 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
408   - tcp_fasttimo();
  402 + tcp_fasttimo(slirp);
409 403 time_fasttimo = 0;
410 404 }
411 405 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
412   - ip_slowtimo();
413   - tcp_slowtimo();
  406 + ip_slowtimo(slirp);
  407 + tcp_slowtimo(slirp);
414 408 last_slowtimo = curtime;
415 409 }
416 410  
... ... @@ -421,7 +415,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
421 415 /*
422 416 * Check TCP sockets
423 417 */
424   - for (so = tcb.so_next; so != &tcb; so = so_next) {
  418 + for (so = slirp->tcb.so_next; so != &slirp->tcb;
  419 + so = so_next) {
425 420 so_next = so->so_next;
426 421  
427 422 /*
... ... @@ -538,7 +533,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
538 533 * Incoming packets are sent straight away, they're not buffered.
539 534 * Incoming UDP data isn't buffered either.
540 535 */
541   - for (so = udb.so_next; so != &udb; so = so_next) {
  536 + for (so = slirp->udb.so_next; so != &slirp->udb;
  537 + so = so_next) {
542 538 so_next = so->so_next;
543 539  
544 540 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,
550 546 /*
551 547 * See if we can start outputting
552 548 */
553   - if (if_queued)
554   - if_start();
  549 + if (slirp->if_queued) {
  550 + if_start(slirp);
  551 + }
555 552  
556 553 /* clear global file descriptor sets.
557 554 * these reside on the stack in vl.c
... ... @@ -596,7 +593,7 @@ struct arphdr
596 593 uint32_t ar_tip ; /* target IP address */
597 594 } __attribute__((packed));
598 595  
599   -static void arp_input(const uint8_t *pkt, int pkt_len)
  596 +static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
600 597 {
601 598 struct ethhdr *eh = (struct ethhdr *)pkt;
602 599 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
... ... @@ -609,18 +606,19 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
609 606 ar_op = ntohs(ah->ar_op);
610 607 switch(ar_op) {
611 608 case ARPOP_REQUEST:
612   - if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
613   - if (ah->ar_tip == vnameserver_addr.s_addr ||
614   - ah->ar_tip == vhost_addr.s_addr)
  609 + if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
  610 + slirp->vnetwork_addr.s_addr) {
  611 + if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
  612 + ah->ar_tip == slirp->vhost_addr.s_addr)
615 613 goto arp_ok;
616   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  614 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
617 615 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
618 616 goto arp_ok;
619 617 }
620 618 return;
621 619 arp_ok:
622 620 /* XXX: make an ARP request to have the client address */
623   - memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
  621 + memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
624 622  
625 623 /* ARP request for alias/dns mac address */
626 624 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
... ... @@ -642,9 +640,9 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
642 640 break;
643 641 case ARPOP_REPLY:
644 642 /* reply to request of client mac address ? */
645   - if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
646   - ah->ar_sip == client_ipaddr.s_addr) {
647   - memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
  643 + if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
  644 + ah->ar_sip == slirp->client_ipaddr.s_addr) {
  645 + memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
648 646 }
649 647 break;
650 648 default:
... ... @@ -654,6 +652,7 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
654 652  
655 653 void slirp_input(const uint8_t *pkt, int pkt_len)
656 654 {
  655 + Slirp *slirp = &slirp_instance;
657 656 struct mbuf *m;
658 657 int proto;
659 658  
... ... @@ -663,10 +662,10 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
663 662 proto = ntohs(*(uint16_t *)(pkt + 12));
664 663 switch(proto) {
665 664 case ETH_P_ARP:
666   - arp_input(pkt, pkt_len);
  665 + arp_input(slirp, pkt, pkt_len);
667 666 break;
668 667 case ETH_P_IP:
669   - m = m_get();
  668 + m = m_get(slirp);
670 669 if (!m)
671 670 return;
672 671 /* Note: we add to align the IP header */
... ... @@ -687,7 +686,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
687 686 }
688 687  
689 688 /* output the IP packet to the ethernet device */
690   -void if_encap(const uint8_t *ip_data, int ip_data_len)
  689 +void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
691 690 {
692 691 uint8_t buf[1600];
693 692 struct ethhdr *eh = (struct ethhdr *)buf;
... ... @@ -695,7 +694,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
695 694 if (ip_data_len + ETH_HLEN > sizeof(buf))
696 695 return;
697 696  
698   - if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
  697 + if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
699 698 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
700 699 struct ethhdr *reh = (struct ethhdr *)arp_req;
701 700 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)
708 707 will retry sending its packet. */
709 708 memset(reh->h_dest, 0xff, ETH_ALEN);
710 709 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
711   - memcpy(&reh->h_source[2], &vhost_addr, 4);
  710 + memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
712 711 reh->h_proto = htons(ETH_P_ARP);
713 712 rah->ar_hrd = htons(1);
714 713 rah->ar_pro = htons(ETH_P_IP);
... ... @@ -717,20 +716,20 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
717 716 rah->ar_op = htons(ARPOP_REQUEST);
718 717 /* source hw addr */
719 718 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
720   - memcpy(&rah->ar_sha[2], &vhost_addr, 4);
  719 + memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
721 720 /* source IP */
722   - rah->ar_sip = vhost_addr.s_addr;
  721 + rah->ar_sip = slirp->vhost_addr.s_addr;
723 722 /* target hw addr (none) */
724 723 memset(rah->ar_tha, 0, ETH_ALEN);
725 724 /* target IP */
726 725 rah->ar_tip = iph->ip_dst.s_addr;
727   - client_ipaddr = iph->ip_dst;
  726 + slirp->client_ipaddr = iph->ip_dst;
728 727 slirp_output(arp_req, sizeof(arp_req));
729 728 } else {
730   - memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
  729 + memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
731 730 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
732 731 /* XXX: not correct */
733   - memcpy(&eh->h_source[2], &vhost_addr, 4);
  732 + memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
734 733 eh->h_proto = htons(ETH_P_IP);
735 734 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
736 735 slirp_output(buf, ip_data_len + ETH_HLEN);
... ... @@ -740,8 +739,9 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
740 739 /* Drop host forwarding rule, return 0 if found. */
741 740 int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
742 741 {
  742 + Slirp *slirp = &slirp_instance;
743 743 struct socket *so;
744   - struct socket *head = (is_udp ? &udb : &tcb);
  744 + struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
745 745 struct sockaddr_in addr;
746 746 int port = htons(host_port);
747 747 socklen_t addr_len;
... ... @@ -764,16 +764,18 @@ int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
764 764 int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
765 765 struct in_addr guest_addr, int guest_port)
766 766 {
  767 + Slirp *slirp = &slirp_instance;
  768 +
767 769 if (!guest_addr.s_addr) {
768   - guest_addr = vdhcp_startaddr;
  770 + guest_addr = slirp->vdhcp_startaddr;
769 771 }
770 772 if (is_udp) {
771   - if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
772   - htons(guest_port), SS_HOSTFWD))
  773 + if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
  774 + guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
773 775 return -1;
774 776 } else {
775   - if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
776   - htons(guest_port), SS_HOSTFWD))
  777 + if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
  778 + guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
777 779 return -1;
778 780 }
779 781 return 0;
... ... @@ -782,16 +784,19 @@ int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
782 784 int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
783 785 int guest_port)
784 786 {
  787 + Slirp *slirp = &slirp_instance;
  788 +
785 789 if (!guest_addr.s_addr) {
786   - guest_addr.s_addr =
787   - vnetwork_addr.s_addr | (htonl(0x0204) & ~vnetwork_mask.s_addr);
  790 + guest_addr.s_addr = slirp->vnetwork_addr.s_addr |
  791 + (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
788 792 }
789   - if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
790   - guest_addr.s_addr == vhost_addr.s_addr ||
791   - guest_addr.s_addr == vnameserver_addr.s_addr) {
  793 + if ((guest_addr.s_addr & slirp->vnetwork_mask.s_addr) !=
  794 + slirp->vnetwork_addr.s_addr ||
  795 + guest_addr.s_addr == slirp->vhost_addr.s_addr ||
  796 + guest_addr.s_addr == slirp->vnameserver_addr.s_addr) {
792 797 return -1;
793 798 }
794   - return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
  799 + return add_exec(&slirp->exec_list, do_pty, (char *)args, guest_addr,
795 800 htons(guest_port));
796 801 }
797 802  
... ... @@ -806,11 +811,11 @@ ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
806 811 }
807 812  
808 813 static struct socket *
809   -slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
  814 +slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
810 815 {
811 816 struct socket *so;
812 817  
813   - for (so = tcb.so_next; so != &tcb; so = so->so_next) {
  818 + for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
814 819 if (so->so_faddr.s_addr == guest_addr.s_addr &&
815 820 htons(so->so_fport) == guest_port) {
816 821 return so;
... ... @@ -821,10 +826,11 @@ slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
821 826  
822 827 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
823 828 {
  829 + Slirp *slirp = &slirp_instance;
824 830 struct iovec iov[2];
825 831 struct socket *so;
826 832  
827   - so = slirp_find_ctl_socket(guest_addr, guest_port);
  833 + so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
828 834  
829 835 if (!so || so->so_state & SS_NOFDREF)
830 836 return 0;
... ... @@ -838,8 +844,9 @@ size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
838 844 void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
839 845 const uint8_t *buf, int size)
840 846 {
  847 + Slirp *slirp = &slirp_instance;
841 848 int ret;
842   - struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
  849 + struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
843 850  
844 851 if (!so)
845 852 return;
... ... @@ -928,12 +935,14 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
928 935  
929 936 static void slirp_state_save(QEMUFile *f, void *opaque)
930 937 {
  938 + Slirp *slirp = opaque;
931 939 struct ex_list *ex_ptr;
932 940  
933   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
  941 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
934 942 if (ex_ptr->ex_pty == 3) {
935 943 struct socket *so;
936   - so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
  944 + so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
  945 + ntohs(ex_ptr->ex_fport));
937 946 if (!so)
938 947 continue;
939 948  
... ... @@ -942,7 +951,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
942 951 }
943 952 qemu_put_byte(f, 0);
944 953  
945   - qemu_put_be16(f, ip_id);
  954 + qemu_put_be16(f, slirp->ip_id);
946 955 }
947 956  
948 957 static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
... ... @@ -1041,12 +1050,13 @@ static int slirp_socket_load(QEMUFile *f, struct socket *so)
1041 1050  
1042 1051 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1043 1052 {
  1053 + Slirp *slirp = opaque;
1044 1054 struct ex_list *ex_ptr;
1045 1055 int r;
1046 1056  
1047 1057 while ((r = qemu_get_byte(f))) {
1048 1058 int ret;
1049   - struct socket *so = socreate();
  1059 + struct socket *so = socreate(slirp);
1050 1060  
1051 1061 if (!so)
1052 1062 return -ENOMEM;
... ... @@ -1056,11 +1066,11 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1056 1066 if (ret < 0)
1057 1067 return ret;
1058 1068  
1059   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
1060   - vnetwork_addr.s_addr) {
  1069 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
  1070 + slirp->vnetwork_addr.s_addr) {
1061 1071 return -EINVAL;
1062 1072 }
1063   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  1073 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1064 1074 if (ex_ptr->ex_pty == 3 &&
1065 1075 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1066 1076 so->so_fport == ex_ptr->ex_fport) {
... ... @@ -1074,7 +1084,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1074 1084 }
1075 1085  
1076 1086 if (version_id >= 2) {
1077   - ip_id = qemu_get_be16(f);
  1087 + slirp->ip_id = qemu_get_be16(f);
1078 1088 }
1079 1089  
1080 1090 return 0;
... ...
slirp/slirp.h
... ... @@ -185,6 +185,7 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
185 185  
186 186 #include "debug.h"
187 187  
  188 +#include "libslirp.h"
188 189 #include "ip.h"
189 190 #include "tcp.h"
190 191 #include "tcp_timer.h"
... ... @@ -204,14 +205,67 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
204 205  
205 206 #include "bootp.h"
206 207 #include "tftp.h"
207   -#include "libslirp.h"
  208 +
  209 +struct Slirp {
  210 + /* virtual network configuration */
  211 + struct in_addr vnetwork_addr;
  212 + struct in_addr vnetwork_mask;
  213 + struct in_addr vhost_addr;
  214 + struct in_addr vdhcp_startaddr;
  215 + struct in_addr vnameserver_addr;
  216 +
  217 + /* ARP cache for the guest IP addresses (XXX: allow many entries) */
  218 + uint8_t client_ethaddr[6];
  219 +
  220 + struct in_addr client_ipaddr;
  221 + char client_hostname[33];
  222 +
  223 + int restricted;
  224 + struct timeval tt;
  225 + struct ex_list *exec_list;
  226 +
  227 + /* mbuf states */
  228 + struct mbuf m_freelist, m_usedlist;
  229 + int mbuf_alloced;
  230 +
  231 + /* if states */
  232 + int if_queued; /* number of packets queued so far */
  233 + struct mbuf if_fastq; /* fast queue (for interactive data) */
  234 + struct mbuf if_batchq; /* queue for non-interactive data */
  235 + struct mbuf *next_m; /* pointer to next mbuf to output */
  236 +
  237 + /* ip states */
  238 + struct ipq ipq; /* ip reass. queue */
  239 + u_int16_t ip_id; /* ip packet ctr, for ids */
  240 +
  241 + /* bootp/dhcp states */
  242 + BOOTPClient bootp_clients[NB_BOOTP_CLIENTS];
  243 + char *bootp_filename;
  244 +
  245 + /* tcp states */
  246 + struct socket tcb;
  247 + struct socket *tcp_last_so;
  248 + tcp_seq tcp_iss; /* tcp initial send seq # */
  249 + u_int32_t tcp_now; /* for RFC 1323 timestamps */
  250 +
  251 + /* udp states */
  252 + struct socket udb;
  253 + struct socket *udp_last_so;
  254 +
  255 + /* tftp states */
  256 + char *tftp_prefix;
  257 + struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
  258 +
  259 +};
  260 +
  261 +extern Slirp slirp_instance;
208 262  
209 263 #ifndef NULL
210 264 #define NULL (void *)0
211 265 #endif
212 266  
213 267 #ifndef FULL_BOLT
214   -void if_start _P((void));
  268 +void if_start _P((Slirp *));
215 269 #else
216 270 void if_start _P((struct ttys *));
217 271 #endif
... ... @@ -257,13 +311,13 @@ void lprint _P((const char *, ...));
257 311 int cksum(struct mbuf *m, int len);
258 312  
259 313 /* if.c */
260   -void if_init _P((void));
  314 +void if_init _P((Slirp *));
261 315 void if_output _P((struct socket *, struct mbuf *));
262 316  
263 317 /* ip_input.c */
264   -void ip_init _P((void));
  318 +void ip_init _P((Slirp *));
265 319 void ip_input _P((struct mbuf *));
266   -void ip_slowtimo _P((void));
  320 +void ip_slowtimo _P((Slirp *));
267 321 void ip_stripoptions _P((register struct mbuf *, struct mbuf *));
268 322  
269 323 /* ip_output.c */
... ... @@ -278,7 +332,7 @@ int tcp_output _P((register struct tcpcb *));
278 332 void tcp_setpersist _P((register struct tcpcb *));
279 333  
280 334 /* tcp_subr.c */
281   -void tcp_init _P((void));
  335 +void tcp_init _P((Slirp *));
282 336 void tcp_template _P((struct tcpcb *));
283 337 void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int));
284 338 struct tcpcb * tcp_newtcpcb _P((struct socket *));
... ...
slirp/socket.c
... ... @@ -41,7 +41,7 @@ solookup(struct socket *head, struct in_addr laddr, u_int lport,
41 41 * insque() it into the correct linked-list
42 42 */
43 43 struct socket *
44   -socreate(void)
  44 +socreate(Slirp *slirp)
45 45 {
46 46 struct socket *so;
47 47  
... ... @@ -50,6 +50,7 @@ socreate(void)
50 50 memset(so, 0, sizeof(struct socket));
51 51 so->so_state = SS_NOFDREF;
52 52 so->s = -1;
  53 + so->slirp = slirp;
53 54 }
54 55 return(so);
55 56 }
... ... @@ -60,15 +61,17 @@ socreate(void)
60 61 void
61 62 sofree(struct socket *so)
62 63 {
  64 + Slirp *slirp = so->slirp;
  65 +
63 66 if (so->so_emu==EMU_RSH && so->extra) {
64 67 sofree(so->extra);
65 68 so->extra=NULL;
66 69 }
67   - if (so == tcp_last_so)
68   - tcp_last_so = &tcb;
69   - else if (so == udp_last_so)
70   - udp_last_so = &udb;
71   -
  70 + if (so == slirp->tcp_last_so) {
  71 + slirp->tcp_last_so = &slirp->tcb;
  72 + } else if (so == slirp->udp_last_so) {
  73 + slirp->udp_last_so = &slirp->udb;
  74 + }
72 75 m_free(so->so_m);
73 76  
74 77 if(so->so_next && so->so_prev)
... ... @@ -473,7 +476,10 @@ sorecvfrom(struct socket *so)
473 476 int n;
474 477 #endif
475 478  
476   - if (!(m = m_get())) return;
  479 + m = m_get(so->slirp);
  480 + if (!m) {
  481 + return;
  482 + }
477 483 m->m_data += IF_MAXLINKHDR;
478 484  
479 485 /*
... ... @@ -533,6 +539,7 @@ sorecvfrom(struct socket *so)
533 539 int
534 540 sosendto(struct socket *so, struct mbuf *m)
535 541 {
  542 + Slirp *slirp = so->slirp;
536 543 int ret;
537 544 struct sockaddr_in addr;
538 545  
... ... @@ -541,10 +548,10 @@ sosendto(struct socket *so, struct mbuf *m)
541 548 DEBUG_ARG("m = %lx", (long)m);
542 549  
543 550 addr.sin_family = AF_INET;
544   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
545   - vnetwork_addr.s_addr) {
  551 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  552 + slirp->vnetwork_addr.s_addr) {
546 553 /* It's an alias */
547   - if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
  554 + if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
548 555 addr.sin_addr = dns_addr;
549 556 } else {
550 557 addr.sin_addr = loopback_addr;
... ... @@ -576,7 +583,8 @@ sosendto(struct socket *so, struct mbuf *m)
576 583 * Listen for incoming TCP connections
577 584 */
578 585 struct socket *
579   -tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags)
  586 +tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
  587 + u_int lport, int flags)
580 588 {
581 589 struct sockaddr_in addr;
582 590 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
590 598 DEBUG_ARG("lport = %d", lport);
591 599 DEBUG_ARG("flags = %x", flags);
592 600  
593   - if ((so = socreate()) == NULL) {
  601 + so = socreate(slirp);
  602 + if (!so) {
594 603 return NULL;
595 604 }
596 605  
... ... @@ -599,7 +608,7 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
599 608 free(so);
600 609 return NULL;
601 610 }
602   - insque(so,&tcb);
  611 + insque(so, &slirp->tcb);
603 612  
604 613 /*
605 614 * 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
637 646 getsockname(s,(struct sockaddr *)&addr,&addrlen);
638 647 so->so_fport = addr.sin_port;
639 648 if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
640   - so->so_faddr = vhost_addr;
  649 + so->so_faddr = slirp->vhost_addr;
641 650 else
642 651 so->so_faddr = addr.sin_addr;
643 652  
... ...
slirp/socket.h
... ... @@ -20,6 +20,8 @@ struct socket {
20 20  
21 21 int s; /* The actual socket */
22 22  
  23 + Slirp *slirp; /* managing slirp instance */
  24 +
23 25 /* XXX union these with not-yet-used sbuf params */
24 26 struct mbuf *so_m; /* Pointer to the original SYN packet,
25 27 * for non-blocking connect()'s, and
... ... @@ -72,10 +74,8 @@ struct socket {
72 74 #define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */
73 75 #define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */
74 76  
75   -extern struct socket tcb;
76   -
77 77 struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
78   -struct socket * socreate _P((void));
  78 +struct socket * socreate _P((Slirp *));
79 79 void sofree _P((struct socket *));
80 80 int soread _P((struct socket *));
81 81 void sorecvoob _P((struct socket *));
... ... @@ -83,7 +83,8 @@ int sosendoob _P((struct socket *));
83 83 int sowrite _P((struct socket *));
84 84 void sorecvfrom _P((struct socket *));
85 85 int sosendto _P((struct socket *, struct mbuf *));
86   -struct socket * tcp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int));
  86 +struct socket * tcp_listen _P((Slirp *, u_int32_t, u_int, u_int32_t, u_int,
  87 + int));
87 88 void soisfconnecting _P((register struct socket *));
88 89 void soisfconnected _P((register struct socket *));
89 90 void sofwdrain _P((struct socket *));
... ...
slirp/tcp.h
... ... @@ -38,8 +38,6 @@ typedef u_int32_t tcp_seq;
38 38 #define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */
39 39 #define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */
40 40  
41   -extern struct socket *tcp_last_so;
42   -
43 41 #define TCP_SNDSPACE 8192
44 42 #define TCP_RCVSPACE 8192
45 43  
... ... @@ -163,6 +161,4 @@ struct tcphdr {
163 161  
164 162 #define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
165 163  
166   -extern tcp_seq tcp_iss; /* tcp initial send seq # */
167   -
168 164 #endif
... ...
slirp/tcp_input.c
... ... @@ -41,12 +41,7 @@
41 41 #include <slirp.h>
42 42 #include "ip_icmp.h"
43 43  
44   -struct socket tcb;
45   -
46 44 #define TCPREXMTTHRESH 3
47   -struct socket *tcp_last_so = &tcb;
48   -
49   -tcp_seq tcp_iss; /* tcp initial send seq # */
50 45  
51 46 #define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
52 47  
... ... @@ -233,6 +228,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
233 228 u_long tiwin;
234 229 int ret;
235 230 struct ex_list *ex_ptr;
  231 + Slirp *slirp;
236 232  
237 233 DEBUG_CALL("tcp_input");
238 234 DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
... ... @@ -243,6 +239,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
243 239 */
244 240 if (m == NULL) {
245 241 so = inso;
  242 + slirp = so->slirp;
246 243  
247 244 /* Re-set a few variables */
248 245 tp = sototcpcb(so);
... ... @@ -254,6 +251,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
254 251  
255 252 goto cont_conn;
256 253 }
  254 + slirp = m->slirp;
257 255  
258 256 /*
259 257 * Get IP and TCP header together in first mbuf.
... ... @@ -318,8 +316,8 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
318 316 m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
319 317 m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
320 318  
321   - if (slirp_restrict) {
322   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  319 + if (slirp->restricted) {
  320 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
323 321 if (ex_ptr->ex_fport == ti->ti_dport &&
324 322 ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
325 323 break;
... ... @@ -332,15 +330,15 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
332 330 * Locate pcb for segment.
333 331 */
334 332 findso:
335   - so = tcp_last_so;
  333 + so = slirp->tcp_last_so;
336 334 if (so->so_fport != ti->ti_dport ||
337 335 so->so_lport != ti->ti_sport ||
338 336 so->so_laddr.s_addr != ti->ti_src.s_addr ||
339 337 so->so_faddr.s_addr != ti->ti_dst.s_addr) {
340   - so = solookup(&tcb, ti->ti_src, ti->ti_sport,
  338 + so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport,
341 339 ti->ti_dst, ti->ti_dport);
342 340 if (so)
343   - tcp_last_so = so;
  341 + slirp->tcp_last_so = so;
344 342 }
345 343  
346 344 /*
... ... @@ -360,7 +358,7 @@ findso:
360 358 if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
361 359 goto dropwithreset;
362 360  
363   - if ((so = socreate()) == NULL)
  361 + if ((so = socreate(slirp)) == NULL)
364 362 goto dropwithreset;
365 363 if (tcp_attach(so) < 0) {
366 364 free(so); /* Not sofree (if it failed, it's not insqued) */
... ... @@ -555,12 +553,13 @@ findso:
555 553 * If this is destined for the control address, then flag to
556 554 * tcp_ctl once connected, otherwise connect
557 555 */
558   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
559   - vnetwork_addr.s_addr) {
560   - if (so->so_faddr.s_addr != vhost_addr.s_addr &&
561   - so->so_faddr.s_addr != vnameserver_addr.s_addr) {
  556 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  557 + slirp->vnetwork_addr.s_addr) {
  558 + if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
  559 + so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
562 560 /* May be an add exec */
563   - for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  561 + for (ex_ptr = slirp->exec_list; ex_ptr;
  562 + ex_ptr = ex_ptr->ex_next) {
564 563 if(ex_ptr->ex_fport == so->so_fport &&
565 564 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
566 565 so->so_state |= SS_CTL;
... ... @@ -631,8 +630,8 @@ findso:
631 630 if (iss)
632 631 tp->iss = iss;
633 632 else
634   - tp->iss = tcp_iss;
635   - tcp_iss += TCP_ISSINCR/2;
  633 + tp->iss = slirp->tcp_iss;
  634 + slirp->tcp_iss += TCP_ISSINCR/2;
636 635 tp->irs = ti->ti_seq;
637 636 tcp_sendseqinit(tp);
638 637 tcp_rcvseqinit(tp);
... ...
slirp/tcp_output.c
... ... @@ -290,7 +290,7 @@ send:
290 290 * the template for sends on this connection.
291 291 */
292 292 if (len) {
293   - m = m_get();
  293 + m = m_get(so->slirp);
294 294 if (m == NULL) {
295 295 error = 1;
296 296 goto out;
... ... @@ -310,7 +310,7 @@ send:
310 310 if (off + len == so->so_snd.sb_cc)
311 311 flags |= TH_PUSH;
312 312 } else {
313   - m = m_get();
  313 + m = m_get(so->slirp);
314 314 if (m == NULL) {
315 315 error = 1;
316 316 goto out;
... ...
slirp/tcp_subr.c
... ... @@ -48,10 +48,11 @@
48 48 * Tcp initialization
49 49 */
50 50 void
51   -tcp_init(void)
  51 +tcp_init(Slirp *slirp)
52 52 {
53   - tcp_iss = 1; /* wrong */
54   - tcb.so_next = tcb.so_prev = &tcb;
  53 + slirp->tcp_iss = 1; /* wrong */
  54 + slirp->tcb.so_next = slirp->tcb.so_prev = &slirp->tcb;
  55 + slirp->tcp_last_so = &slirp->tcb;
55 56 }
56 57  
57 58 /*
... ... @@ -116,7 +117,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
116 117 if (tp)
117 118 win = sbspace(&tp->t_socket->so_rcv);
118 119 if (m == NULL) {
119   - if ((m = m_get()) == NULL)
  120 + if ((m = m_get(tp->t_socket->slirp)) == NULL)
120 121 return;
121 122 tlen = 0;
122 123 m->m_data += IF_MAXLINKHDR;
... ... @@ -237,6 +238,7 @@ tcp_close(struct tcpcb *tp)
237 238 {
238 239 register struct tcpiphdr *t;
239 240 struct socket *so = tp->t_socket;
  241 + Slirp *slirp = so->slirp;
240 242 register struct mbuf *m;
241 243  
242 244 DEBUG_CALL("tcp_close");
... ... @@ -253,8 +255,8 @@ tcp_close(struct tcpcb *tp)
253 255 free(tp);
254 256 so->so_tcpcb = NULL;
255 257 /* clobber input socket cache if we're closing the cached connection */
256   - if (so == tcp_last_so)
257   - tcp_last_so = &tcb;
  258 + if (so == slirp->tcp_last_so)
  259 + slirp->tcp_last_so = &slirp->tcb;
258 260 closesocket(so->s);
259 261 sbfree(&so->so_rcv);
260 262 sbfree(&so->so_snd);
... ... @@ -317,6 +319,7 @@ tcp_sockclosed(struct tcpcb *tp)
317 319 */
318 320 int tcp_fconnect(struct socket *so)
319 321 {
  322 + Slirp *slirp = so->slirp;
320 323 int ret=0;
321 324  
322 325 DEBUG_CALL("tcp_fconnect");
... ... @@ -333,9 +336,10 @@ int tcp_fconnect(struct socket *so)
333 336 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
334 337  
335 338 addr.sin_family = AF_INET;
336   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
  339 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  340 + slirp->vnetwork_addr.s_addr) {
337 341 /* It's an alias */
338   - if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
  342 + if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
339 343 addr.sin_addr = dns_addr;
340 344 } else {
341 345 addr.sin_addr = loopback_addr;
... ... @@ -375,6 +379,7 @@ int tcp_fconnect(struct socket *so)
375 379 void
376 380 tcp_connect(struct socket *inso)
377 381 {
  382 + Slirp *slirp = inso->slirp;
378 383 struct socket *so;
379 384 struct sockaddr_in addr;
380 385 socklen_t addrlen = sizeof(struct sockaddr_in);
... ... @@ -392,7 +397,7 @@ tcp_connect(struct socket *inso)
392 397 /* FACCEPTONCE already have a tcpcb */
393 398 so = inso;
394 399 } else {
395   - if ((so = socreate()) == NULL) {
  400 + if ((so = socreate(slirp)) == NULL) {
396 401 /* If it failed, get rid of the pending connection */
397 402 closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen));
398 403 return;
... ... @@ -423,7 +428,7 @@ tcp_connect(struct socket *inso)
423 428 so->so_faddr = addr.sin_addr;
424 429 /* Translate connections from localhost to the real hostname */
425 430 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
426   - so->so_faddr = vhost_addr;
  431 + so->so_faddr = slirp->vhost_addr;
427 432  
428 433 /* Close the accept() socket, set right state */
429 434 if (inso->so_state & SS_FACCEPTONCE) {
... ... @@ -441,8 +446,8 @@ tcp_connect(struct socket *inso)
441 446  
442 447 tp->t_state = TCPS_SYN_SENT;
443 448 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
444   - tp->iss = tcp_iss;
445   - tcp_iss += TCP_ISSINCR/2;
  449 + tp->iss = slirp->tcp_iss;
  450 + slirp->tcp_iss += TCP_ISSINCR/2;
446 451 tcp_sendseqinit(tp);
447 452 tcp_output(tp);
448 453 }
... ... @@ -456,7 +461,7 @@ tcp_attach(struct socket *so)
456 461 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
457 462 return -1;
458 463  
459   - insque(so, &tcb);
  464 + insque(so, &so->slirp->tcb);
460 465  
461 466 return 0;
462 467 }
... ... @@ -539,6 +544,7 @@ tcp_tos(struct socket *so)
539 544 int
540 545 tcp_emu(struct socket *so, struct mbuf *m)
541 546 {
  547 + Slirp *slirp = so->slirp;
542 548 u_int n1, n2, n3, n4, n5, n6;
543 549 char buff[257];
544 550 u_int32_t laddr;
... ... @@ -572,7 +578,9 @@ tcp_emu(struct socket *so, struct mbuf *m)
572 578 HTONS(n1);
573 579 HTONS(n2);
574 580 /* n2 is the one on our host */
575   - for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
  581 + for (tmpso = slirp->tcb.so_next;
  582 + tmpso != &slirp->tcb;
  583 + tmpso = tmpso->so_next) {
576 584 if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
577 585 tmpso->so_lport == n2 &&
578 586 tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
... ... @@ -608,9 +616,10 @@ tcp_emu(struct socket *so, struct mbuf *m)
608 616 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
609 617 lport = htons((n5 << 8) | (n6));
610 618  
611   - if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
  619 + if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
  620 + lport, SS_FACCEPTONCE)) == NULL) {
612 621 return 1;
613   -
  622 + }
614 623 n6 = ntohs(so->so_fport);
615 624  
616 625 n5 = (n6 >> 8) & 0xff;
... ... @@ -640,9 +649,10 @@ tcp_emu(struct socket *so, struct mbuf *m)
640 649 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
641 650 lport = htons((n5 << 8) | (n6));
642 651  
643   - if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
  652 + if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
  653 + lport, SS_FACCEPTONCE)) == NULL) {
644 654 return 1;
645   -
  655 + }
646 656 n6 = ntohs(so->so_fport);
647 657  
648 658 n5 = (n6 >> 8) & 0xff;
... ... @@ -680,7 +690,8 @@ tcp_emu(struct socket *so, struct mbuf *m)
680 690 lport += m->m_data[i] - '0';
681 691 }
682 692 if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
683   - (so = tcp_listen(INADDR_ANY, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
  693 + (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr,
  694 + htons(lport), SS_FACCEPTONCE)) != NULL)
684 695 m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d",
685 696 ntohs(so->so_fport)) + 1;
686 697 return 1;
... ... @@ -695,27 +706,33 @@ tcp_emu(struct socket *so, struct mbuf *m)
695 706  
696 707 /* The %256s is for the broken mIRC */
697 708 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
698   - if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
  709 + if ((so = tcp_listen(slirp, INADDR_ANY, 0,
  710 + htonl(laddr), htons(lport),
  711 + SS_FACCEPTONCE)) == NULL) {
699 712 return 1;
700   -
  713 + }
701 714 m->m_len = bptr - m->m_data; /* Adjust length */
702 715 m->m_len += snprintf(bptr, m->m_hdr.mh_size,
703 716 "DCC CHAT chat %lu %u%c\n",
704 717 (unsigned long)ntohl(so->so_faddr.s_addr),
705 718 ntohs(so->so_fport), 1);
706 719 } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
707   - if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
  720 + if ((so = tcp_listen(slirp, INADDR_ANY, 0,
  721 + htonl(laddr), htons(lport),
  722 + SS_FACCEPTONCE)) == NULL) {
708 723 return 1;
709   -
  724 + }
710 725 m->m_len = bptr - m->m_data; /* Adjust length */
711 726 m->m_len += snprintf(bptr, m->m_hdr.mh_size,
712 727 "DCC SEND %s %lu %u %u%c\n", buff,
713 728 (unsigned long)ntohl(so->so_faddr.s_addr),
714 729 ntohs(so->so_fport), n1, 1);
715 730 } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
716   - if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
  731 + if ((so = tcp_listen(slirp, INADDR_ANY, 0,
  732 + htonl(laddr), htons(lport),
  733 + SS_FACCEPTONCE)) == NULL) {
717 734 return 1;
718   -
  735 + }
719 736 m->m_len = bptr - m->m_data; /* Adjust length */
720 737 m->m_len += snprintf(bptr, m->m_hdr.mh_size,
721 738 "DCC MOVE %s %lu %u %u%c\n", buff,
... ... @@ -828,7 +845,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
828 845  
829 846 /* try to get udp port between 6970 - 7170 */
830 847 for (p = 6970; p < 7071; p++) {
831   - if (udp_listen(INADDR_ANY,
  848 + if (udp_listen(slirp, INADDR_ANY,
832 849 htons(p),
833 850 so->so_laddr.s_addr,
834 851 htons(lport),
... ... @@ -865,6 +882,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
865 882 */
866 883 int tcp_ctl(struct socket *so)
867 884 {
  885 + Slirp *slirp = so->slirp;
868 886 struct sbuf *sb = &so->so_snd;
869 887 struct ex_list *ex_ptr;
870 888 int do_pty;
... ... @@ -872,9 +890,9 @@ int tcp_ctl(struct socket *so)
872 890 DEBUG_CALL("tcp_ctl");
873 891 DEBUG_ARG("so = %lx", (long )so);
874 892  
875   - if (so->so_faddr.s_addr != vhost_addr.s_addr) {
  893 + if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
876 894 /* Check if it's pty_exec */
877   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  895 + for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
878 896 if (ex_ptr->ex_fport == so->so_fport &&
879 897 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
880 898 if (ex_ptr->ex_pty == 3) {
... ...
slirp/tcp_timer.c
... ... @@ -32,24 +32,22 @@
32 32  
33 33 #include <slirp.h>
34 34  
35   -u_int32_t tcp_now; /* for RFC 1323 timestamps */
36   -
37 35 static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
38 36  
39 37 /*
40 38 * Fast timeout routine for processing delayed acks
41 39 */
42 40 void
43   -tcp_fasttimo(void)
  41 +tcp_fasttimo(Slirp *slirp)
44 42 {
45 43 register struct socket *so;
46 44 register struct tcpcb *tp;
47 45  
48 46 DEBUG_CALL("tcp_fasttimo");
49 47  
50   - so = tcb.so_next;
  48 + so = slirp->tcb.so_next;
51 49 if (so)
52   - for (; so != &tcb; so = so->so_next)
  50 + for (; so != &slirp->tcb; so = so->so_next)
53 51 if ((tp = (struct tcpcb *)so->so_tcpcb) &&
54 52 (tp->t_flags & TF_DELACK)) {
55 53 tp->t_flags &= ~TF_DELACK;
... ... @@ -64,7 +62,7 @@ tcp_fasttimo(void)
64 62 * causes finite state machine actions if timers expire.
65 63 */
66 64 void
67   -tcp_slowtimo(void)
  65 +tcp_slowtimo(Slirp *slirp)
68 66 {
69 67 register struct socket *ip, *ipnxt;
70 68 register struct tcpcb *tp;
... ... @@ -75,10 +73,10 @@ tcp_slowtimo(void)
75 73 /*
76 74 * Search through tcb's and update active timers.
77 75 */
78   - ip = tcb.so_next;
  76 + ip = slirp->tcb.so_next;
79 77 if (ip == 0)
80 78 return;
81   - for (; ip != &tcb; ip = ipnxt) {
  79 + for (; ip != &slirp->tcb; ip = ipnxt) {
82 80 ipnxt = ip->so_next;
83 81 tp = sototcpcb(ip);
84 82 if (tp == 0)
... ... @@ -96,8 +94,8 @@ tcp_slowtimo(void)
96 94 tpgone:
97 95 ;
98 96 }
99   - tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
100   - tcp_now++; /* for timestamps */
  97 + slirp->tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
  98 + slirp->tcp_now++; /* for timestamps */
101 99 }
102 100  
103 101 /*
... ...
slirp/tcp_timer.h
... ... @@ -120,8 +120,8 @@ extern const int tcp_backoff[];
120 120  
121 121 struct tcpcb;
122 122  
123   -void tcp_fasttimo _P((void));
124   -void tcp_slowtimo _P((void));
  123 +void tcp_fasttimo _P((Slirp *));
  124 +void tcp_slowtimo _P((Slirp *));
125 125 void tcp_canceltimers _P((struct tcpcb *));
126 126  
127 127 #endif
... ...
slirp/tcp_var.h
... ... @@ -158,6 +158,4 @@ struct tcpcb {
158 158 #define TCP_REXMTVAL(tp) \
159 159 (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
160 160  
161   -extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
162   -
163 161 #endif
... ...
slirp/tftp.c
... ... @@ -25,41 +25,31 @@
25 25 #include <slirp.h>
26 26 #include "qemu-common.h"
27 27  
28   -struct tftp_session {
29   - int in_use;
30   - char *filename;
31   -
32   - struct in_addr client_ip;
33   - u_int16_t client_port;
34   -
35   - int timestamp;
36   -};
37   -
38   -static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
39   -
40   -char *tftp_prefix;
  28 +static inline int tftp_session_in_use(struct tftp_session *spt)
  29 +{
  30 + return (spt->slirp != NULL);
  31 +}
41 32  
42   -static void tftp_session_update(struct tftp_session *spt)
  33 +static inline void tftp_session_update(struct tftp_session *spt)
43 34 {
44 35 spt->timestamp = curtime;
45   - spt->in_use = 1;
46 36 }
47 37  
48 38 static void tftp_session_terminate(struct tftp_session *spt)
49 39 {
50   - qemu_free(spt->filename);
51   - spt->in_use = 0;
  40 + qemu_free(spt->filename);
  41 + spt->slirp = NULL;
52 42 }
53 43  
54   -static int tftp_session_allocate(struct tftp_t *tp)
  44 +static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp)
55 45 {
56 46 struct tftp_session *spt;
57 47 int k;
58 48  
59 49 for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
60   - spt = &tftp_sessions[k];
  50 + spt = &slirp->tftp_sessions[k];
61 51  
62   - if (!spt->in_use)
  52 + if (!tftp_session_in_use(spt))
63 53 goto found;
64 54  
65 55 /* sessions time out after 5 inactive seconds */
... ... @@ -75,21 +65,22 @@ static int tftp_session_allocate(struct tftp_t *tp)
75 65 memset(spt, 0, sizeof(*spt));
76 66 memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
77 67 spt->client_port = tp->udp.uh_sport;
  68 + spt->slirp = slirp;
78 69  
79 70 tftp_session_update(spt);
80 71  
81 72 return k;
82 73 }
83 74  
84   -static int tftp_session_find(struct tftp_t *tp)
  75 +static int tftp_session_find(Slirp *slirp, struct tftp_t *tp)
85 76 {
86 77 struct tftp_session *spt;
87 78 int k;
88 79  
89 80 for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
90   - spt = &tftp_sessions[k];
  81 + spt = &slirp->tftp_sessions[k];
91 82  
92   - if (spt->in_use) {
  83 + if (tftp_session_in_use(spt)) {
93 84 if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) {
94 85 if (spt->client_port == tp->udp.uh_sport) {
95 86 return k;
... ... @@ -133,7 +124,7 @@ static int tftp_send_oack(struct tftp_session *spt,
133 124 struct tftp_t *tp;
134 125 int n = 0;
135 126  
136   - m = m_get();
  127 + m = m_get(spt->slirp);
137 128  
138 129 if (!m)
139 130 return -1;
... ... @@ -172,7 +163,7 @@ static void tftp_send_error(struct tftp_session *spt,
172 163 struct tftp_t *tp;
173 164 int nobytes;
174 165  
175   - m = m_get();
  166 + m = m_get(spt->slirp);
176 167  
177 168 if (!m) {
178 169 goto out;
... ... @@ -218,7 +209,7 @@ static int tftp_send_data(struct tftp_session *spt,
218 209 return -1;
219 210 }
220 211  
221   - m = m_get();
  212 + m = m_get(spt->slirp);
222 213  
223 214 if (!m) {
224 215 return -1;
... ... @@ -266,23 +257,23 @@ static int tftp_send_data(struct tftp_session *spt,
266 257 return 0;
267 258 }
268 259  
269   -static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
  260 +static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
270 261 {
271 262 struct tftp_session *spt;
272 263 int s, k;
273 264 size_t prefix_len;
274 265 char *req_fname;
275 266  
276   - s = tftp_session_allocate(tp);
  267 + s = tftp_session_allocate(slirp, tp);
277 268  
278 269 if (s < 0) {
279 270 return;
280 271 }
281 272  
282   - spt = &tftp_sessions[s];
  273 + spt = &slirp->tftp_sessions[s];
283 274  
284 275 /* unspecifed prefix means service disabled */
285   - if (!tftp_prefix) {
  276 + if (!slirp->tftp_prefix) {
286 277 tftp_send_error(spt, 2, "Access violation", tp);
287 278 return;
288 279 }
... ... @@ -292,9 +283,9 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
292 283 pktlen -= ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
293 284  
294 285 /* prepend tftp_prefix */
295   - prefix_len = strlen(tftp_prefix);
  286 + prefix_len = strlen(slirp->tftp_prefix);
296 287 spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 1);
297   - memcpy(spt->filename, tftp_prefix, prefix_len);
  288 + memcpy(spt->filename, slirp->tftp_prefix, prefix_len);
298 289  
299 290 /* get name */
300 291 req_fname = spt->filename + prefix_len;
... ... @@ -375,17 +366,17 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
375 366 tftp_send_data(spt, 1, tp);
376 367 }
377 368  
378   -static void tftp_handle_ack(struct tftp_t *tp, int pktlen)
  369 +static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
379 370 {
380 371 int s;
381 372  
382   - s = tftp_session_find(tp);
  373 + s = tftp_session_find(slirp, tp);
383 374  
384 375 if (s < 0) {
385 376 return;
386 377 }
387 378  
388   - if (tftp_send_data(&tftp_sessions[s],
  379 + if (tftp_send_data(&slirp->tftp_sessions[s],
389 380 ntohs(tp->x.tp_data.tp_block_nr) + 1,
390 381 tp) < 0) {
391 382 return;
... ... @@ -398,11 +389,11 @@ void tftp_input(struct mbuf *m)
398 389  
399 390 switch(ntohs(tp->tp_op)) {
400 391 case TFTP_RRQ:
401   - tftp_handle_rrq(tp, m->m_len);
  392 + tftp_handle_rrq(m->slirp, tp, m->m_len);
402 393 break;
403 394  
404 395 case TFTP_ACK:
405   - tftp_handle_ack(tp, m->m_len);
  396 + tftp_handle_ack(m->slirp, tp, m->m_len);
406 397 break;
407 398 }
408 399 }
... ...
slirp/tftp.h
... ... @@ -30,4 +30,14 @@ struct tftp_t {
30 30 } x;
31 31 };
32 32  
  33 +struct tftp_session {
  34 + Slirp *slirp;
  35 + char *filename;
  36 +
  37 + struct in_addr client_ip;
  38 + u_int16_t client_port;
  39 +
  40 + int timestamp;
  41 +};
  42 +
33 43 void tftp_input(struct mbuf *m);
... ...
slirp/udp.c
... ... @@ -41,17 +41,14 @@
41 41 #include <slirp.h>
42 42 #include "ip_icmp.h"
43 43  
44   -struct socket udb;
45   -
46 44 static u_int8_t udp_tos(struct socket *so);
47 45 static void udp_emu(struct socket *so, struct mbuf *m);
48 46  
49   -struct socket *udp_last_so = &udb;
50   -
51 47 void
52   -udp_init(void)
  48 +udp_init(Slirp *slirp)
53 49 {
54   - udb.so_next = udb.so_prev = &udb;
  50 + slirp->udb.so_next = slirp->udb.so_prev = &slirp->udb;
  51 + slirp->udp_last_so = &slirp->udb;
55 52 }
56 53 /* m->m_data points at ip packet header
57 54 * m->m_len length ip packet
... ... @@ -60,6 +57,7 @@ udp_init(void)
60 57 void
61 58 udp_input(register struct mbuf *m, int iphlen)
62 59 {
  60 + Slirp *slirp = m->slirp;
63 61 register struct ip *ip;
64 62 register struct udphdr *uh;
65 63 int len;
... ... @@ -128,8 +126,9 @@ udp_input(register struct mbuf *m, int iphlen)
128 126 goto bad;
129 127 }
130 128  
131   - if (slirp_restrict)
  129 + if (slirp->restricted) {
132 130 goto bad;
  131 + }
133 132  
134 133 /*
135 134 * handle TFTP
... ... @@ -142,22 +141,23 @@ udp_input(register struct mbuf *m, int iphlen)
142 141 /*
143 142 * Locate pcb for datagram.
144 143 */
145   - so = udp_last_so;
  144 + so = slirp->udp_last_so;
146 145 if (so->so_lport != uh->uh_sport ||
147 146 so->so_laddr.s_addr != ip->ip_src.s_addr) {
148 147 struct socket *tmp;
149 148  
150   - for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
  149 + for (tmp = slirp->udb.so_next; tmp != &slirp->udb;
  150 + tmp = tmp->so_next) {
151 151 if (tmp->so_lport == uh->uh_sport &&
152 152 tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
153 153 so = tmp;
154 154 break;
155 155 }
156 156 }
157   - if (tmp == &udb) {
  157 + if (tmp == &slirp->udb) {
158 158 so = NULL;
159 159 } else {
160   - udp_last_so = so;
  160 + slirp->udp_last_so = so;
161 161 }
162 162 }
163 163  
... ... @@ -166,7 +166,10 @@ udp_input(register struct mbuf *m, int iphlen)
166 166 * If there's no socket for this packet,
167 167 * create one
168 168 */
169   - if ((so = socreate()) == NULL) goto bad;
  169 + so = socreate(slirp);
  170 + if (!so) {
  171 + goto bad;
  172 + }
170 173 if(udp_attach(so) == -1) {
171 174 DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
172 175 errno,strerror(errno)));
... ... @@ -279,15 +282,18 @@ int udp_output(struct socket *so, struct mbuf *m,
279 282 struct sockaddr_in *addr)
280 283  
281 284 {
  285 + Slirp *slirp = so->slirp;
282 286 struct sockaddr_in saddr, daddr;
283 287  
284 288 saddr = *addr;
285   - if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
286   - if ((so->so_faddr.s_addr & ~vnetwork_mask.s_addr) ==
287   - ~vnetwork_mask.s_addr) {
288   - saddr.sin_addr = vhost_addr;
  289 + if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  290 + slirp->vnetwork_addr.s_addr) {
  291 + uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
  292 +
  293 + if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
  294 + saddr.sin_addr = slirp->vhost_addr;
289 295 } else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
290   - so->so_faddr.s_addr != vhost_addr.s_addr) {
  296 + so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
291 297 saddr.sin_addr = so->so_faddr;
292 298 }
293 299 }
... ... @@ -323,7 +329,7 @@ udp_attach(struct socket *so)
323 329 } else {
324 330 /* success, insert in queue */
325 331 so->so_expire = curtime + SO_EXPIRE;
326   - insque(so,&udb);
  332 + insque(so, &so->slirp->udb);
327 333 }
328 334 }
329 335 return(so->s);
... ... @@ -595,20 +601,20 @@ struct cu_header {
595 601 }
596 602  
597 603 struct socket *
598   -udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport,
599   - int flags)
  604 +udp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
  605 + u_int lport, int flags)
600 606 {
601 607 struct sockaddr_in addr;
602 608 struct socket *so;
603 609 socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1;
604 610  
605   - if ((so = socreate()) == NULL) {
606   - free(so);
607   - return NULL;
  611 + so = socreate(slirp);
  612 + if (!so) {
  613 + return NULL;
608 614 }
609 615 so->s = socket(AF_INET,SOCK_DGRAM,0);
610 616 so->so_expire = curtime + SO_EXPIRE;
611   - insque(so,&udb);
  617 + insque(so, &slirp->udb);
612 618  
613 619 addr.sin_family = AF_INET;
614 620 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,
624 630 so->so_fport = addr.sin_port;
625 631 if (addr.sin_addr.s_addr == 0 ||
626 632 addr.sin_addr.s_addr == loopback_addr.s_addr) {
627   - so->so_faddr = vhost_addr;
  633 + so->so_faddr = slirp->vhost_addr;
628 634 } else {
629 635 so->so_faddr = addr.sin_addr;
630 636 }
... ...
slirp/udp.h
... ... @@ -36,8 +36,6 @@
36 36 #define UDP_TTL 0x60
37 37 #define UDP_UDPDATALEN 16192
38 38  
39   -extern struct socket *udp_last_so;
40   -
41 39 /*
42 40 * Udp protocol header.
43 41 * Per RFC 768, September, 1981.
... ... @@ -73,15 +71,15 @@ struct udpiphdr {
73 71 #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
74 72 #define UDPCTL_MAXID 2
75 73  
76   -extern struct socket udb;
77 74 struct mbuf;
78 75  
79   -void udp_init _P((void));
  76 +void udp_init _P((Slirp *));
80 77 void udp_input _P((register struct mbuf *, int));
81 78 int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *));
82 79 int udp_attach _P((struct socket *));
83 80 void udp_detach _P((struct socket *));
84   -struct socket * udp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int));
  81 +struct socket * udp_listen _P((Slirp *, u_int32_t, u_int, u_int32_t, u_int,
  82 + int));
85 83 int udp_output2(struct socket *so, struct mbuf *m,
86 84 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
87 85 int iptos);
... ...