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