Commit 429d0a3db8138ae6a545500b92dbe532629a24e1

Authored by blueswir1
1 parent cb457d76

Fix 64 bit issue in slirp

Signed-off-by: Gleb Natapov <gleb@redhat.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6288 c046a42c-6fe2-441c-8c8c-71466251a162
slirp/ip.h
@@ -183,35 +183,31 @@ struct ip_timestamp { @@ -183,35 +183,31 @@ struct ip_timestamp {
183 183
184 #define IP_MSS 576 /* default maximum segment size */ 184 #define IP_MSS 576 /* default maximum segment size */
185 185
186 -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */  
187 -#include <sys/types32.h>  
188 -#else  
189 #if SIZEOF_CHAR_P == 4 186 #if SIZEOF_CHAR_P == 4
190 -typedef caddr_t caddr32_t;  
191 -#else  
192 -typedef u_int32_t caddr32_t;  
193 -#endif  
194 -#endif  
195 -  
196 -#if SIZEOF_CHAR_P == 4  
197 -typedef struct ipq *ipqp_32;  
198 -typedef struct ipasfrag *ipasfragp_32; 187 +struct mbuf_ptr {
  188 + struct mbuf *mptr;
  189 + uint32_t dummy;
  190 +};
199 #else 191 #else
200 -typedef caddr32_t ipqp_32;  
201 -typedef caddr32_t ipasfragp_32; 192 +struct mbuf_ptr {
  193 + struct mbuf *mptr;
  194 +};
202 #endif 195 #endif
  196 +struct qlink {
  197 + void *next, *prev;
  198 +};
203 199
204 /* 200 /*
205 * Overlay for ip header used by other protocols (tcp, udp). 201 * Overlay for ip header used by other protocols (tcp, udp).
206 */ 202 */
207 struct ipovly { 203 struct ipovly {
208 - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ 204 + struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */
209 u_int8_t ih_x1; /* (unused) */ 205 u_int8_t ih_x1; /* (unused) */
210 u_int8_t ih_pr; /* protocol */ 206 u_int8_t ih_pr; /* protocol */
211 u_int16_t ih_len; /* protocol length */ 207 u_int16_t ih_len; /* protocol length */
212 struct in_addr ih_src; /* source internet address */ 208 struct in_addr ih_src; /* source internet address */
213 struct in_addr ih_dst; /* destination internet address */ 209 struct in_addr ih_dst; /* destination internet address */
214 -}; 210 +} __attribute__((packed));
215 211
216 /* 212 /*
217 * Ip reassembly queue structure. Each fragment 213 * Ip reassembly queue structure. Each fragment
@@ -221,44 +217,30 @@ struct ipovly { @@ -221,44 +217,30 @@ struct ipovly {
221 * size 28 bytes 217 * size 28 bytes
222 */ 218 */
223 struct ipq { 219 struct ipq {
224 - ipqp_32 next,prev; /* to other reass headers */ 220 + struct qlink frag_link; /* to ip headers of fragments */
  221 + struct qlink ip_link; /* to other reass headers */
225 u_int8_t ipq_ttl; /* time for reass q to live */ 222 u_int8_t ipq_ttl; /* time for reass q to live */
226 u_int8_t ipq_p; /* protocol of this fragment */ 223 u_int8_t ipq_p; /* protocol of this fragment */
227 u_int16_t ipq_id; /* sequence id for reassembly */ 224 u_int16_t ipq_id; /* sequence id for reassembly */
228 - ipasfragp_32 ipq_next,ipq_prev;  
229 - /* to ip headers of fragments */  
230 struct in_addr ipq_src,ipq_dst; 225 struct in_addr ipq_src,ipq_dst;
231 }; 226 };
232 227
233 /* 228 /*
234 * Ip header, when holding a fragment. 229 * Ip header, when holding a fragment.
235 * 230 *
236 - * Note: ipf_next must be at same offset as ipq_next above 231 + * Note: ipf_link must be at same offset as frag_link above
237 */ 232 */
238 struct ipasfrag { 233 struct ipasfrag {
239 -#ifdef WORDS_BIGENDIAN  
240 - u_int ip_v:4,  
241 - ip_hl:4;  
242 -#else  
243 - u_int ip_hl:4,  
244 - ip_v:4;  
245 -#endif  
246 - /* BUG : u_int changed to u_int8_t.  
247 - * sizeof(u_int)==4 on linux 2.0  
248 - */  
249 - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit  
250 - * to avoid destroying tos (PPPDTRuu);  
251 - * copied from (ip_off&IP_MF) */  
252 - u_int16_t ip_len;  
253 - u_int16_t ip_id;  
254 - u_int16_t ip_off;  
255 - u_int8_t ip_ttl;  
256 - u_int8_t ip_p;  
257 - u_int16_t ip_sum;  
258 - ipasfragp_32 ipf_next; /* next fragment */  
259 - ipasfragp_32 ipf_prev; /* previous fragment */ 234 + struct qlink ipf_link;
  235 + struct ip ipf_ip;
260 }; 236 };
261 237
  238 +#define ipf_off ipf_ip.ip_off
  239 +#define ipf_tos ipf_ip.ip_tos
  240 +#define ipf_len ipf_ip.ip_len
  241 +#define ipf_next ipf_link.next
  242 +#define ipf_prev ipf_link.prev
  243 +
262 /* 244 /*
263 * Structure stored in mbuf in inpcb.ip_options 245 * Structure stored in mbuf in inpcb.ip_options
264 * and passed to ip_output when ip options are in use. 246 * and passed to ip_output when ip options are in use.
slirp/ip_input.c
@@ -43,6 +43,7 @@ @@ -43,6 +43,7 @@
43 */ 43 */
44 44
45 #include <slirp.h> 45 #include <slirp.h>
  46 +#include <osdep.h>
46 #include "ip_icmp.h" 47 #include "ip_icmp.h"
47 48
48 #ifdef LOG_ENABLED 49 #ifdef LOG_ENABLED
@@ -51,7 +52,7 @@ struct ipstat ipstat; @@ -51,7 +52,7 @@ struct ipstat ipstat;
51 52
52 struct ipq ipq; 53 struct ipq ipq;
53 54
54 -static struct ip *ip_reass(register struct ipasfrag *ip, 55 +static struct ip *ip_reass(register struct ip *ip,
55 register struct ipq *fp); 56 register struct ipq *fp);
56 static void ip_freef(struct ipq *fp); 57 static void ip_freef(struct ipq *fp);
57 static void ip_enq(register struct ipasfrag *p, 58 static void ip_enq(register struct ipasfrag *p,
@@ -65,7 +66,7 @@ static void ip_deq(register struct ipasfrag *p); @@ -65,7 +66,7 @@ static void ip_deq(register struct ipasfrag *p);
65 void 66 void
66 ip_init() 67 ip_init()
67 { 68 {
68 - ipq.next = ipq.prev = (ipqp_32)&ipq; 69 + ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
69 ip_id = tt.tv_sec & 0xffff; 70 ip_id = tt.tv_sec & 0xffff;
70 udp_init(); 71 udp_init();
71 tcp_init(); 72 tcp_init();
@@ -188,18 +189,20 @@ ip_input(m) @@ -188,18 +189,20 @@ ip_input(m)
188 */ 189 */
189 if (ip->ip_off &~ IP_DF) { 190 if (ip->ip_off &~ IP_DF) {
190 register struct ipq *fp; 191 register struct ipq *fp;
  192 + struct qlink *l;
191 /* 193 /*
192 * Look for queue of fragments 194 * Look for queue of fragments
193 * of this datagram. 195 * of this datagram.
194 */ 196 */
195 - for (fp = (struct ipq *) ipq.next; fp != &ipq;  
196 - fp = (struct ipq *) fp->next)  
197 - if (ip->ip_id == fp->ipq_id &&  
198 - ip->ip_src.s_addr == fp->ipq_src.s_addr &&  
199 - ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&  
200 - ip->ip_p == fp->ipq_p) 197 + for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
  198 + fp = container_of(l, struct ipq, ip_link);
  199 + if (ip->ip_id == fp->ipq_id &&
  200 + ip->ip_src.s_addr == fp->ipq_src.s_addr &&
  201 + ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
  202 + ip->ip_p == fp->ipq_p)
201 goto found; 203 goto found;
202 - fp = 0; 204 + }
  205 + fp = NULL;
203 found: 206 found:
204 207
205 /* 208 /*
@@ -209,9 +212,9 @@ ip_input(m) @@ -209,9 +212,9 @@ ip_input(m)
209 */ 212 */
210 ip->ip_len -= hlen; 213 ip->ip_len -= hlen;
211 if (ip->ip_off & IP_MF) 214 if (ip->ip_off & IP_MF)
212 - ((struct ipasfrag *)ip)->ipf_mff |= 1; 215 + ip->ip_tos |= 1;
213 else 216 else
214 - ((struct ipasfrag *)ip)->ipf_mff &= ~1; 217 + ip->ip_tos &= ~1;
215 218
216 ip->ip_off <<= 3; 219 ip->ip_off <<= 3;
217 220
@@ -220,9 +223,9 @@ ip_input(m) @@ -220,9 +223,9 @@ ip_input(m)
220 * or if this is not the first fragment, 223 * or if this is not the first fragment,
221 * attempt reassembly; if it succeeds, proceed. 224 * attempt reassembly; if it succeeds, proceed.
222 */ 225 */
223 - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { 226 + if (ip->ip_tos & 1 || ip->ip_off) {
224 STAT(ipstat.ips_fragments++); 227 STAT(ipstat.ips_fragments++);
225 - ip = ip_reass((struct ipasfrag *)ip, fp); 228 + ip = ip_reass(ip, fp);
226 if (ip == 0) 229 if (ip == 0)
227 return; 230 return;
228 STAT(ipstat.ips_reassembled++); 231 STAT(ipstat.ips_reassembled++);
@@ -258,6 +261,8 @@ bad: @@ -258,6 +261,8 @@ bad:
258 return; 261 return;
259 } 262 }
260 263
  264 +#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
  265 +#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
261 /* 266 /*
262 * Take incoming datagram fragment and try to 267 * Take incoming datagram fragment and try to
263 * reassemble it into whole datagram. If a chain for 268 * reassemble it into whole datagram. If a chain for
@@ -265,7 +270,7 @@ bad: @@ -265,7 +270,7 @@ bad:
265 * is given as fp; otherwise have to make a chain. 270 * is given as fp; otherwise have to make a chain.
266 */ 271 */
267 static struct ip * 272 static struct ip *
268 -ip_reass(register struct ipasfrag *ip, register struct ipq *fp) 273 +ip_reass(register struct ip *ip, register struct ipq *fp)
269 { 274 {
270 register struct mbuf *m = dtom(ip); 275 register struct mbuf *m = dtom(ip);
271 register struct ipasfrag *q; 276 register struct ipasfrag *q;
@@ -292,13 +297,13 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp) @@ -292,13 +297,13 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
292 struct mbuf *t; 297 struct mbuf *t;
293 if ((t = m_get()) == NULL) goto dropfrag; 298 if ((t = m_get()) == NULL) goto dropfrag;
294 fp = mtod(t, struct ipq *); 299 fp = mtod(t, struct ipq *);
295 - insque_32(fp, &ipq); 300 + insque(&fp->ip_link, &ipq.ip_link);
296 fp->ipq_ttl = IPFRAGTTL; 301 fp->ipq_ttl = IPFRAGTTL;
297 fp->ipq_p = ip->ip_p; 302 fp->ipq_p = ip->ip_p;
298 fp->ipq_id = ip->ip_id; 303 fp->ipq_id = ip->ip_id;
299 - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;  
300 - fp->ipq_src = ((struct ip *)ip)->ip_src;  
301 - fp->ipq_dst = ((struct ip *)ip)->ip_dst; 304 + fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
  305 + fp->ipq_src = ip->ip_src;
  306 + fp->ipq_dst = ip->ip_dst;
302 q = (struct ipasfrag *)fp; 307 q = (struct ipasfrag *)fp;
303 goto insert; 308 goto insert;
304 } 309 }
@@ -306,9 +311,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp) @@ -306,9 +311,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
306 /* 311 /*
307 * Find a segment which begins after this one does. 312 * Find a segment which begins after this one does.
308 */ 313 */
309 - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;  
310 - q = (struct ipasfrag *)q->ipf_next)  
311 - if (q->ip_off > ip->ip_off) 314 + for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
  315 + q = q->ipf_next)
  316 + if (q->ipf_off > ip->ip_off)
312 break; 317 break;
313 318
314 /* 319 /*
@@ -316,9 +321,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp) @@ -316,9 +321,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
316 * our data already. If so, drop the data from the incoming 321 * our data already. If so, drop the data from the incoming
317 * segment. If it provides all of our data, drop us. 322 * segment. If it provides all of our data, drop us.
318 */ 323 */
319 - if (q->ipf_prev != (ipasfragp_32)fp) {  
320 - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +  
321 - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; 324 + if (q->ipf_prev != &fp->frag_link) {
  325 + struct ipasfrag *pq = q->ipf_prev;
  326 + i = pq->ipf_off + pq->ipf_len - ip->ip_off;
322 if (i > 0) { 327 if (i > 0) {
323 if (i >= ip->ip_len) 328 if (i >= ip->ip_len)
324 goto dropfrag; 329 goto dropfrag;
@@ -332,17 +337,18 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp) @@ -332,17 +337,18 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
332 * While we overlap succeeding segments trim them or, 337 * While we overlap succeeding segments trim them or,
333 * if they are completely covered, dequeue them. 338 * if they are completely covered, dequeue them.
334 */ 339 */
335 - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {  
336 - i = (ip->ip_off + ip->ip_len) - q->ip_off;  
337 - if (i < q->ip_len) {  
338 - q->ip_len -= i;  
339 - q->ip_off += i; 340 + while (q != (struct ipasfrag*)&fp->frag_link &&
  341 + ip->ip_off + ip->ip_len > q->ipf_off) {
  342 + i = (ip->ip_off + ip->ip_len) - q->ipf_off;
  343 + if (i < q->ipf_len) {
  344 + q->ipf_len -= i;
  345 + q->ipf_off += i;
340 m_adj(dtom(q), i); 346 m_adj(dtom(q), i);
341 break; 347 break;
342 } 348 }
343 - q = (struct ipasfrag *) q->ipf_next;  
344 - m_freem(dtom((struct ipasfrag *) q->ipf_prev));  
345 - ip_deq((struct ipasfrag *) q->ipf_prev); 349 + q = q->ipf_next;
  350 + m_freem(dtom(q->ipf_prev));
  351 + ip_deq(q->ipf_prev);
346 } 352 }
347 353
348 insert: 354 insert:
@@ -350,27 +356,26 @@ insert: @@ -350,27 +356,26 @@ insert:
350 * Stick new segment in its place; 356 * Stick new segment in its place;
351 * check for complete reassembly. 357 * check for complete reassembly.
352 */ 358 */
353 - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); 359 + ip_enq(iptofrag(ip), q->ipf_prev);
354 next = 0; 360 next = 0;
355 - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;  
356 - q = (struct ipasfrag *) q->ipf_next) {  
357 - if (q->ip_off != next) 361 + for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
  362 + q = q->ipf_next) {
  363 + if (q->ipf_off != next)
358 return (0); 364 return (0);
359 - next += q->ip_len; 365 + next += q->ipf_len;
360 } 366 }
361 - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) 367 + if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
362 return (0); 368 return (0);
363 369
364 /* 370 /*
365 * Reassembly is complete; concatenate fragments. 371 * Reassembly is complete; concatenate fragments.
366 */ 372 */
367 - q = (struct ipasfrag *) fp->ipq_next; 373 + q = fp->frag_link.next;
368 m = dtom(q); 374 m = dtom(q);
369 375
370 q = (struct ipasfrag *) q->ipf_next; 376 q = (struct ipasfrag *) q->ipf_next;
371 - while (q != (struct ipasfrag *)fp) {  
372 - struct mbuf *t;  
373 - t = dtom(q); 377 + while (q != (struct ipasfrag*)&fp->frag_link) {
  378 + struct mbuf *t = dtom(q);
374 q = (struct ipasfrag *) q->ipf_next; 379 q = (struct ipasfrag *) q->ipf_next;
375 m_cat(m, t); 380 m_cat(m, t);
376 } 381 }
@@ -381,7 +386,7 @@ insert: @@ -381,7 +386,7 @@ insert:
381 * dequeue and discard fragment reassembly header. 386 * dequeue and discard fragment reassembly header.
382 * Make header visible. 387 * Make header visible.
383 */ 388 */
384 - ip = (struct ipasfrag *) fp->ipq_next; 389 + q = fp->frag_link.next;
385 390
386 /* 391 /*
387 * If the fragments concatenated to an mbuf that's 392 * If the fragments concatenated to an mbuf that's
@@ -393,23 +398,23 @@ insert: @@ -393,23 +398,23 @@ insert:
393 if (m->m_flags & M_EXT) { 398 if (m->m_flags & M_EXT) {
394 int delta; 399 int delta;
395 delta = (char *)ip - m->m_dat; 400 delta = (char *)ip - m->m_dat;
396 - ip = (struct ipasfrag *)(m->m_ext + delta); 401 + q = (struct ipasfrag *)(m->m_ext + delta);
397 } 402 }
398 403
399 /* DEBUG_ARG("ip = %lx", (long)ip); 404 /* DEBUG_ARG("ip = %lx", (long)ip);
400 * ip=(struct ipasfrag *)m->m_data; */ 405 * ip=(struct ipasfrag *)m->m_data; */
401 406
  407 + ip = fragtoip(q);
402 ip->ip_len = next; 408 ip->ip_len = next;
403 - ip->ipf_mff &= ~1;  
404 - ((struct ip *)ip)->ip_src = fp->ipq_src;  
405 - ((struct ip *)ip)->ip_dst = fp->ipq_dst;  
406 - remque_32(fp); 409 + ip->ip_tos &= ~1;
  410 + ip->ip_src = fp->ipq_src;
  411 + ip->ip_dst = fp->ipq_dst;
  412 + remque(&fp->ip_link);
407 (void) m_free(dtom(fp)); 413 (void) m_free(dtom(fp));
408 - m = dtom(ip);  
409 m->m_len += (ip->ip_hl << 2); 414 m->m_len += (ip->ip_hl << 2);
410 m->m_data -= (ip->ip_hl << 2); 415 m->m_data -= (ip->ip_hl << 2);
411 416
412 - return ((struct ip *)ip); 417 + return ip;
413 418
414 dropfrag: 419 dropfrag:
415 STAT(ipstat.ips_fragdropped++); 420 STAT(ipstat.ips_fragdropped++);
@@ -426,13 +431,12 @@ ip_freef(struct ipq *fp) @@ -426,13 +431,12 @@ ip_freef(struct ipq *fp)
426 { 431 {
427 register struct ipasfrag *q, *p; 432 register struct ipasfrag *q, *p;
428 433
429 - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;  
430 - q = p) {  
431 - p = (struct ipasfrag *) q->ipf_next; 434 + for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
  435 + p = q->ipf_next;
432 ip_deq(q); 436 ip_deq(q);
433 m_freem(dtom(q)); 437 m_freem(dtom(q));
434 } 438 }
435 - remque_32(fp); 439 + remque(&fp->ip_link);
436 (void) m_free(dtom(fp)); 440 (void) m_free(dtom(fp));
437 } 441 }
438 442
@@ -445,10 +449,10 @@ ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev) @@ -445,10 +449,10 @@ ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
445 { 449 {
446 DEBUG_CALL("ip_enq"); 450 DEBUG_CALL("ip_enq");
447 DEBUG_ARG("prev = %lx", (long)prev); 451 DEBUG_ARG("prev = %lx", (long)prev);
448 - p->ipf_prev = (ipasfragp_32) prev; 452 + p->ipf_prev = prev;
449 p->ipf_next = prev->ipf_next; 453 p->ipf_next = prev->ipf_next;
450 - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;  
451 - prev->ipf_next = (ipasfragp_32) p; 454 + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
  455 + prev->ipf_next = p;
452 } 456 }
453 457
454 /* 458 /*
@@ -469,20 +473,21 @@ ip_deq(register struct ipasfrag *p) @@ -469,20 +473,21 @@ ip_deq(register struct ipasfrag *p)
469 void 473 void
470 ip_slowtimo() 474 ip_slowtimo()
471 { 475 {
472 - register struct ipq *fp; 476 + struct qlink *l;
473 477
474 DEBUG_CALL("ip_slowtimo"); 478 DEBUG_CALL("ip_slowtimo");
475 479
476 - fp = (struct ipq *) ipq.next;  
477 - if (fp == 0) 480 + l = ipq.ip_link.next;
  481 +
  482 + if (l == 0)
478 return; 483 return;
479 484
480 - while (fp != &ipq) {  
481 - --fp->ipq_ttl;  
482 - fp = (struct ipq *) fp->next;  
483 - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { 485 + while (l != &ipq.ip_link) {
  486 + struct ipq *fp = container_of(l, struct ipq, ip_link);
  487 + l = l->next;
  488 + if (--fp->ipq_ttl == 0) {
484 STAT(ipstat.ips_fragtimeout++); 489 STAT(ipstat.ips_fragtimeout++);
485 - ip_freef((struct ipq *) fp->prev); 490 + ip_freef(fp);
486 } 491 }
487 } 492 }
488 } 493 }
slirp/misc.c
@@ -83,39 +83,6 @@ getouraddr() @@ -83,39 +83,6 @@ getouraddr()
83 our_addr.s_addr = loopback_addr.s_addr; 83 our_addr.s_addr = loopback_addr.s_addr;
84 } 84 }
85 85
86 -#if SIZEOF_CHAR_P == 8  
87 -  
88 -struct quehead_32 {  
89 - u_int32_t qh_link;  
90 - u_int32_t qh_rlink;  
91 -};  
92 -  
93 -inline void  
94 -insque_32(a, b)  
95 - void *a;  
96 - void *b;  
97 -{  
98 - register struct quehead_32 *element = (struct quehead_32 *) a;  
99 - register struct quehead_32 *head = (struct quehead_32 *) b;  
100 - element->qh_link = head->qh_link;  
101 - head->qh_link = (u_int32_t)element;  
102 - element->qh_rlink = (u_int32_t)head;  
103 - ((struct quehead_32 *)(element->qh_link))->qh_rlink  
104 - = (u_int32_t)element;  
105 -}  
106 -  
107 -inline void  
108 -remque_32(a)  
109 - void *a;  
110 -{  
111 - register struct quehead_32 *element = (struct quehead_32 *) a;  
112 - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;  
113 - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;  
114 - element->qh_rlink = 0;  
115 -}  
116 -  
117 -#endif /* SIZEOF_CHAR_P == 8 */  
118 -  
119 struct quehead { 86 struct quehead {
120 struct quehead *qh_link; 87 struct quehead *qh_link;
121 struct quehead *qh_rlink; 88 struct quehead *qh_rlink;
slirp/slirp.c
@@ -262,7 +262,7 @@ void slirp_select_fill(int *pnfds, @@ -262,7 +262,7 @@ void slirp_select_fill(int *pnfds,
262 * in the fragment queue, or there are TCP connections active 262 * in the fragment queue, or there are TCP connections active
263 */ 263 */
264 do_slowtimo = ((tcb.so_next != &tcb) || 264 do_slowtimo = ((tcb.so_next != &tcb) ||
265 - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); 265 + (&ipq.ip_link != ipq.ip_link.next));
266 266
267 for (so = tcb.so_next; so != &tcb; so = so_next) { 267 for (so = tcb.so_next; so != &tcb; so = so_next) {
268 so_next = so->so_next; 268 so_next = so->so_next;
slirp/slirp.h
@@ -266,14 +266,6 @@ void if_start _P((struct ttys *)); @@ -266,14 +266,6 @@ void if_start _P((struct ttys *));
266 266
267 void lprint _P((const char *, ...)); 267 void lprint _P((const char *, ...));
268 268
269 -#if SIZEOF_CHAR_P == 4  
270 -# define insque_32 insque  
271 -# define remque_32 remque  
272 -#else  
273 - void insque_32 _P((void *, void *));  
274 - void remque_32 _P((void *));  
275 -#endif  
276 -  
277 #ifndef _WIN32 269 #ifndef _WIN32
278 #include <netdb.h> 270 #include <netdb.h>
279 #endif 271 #endif
slirp/tcp_input.c
@@ -71,7 +71,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ @@ -71,7 +71,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
71 #ifdef TCP_ACK_HACK 71 #ifdef TCP_ACK_HACK
72 #define TCP_REASS(tp, ti, m, so, flags) {\ 72 #define TCP_REASS(tp, ti, m, so, flags) {\
73 if ((ti)->ti_seq == (tp)->rcv_nxt && \ 73 if ((ti)->ti_seq == (tp)->rcv_nxt && \
74 - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ 74 + tcpfrag_list_empty(tp) && \
75 (tp)->t_state == TCPS_ESTABLISHED) {\ 75 (tp)->t_state == TCPS_ESTABLISHED) {\
76 if (ti->ti_flags & TH_PUSH) \ 76 if (ti->ti_flags & TH_PUSH) \
77 tp->t_flags |= TF_ACKNOW; \ 77 tp->t_flags |= TF_ACKNOW; \
@@ -94,7 +94,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ @@ -94,7 +94,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
94 #else 94 #else
95 #define TCP_REASS(tp, ti, m, so, flags) { \ 95 #define TCP_REASS(tp, ti, m, so, flags) { \
96 if ((ti)->ti_seq == (tp)->rcv_nxt && \ 96 if ((ti)->ti_seq == (tp)->rcv_nxt && \
97 - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ 97 + tcpfrag_list_empty(tp) && \
98 (tp)->t_state == TCPS_ESTABLISHED) { \ 98 (tp)->t_state == TCPS_ESTABLISHED) { \
99 tp->t_flags |= TF_DELACK; \ 99 tp->t_flags |= TF_DELACK; \
100 (tp)->rcv_nxt += (ti)->ti_len; \ 100 (tp)->rcv_nxt += (ti)->ti_len; \
@@ -134,8 +134,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, @@ -134,8 +134,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
134 /* 134 /*
135 * Find a segment which begins after this one does. 135 * Find a segment which begins after this one does.
136 */ 136 */
137 - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;  
138 - q = (struct tcpiphdr *)q->ti_next) 137 + for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
  138 + q = tcpiphdr_next(q))
139 if (SEQ_GT(q->ti_seq, ti->ti_seq)) 139 if (SEQ_GT(q->ti_seq, ti->ti_seq))
140 break; 140 break;
141 141
@@ -144,9 +144,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, @@ -144,9 +144,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
144 * our data already. If so, drop the data from the incoming 144 * our data already. If so, drop the data from the incoming
145 * segment. If it provides all of our data, drop us. 145 * segment. If it provides all of our data, drop us.
146 */ 146 */
147 - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { 147 + if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
148 register int i; 148 register int i;
149 - q = (struct tcpiphdr *)q->ti_prev; 149 + q = tcpiphdr_prev(q);
150 /* conversion to int (in i) handles seq wraparound */ 150 /* conversion to int (in i) handles seq wraparound */
151 i = q->ti_seq + q->ti_len - ti->ti_seq; 151 i = q->ti_seq + q->ti_len - ti->ti_seq;
152 if (i > 0) { 152 if (i > 0) {
@@ -166,36 +166,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, @@ -166,36 +166,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
166 ti->ti_len -= i; 166 ti->ti_len -= i;
167 ti->ti_seq += i; 167 ti->ti_seq += i;
168 } 168 }
169 - q = (struct tcpiphdr *)(q->ti_next); 169 + q = tcpiphdr_next(q);
170 } 170 }
171 STAT(tcpstat.tcps_rcvoopack++); 171 STAT(tcpstat.tcps_rcvoopack++);
172 STAT(tcpstat.tcps_rcvoobyte += ti->ti_len); 172 STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
173 - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ 173 + ti->ti_mbuf = m;
174 174
175 /* 175 /*
176 * While we overlap succeeding segments trim them or, 176 * While we overlap succeeding segments trim them or,
177 * if they are completely covered, dequeue them. 177 * if they are completely covered, dequeue them.
178 */ 178 */
179 - while (q != (struct tcpiphdr *)tp) { 179 + while (!tcpfrag_list_end(q, tp)) {
180 register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 180 register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
181 if (i <= 0) 181 if (i <= 0)
182 break; 182 break;
183 if (i < q->ti_len) { 183 if (i < q->ti_len) {
184 q->ti_seq += i; 184 q->ti_seq += i;
185 q->ti_len -= i; 185 q->ti_len -= i;
186 - m_adj((struct mbuf *) REASS_MBUF(q), i); 186 + m_adj(q->ti_mbuf, i);
187 break; 187 break;
188 } 188 }
189 - q = (struct tcpiphdr *)q->ti_next;  
190 - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev);  
191 - remque_32((void *)(q->ti_prev)); 189 + q = tcpiphdr_next(q);
  190 + m = tcpiphdr_prev(q)->ti_mbuf;
  191 + remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
192 m_freem(m); 192 m_freem(m);
193 } 193 }
194 194
195 /* 195 /*
196 * Stick new segment in its place. 196 * Stick new segment in its place.
197 */ 197 */
198 - insque_32(ti, (void *)(q->ti_prev)); 198 + insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));
199 199
200 present: 200 present:
201 /* 201 /*
@@ -204,17 +204,17 @@ present: @@ -204,17 +204,17 @@ present:
204 */ 204 */
205 if (!TCPS_HAVEESTABLISHED(tp->t_state)) 205 if (!TCPS_HAVEESTABLISHED(tp->t_state))
206 return (0); 206 return (0);
207 - ti = (struct tcpiphdr *) tp->seg_next;  
208 - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) 207 + ti = tcpfrag_list_first(tp);
  208 + if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
209 return (0); 209 return (0);
210 if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) 210 if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
211 return (0); 211 return (0);
212 do { 212 do {
213 tp->rcv_nxt += ti->ti_len; 213 tp->rcv_nxt += ti->ti_len;
214 flags = ti->ti_flags & TH_FIN; 214 flags = ti->ti_flags & TH_FIN;
215 - remque_32(ti);  
216 - m = (struct mbuf *) REASS_MBUF(ti); /* XXX */  
217 - ti = (struct tcpiphdr *)ti->ti_next; 215 + remque(tcpiphdr2qlink(ti));
  216 + m = ti->ti_mbuf;
  217 + ti = tcpiphdr_next(ti);
218 /* if (so->so_state & SS_FCANTRCVMORE) */ 218 /* if (so->so_state & SS_FCANTRCVMORE) */
219 if (so->so_state & SS_FCANTSENDMORE) 219 if (so->so_state & SS_FCANTSENDMORE)
220 m_freem(m); 220 m_freem(m);
@@ -302,7 +302,8 @@ tcp_input(m, iphlen, inso) @@ -302,7 +302,8 @@ tcp_input(m, iphlen, inso)
302 * Checksum extended TCP header and data. 302 * Checksum extended TCP header and data.
303 */ 303 */
304 tlen = ((struct ip *)ti)->ip_len; 304 tlen = ((struct ip *)ti)->ip_len;
305 - ti->ti_next = ti->ti_prev = 0; 305 + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0;
  306 + memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
306 ti->ti_x1 = 0; 307 ti->ti_x1 = 0;
307 ti->ti_len = htons((u_int16_t)tlen); 308 ti->ti_len = htons((u_int16_t)tlen);
308 len = sizeof(struct ip ) + tlen; 309 len = sizeof(struct ip ) + tlen;
@@ -560,7 +561,7 @@ findso: @@ -560,7 +561,7 @@ findso:
560 return; 561 return;
561 } 562 }
562 } else if (ti->ti_ack == tp->snd_una && 563 } else if (ti->ti_ack == tp->snd_una &&
563 - tp->seg_next == (tcpiphdrp_32)tp && 564 + tcpfrag_list_empty(tp) &&
564 ti->ti_len <= sbspace(&so->so_rcv)) { 565 ti->ti_len <= sbspace(&so->so_rcv)) {
565 /* 566 /*
566 * this is a pure, in-sequence data packet 567 * this is a pure, in-sequence data packet
slirp/tcp_subr.c
@@ -73,7 +73,7 @@ tcp_template(tp) @@ -73,7 +73,7 @@ tcp_template(tp)
73 struct socket *so = tp->t_socket; 73 struct socket *so = tp->t_socket;
74 register struct tcpiphdr *n = &tp->t_template; 74 register struct tcpiphdr *n = &tp->t_template;
75 75
76 - n->ti_next = n->ti_prev = 0; 76 + n->ti_mbuf = NULL;
77 n->ti_x1 = 0; 77 n->ti_x1 = 0;
78 n->ti_pr = IPPROTO_TCP; 78 n->ti_pr = IPPROTO_TCP;
79 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 79 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
@@ -156,7 +156,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) @@ -156,7 +156,7 @@ tcp_respond(tp, ti, m, ack, seq, flags)
156 tlen += sizeof (struct tcpiphdr); 156 tlen += sizeof (struct tcpiphdr);
157 m->m_len = tlen; 157 m->m_len = tlen;
158 158
159 - ti->ti_next = ti->ti_prev = 0; 159 + ti->ti_mbuf = 0;
160 ti->ti_x1 = 0; 160 ti->ti_x1 = 0;
161 ti->ti_seq = htonl(seq); 161 ti->ti_seq = htonl(seq);
162 ti->ti_ack = htonl(ack); 162 ti->ti_ack = htonl(ack);
@@ -196,7 +196,7 @@ tcp_newtcpcb(so) @@ -196,7 +196,7 @@ tcp_newtcpcb(so)
196 return ((struct tcpcb *)0); 196 return ((struct tcpcb *)0);
197 197
198 memset((char *) tp, 0, sizeof(struct tcpcb)); 198 memset((char *) tp, 0, sizeof(struct tcpcb));
199 - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; 199 + tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
200 tp->t_maxseg = TCP_MSS; 200 tp->t_maxseg = TCP_MSS;
201 201
202 tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 202 tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
@@ -272,11 +272,11 @@ tcp_close(tp) @@ -272,11 +272,11 @@ tcp_close(tp)
272 DEBUG_ARG("tp = %lx", (long )tp); 272 DEBUG_ARG("tp = %lx", (long )tp);
273 273
274 /* free the reassembly queue, if any */ 274 /* free the reassembly queue, if any */
275 - t = (struct tcpiphdr *) tp->seg_next;  
276 - while (t != (struct tcpiphdr *)tp) {  
277 - t = (struct tcpiphdr *)t->ti_next;  
278 - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);  
279 - remque_32((struct tcpiphdr *) t->ti_prev); 275 + t = tcpfrag_list_first(tp);
  276 + while (!tcpfrag_list_end(t, tp)) {
  277 + t = tcpiphdr_next(t);
  278 + m = tcpiphdr_prev(t)->ti_mbuf;
  279 + remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
280 m_freem(m); 280 m_freem(m);
281 } 281 }
282 /* It's static */ 282 /* It's static */
slirp/tcp_var.h
@@ -40,18 +40,12 @@ @@ -40,18 +40,12 @@
40 #include "tcpip.h" 40 #include "tcpip.h"
41 #include "tcp_timer.h" 41 #include "tcp_timer.h"
42 42
43 -#if SIZEOF_CHAR_P == 4  
44 - typedef struct tcpiphdr *tcpiphdrp_32;  
45 -#else  
46 - typedef u_int32_t tcpiphdrp_32;  
47 -#endif  
48 -  
49 /* 43 /*
50 * Tcp control block, one per tcp; fields: 44 * Tcp control block, one per tcp; fields:
51 */ 45 */
52 struct tcpcb { 46 struct tcpcb {
53 - tcpiphdrp_32 seg_next; /* sequencing queue */  
54 - tcpiphdrp_32 seg_prev; 47 + struct tcpiphdr *seg_next; /* sequencing queue */
  48 + struct tcpiphdr *seg_prev;
55 short t_state; /* state of this connection */ 49 short t_state; /* state of this connection */
56 short t_timer[TCPT_NTIMERS]; /* tcp timers */ 50 short t_timer[TCPT_NTIMERS]; /* tcp timers */
57 short t_rxtshift; /* log(2) of rexmt exp. backoff */ 51 short t_rxtshift; /* log(2) of rexmt exp. backoff */
@@ -170,21 +164,6 @@ struct tcpcb { @@ -170,21 +164,6 @@ struct tcpcb {
170 #define TCP_REXMTVAL(tp) \ 164 #define TCP_REXMTVAL(tp) \
171 (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) 165 (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
172 166
173 -/* XXX  
174 - * We want to avoid doing m_pullup on incoming packets but that  
175 - * means avoiding dtom on the tcp reassembly code. That in turn means  
176 - * keeping an mbuf pointer in the reassembly queue (since we might  
177 - * have a cluster). As a quick hack, the source & destination  
178 - * port numbers (which are no longer needed once we've located the  
179 - * tcpcb) are overlayed with an mbuf pointer.  
180 - */  
181 -#if SIZEOF_CHAR_P == 4  
182 -typedef struct mbuf *mbufp_32;  
183 -#else  
184 -typedef u_int32_t mbufp_32;  
185 -#endif  
186 -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))  
187 -  
188 #ifdef LOG_ENABLED 167 #ifdef LOG_ENABLED
189 /* 168 /*
190 * TCP statistics. 169 * TCP statistics.
slirp/tcpip.h
@@ -44,8 +44,7 @@ struct tcpiphdr { @@ -44,8 +44,7 @@ struct tcpiphdr {
44 struct ipovly ti_i; /* overlaid ip structure */ 44 struct ipovly ti_i; /* overlaid ip structure */
45 struct tcphdr ti_t; /* tcp header */ 45 struct tcphdr ti_t; /* tcp header */
46 }; 46 };
47 -#define ti_next ti_i.ih_next  
48 -#define ti_prev ti_i.ih_prev 47 +#define ti_mbuf ti_i.ih_mbuf.mptr
49 #define ti_x1 ti_i.ih_x1 48 #define ti_x1 ti_i.ih_x1
50 #define ti_pr ti_i.ih_pr 49 #define ti_pr ti_i.ih_pr
51 #define ti_len ti_i.ih_len 50 #define ti_len ti_i.ih_len
@@ -62,6 +61,14 @@ struct tcpiphdr { @@ -62,6 +61,14 @@ struct tcpiphdr {
62 #define ti_sum ti_t.th_sum 61 #define ti_sum ti_t.th_sum
63 #define ti_urp ti_t.th_urp 62 #define ti_urp ti_t.th_urp
64 63
  64 +#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink)))
  65 +#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink)))
  66 +#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next)
  67 +#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev)
  68 +#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next)
  69 +#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T))
  70 +#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T))
  71 +
65 /* 72 /*
66 * Just a clean way to get to the first byte 73 * Just a clean way to get to the first byte
67 * of the packet 74 * of the packet
slirp/udp.c
@@ -136,8 +136,7 @@ udp_input(m, iphlen) @@ -136,8 +136,7 @@ udp_input(m, iphlen)
136 * Checksum extended UDP header and data. 136 * Checksum extended UDP header and data.
137 */ 137 */
138 if (UDPCKSUM && uh->uh_sum) { 138 if (UDPCKSUM && uh->uh_sum) {
139 - ((struct ipovly *)ip)->ih_next = 0;  
140 - ((struct ipovly *)ip)->ih_prev = 0; 139 + memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr));
141 ((struct ipovly *)ip)->ih_x1 = 0; 140 ((struct ipovly *)ip)->ih_x1 = 0;
142 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 141 ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
143 /* keep uh_sum for ICMP reply 142 /* keep uh_sum for ICMP reply
@@ -283,7 +282,7 @@ int udp_output2(struct socket *so, struct mbuf *m, @@ -283,7 +282,7 @@ int udp_output2(struct socket *so, struct mbuf *m,
283 * and addresses and length put into network format. 282 * and addresses and length put into network format.
284 */ 283 */
285 ui = mtod(m, struct udpiphdr *); 284 ui = mtod(m, struct udpiphdr *);
286 - ui->ui_next = ui->ui_prev = 0; 285 + memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
287 ui->ui_x1 = 0; 286 ui->ui_x1 = 0;
288 ui->ui_pr = IPPROTO_UDP; 287 ui->ui_pr = IPPROTO_UDP;
289 ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ 288 ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
slirp/udp.h
@@ -60,8 +60,7 @@ struct udpiphdr { @@ -60,8 +60,7 @@ struct udpiphdr {
60 struct ipovly ui_i; /* overlaid ip structure */ 60 struct ipovly ui_i; /* overlaid ip structure */
61 struct udphdr ui_u; /* udp header */ 61 struct udphdr ui_u; /* udp header */
62 }; 62 };
63 -#define ui_next ui_i.ih_next  
64 -#define ui_prev ui_i.ih_prev 63 +#define ui_mbuf ui_i.ih_mbuf.mptr
65 #define ui_x1 ui_i.ih_x1 64 #define ui_x1 ui_i.ih_x1
66 #define ui_pr ui_i.ih_pr 65 #define ui_pr ui_i.ih_pr
67 #define ui_len ui_i.ih_len 66 #define ui_len ui_i.ih_len