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 183  
184 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 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 191 #else
200   -typedef caddr32_t ipqp_32;
201   -typedef caddr32_t ipasfragp_32;
  192 +struct mbuf_ptr {
  193 + struct mbuf *mptr;
  194 +};
202 195 #endif
  196 +struct qlink {
  197 + void *next, *prev;
  198 +};
203 199  
204 200 /*
205 201 * Overlay for ip header used by other protocols (tcp, udp).
206 202 */
207 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 205 u_int8_t ih_x1; /* (unused) */
210 206 u_int8_t ih_pr; /* protocol */
211 207 u_int16_t ih_len; /* protocol length */
212 208 struct in_addr ih_src; /* source internet address */
213 209 struct in_addr ih_dst; /* destination internet address */
214   -};
  210 +} __attribute__((packed));
215 211  
216 212 /*
217 213 * Ip reassembly queue structure. Each fragment
... ... @@ -221,44 +217,30 @@ struct ipovly {
221 217 * size 28 bytes
222 218 */
223 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 222 u_int8_t ipq_ttl; /* time for reass q to live */
226 223 u_int8_t ipq_p; /* protocol of this fragment */
227 224 u_int16_t ipq_id; /* sequence id for reassembly */
228   - ipasfragp_32 ipq_next,ipq_prev;
229   - /* to ip headers of fragments */
230 225 struct in_addr ipq_src,ipq_dst;
231 226 };
232 227  
233 228 /*
234 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 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 245 * Structure stored in mbuf in inpcb.ip_options
264 246 * and passed to ip_output when ip options are in use.
... ...
slirp/ip_input.c
... ... @@ -43,6 +43,7 @@
43 43 */
44 44  
45 45 #include <slirp.h>
  46 +#include <osdep.h>
46 47 #include "ip_icmp.h"
47 48  
48 49 #ifdef LOG_ENABLED
... ... @@ -51,7 +52,7 @@ struct ipstat ipstat;
51 52  
52 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 56 register struct ipq *fp);
56 57 static void ip_freef(struct ipq *fp);
57 58 static void ip_enq(register struct ipasfrag *p,
... ... @@ -65,7 +66,7 @@ static void ip_deq(register struct ipasfrag *p);
65 66 void
66 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 70 ip_id = tt.tv_sec & 0xffff;
70 71 udp_init();
71 72 tcp_init();
... ... @@ -188,18 +189,20 @@ ip_input(m)
188 189 */
189 190 if (ip->ip_off &~ IP_DF) {
190 191 register struct ipq *fp;
  192 + struct qlink *l;
191 193 /*
192 194 * Look for queue of fragments
193 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 203 goto found;
202   - fp = 0;
  204 + }
  205 + fp = NULL;
203 206 found:
204 207  
205 208 /*
... ... @@ -209,9 +212,9 @@ ip_input(m)
209 212 */
210 213 ip->ip_len -= hlen;
211 214 if (ip->ip_off & IP_MF)
212   - ((struct ipasfrag *)ip)->ipf_mff |= 1;
  215 + ip->ip_tos |= 1;
213 216 else
214   - ((struct ipasfrag *)ip)->ipf_mff &= ~1;
  217 + ip->ip_tos &= ~1;
215 218  
216 219 ip->ip_off <<= 3;
217 220  
... ... @@ -220,9 +223,9 @@ ip_input(m)
220 223 * or if this is not the first fragment,
221 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 227 STAT(ipstat.ips_fragments++);
225   - ip = ip_reass((struct ipasfrag *)ip, fp);
  228 + ip = ip_reass(ip, fp);
226 229 if (ip == 0)
227 230 return;
228 231 STAT(ipstat.ips_reassembled++);
... ... @@ -258,6 +261,8 @@ bad:
258 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 267 * Take incoming datagram fragment and try to
263 268 * reassemble it into whole datagram. If a chain for
... ... @@ -265,7 +270,7 @@ bad:
265 270 * is given as fp; otherwise have to make a chain.
266 271 */
267 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 275 register struct mbuf *m = dtom(ip);
271 276 register struct ipasfrag *q;
... ... @@ -292,13 +297,13 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
292 297 struct mbuf *t;
293 298 if ((t = m_get()) == NULL) goto dropfrag;
294 299 fp = mtod(t, struct ipq *);
295   - insque_32(fp, &ipq);
  300 + insque(&fp->ip_link, &ipq.ip_link);
296 301 fp->ipq_ttl = IPFRAGTTL;
297 302 fp->ipq_p = ip->ip_p;
298 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 307 q = (struct ipasfrag *)fp;
303 308 goto insert;
304 309 }
... ... @@ -306,9 +311,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
306 311 /*
307 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 317 break;
313 318  
314 319 /*
... ... @@ -316,9 +321,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
316 321 * our data already. If so, drop the data from the incoming
317 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 327 if (i > 0) {
323 328 if (i >= ip->ip_len)
324 329 goto dropfrag;
... ... @@ -332,17 +337,18 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
332 337 * While we overlap succeeding segments trim them or,
333 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 346 m_adj(dtom(q), i);
341 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 354 insert:
... ... @@ -350,27 +356,26 @@ insert:
350 356 * Stick new segment in its place;
351 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 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 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 368 return (0);
363 369  
364 370 /*
365 371 * Reassembly is complete; concatenate fragments.
366 372 */
367   - q = (struct ipasfrag *) fp->ipq_next;
  373 + q = fp->frag_link.next;
368 374 m = dtom(q);
369 375  
370 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 379 q = (struct ipasfrag *) q->ipf_next;
375 380 m_cat(m, t);
376 381 }
... ... @@ -381,7 +386,7 @@ insert:
381 386 * dequeue and discard fragment reassembly header.
382 387 * Make header visible.
383 388 */
384   - ip = (struct ipasfrag *) fp->ipq_next;
  389 + q = fp->frag_link.next;
385 390  
386 391 /*
387 392 * If the fragments concatenated to an mbuf that's
... ... @@ -393,23 +398,23 @@ insert:
393 398 if (m->m_flags & M_EXT) {
394 399 int delta;
395 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 404 /* DEBUG_ARG("ip = %lx", (long)ip);
400 405 * ip=(struct ipasfrag *)m->m_data; */
401 406  
  407 + ip = fragtoip(q);
402 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 413 (void) m_free(dtom(fp));
408   - m = dtom(ip);
409 414 m->m_len += (ip->ip_hl << 2);
410 415 m->m_data -= (ip->ip_hl << 2);
411 416  
412   - return ((struct ip *)ip);
  417 + return ip;
413 418  
414 419 dropfrag:
415 420 STAT(ipstat.ips_fragdropped++);
... ... @@ -426,13 +431,12 @@ ip_freef(struct ipq *fp)
426 431 {
427 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 436 ip_deq(q);
433 437 m_freem(dtom(q));
434 438 }
435   - remque_32(fp);
  439 + remque(&fp->ip_link);
436 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 449 {
446 450 DEBUG_CALL("ip_enq");
447 451 DEBUG_ARG("prev = %lx", (long)prev);
448   - p->ipf_prev = (ipasfragp_32) prev;
  452 + p->ipf_prev = prev;
449 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 473 void
470 474 ip_slowtimo()
471 475 {
472   - register struct ipq *fp;
  476 + struct qlink *l;
473 477  
474 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 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 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 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 86 struct quehead {
120 87 struct quehead *qh_link;
121 88 struct quehead *qh_rlink;
... ...
slirp/slirp.c
... ... @@ -262,7 +262,7 @@ void slirp_select_fill(int *pnfds,
262 262 * in the fragment queue, or there are TCP connections active
263 263 */
264 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 267 for (so = tcb.so_next; so != &tcb; so = so_next) {
268 268 so_next = so->so_next;
... ...
slirp/slirp.h
... ... @@ -266,14 +266,6 @@ void if_start _P((struct ttys *));
266 266  
267 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 269 #ifndef _WIN32
278 270 #include <netdb.h>
279 271 #endif
... ...
slirp/tcp_input.c
... ... @@ -71,7 +71,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
71 71 #ifdef TCP_ACK_HACK
72 72 #define TCP_REASS(tp, ti, m, so, flags) {\
73 73 if ((ti)->ti_seq == (tp)->rcv_nxt && \
74   - (tp)->seg_next == (tcpiphdrp_32)(tp) && \
  74 + tcpfrag_list_empty(tp) && \
75 75 (tp)->t_state == TCPS_ESTABLISHED) {\
76 76 if (ti->ti_flags & TH_PUSH) \
77 77 tp->t_flags |= TF_ACKNOW; \
... ... @@ -94,7 +94,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
94 94 #else
95 95 #define TCP_REASS(tp, ti, m, so, flags) { \
96 96 if ((ti)->ti_seq == (tp)->rcv_nxt && \
97   - (tp)->seg_next == (tcpiphdrp_32)(tp) && \
  97 + tcpfrag_list_empty(tp) && \
98 98 (tp)->t_state == TCPS_ESTABLISHED) { \
99 99 tp->t_flags |= TF_DELACK; \
100 100 (tp)->rcv_nxt += (ti)->ti_len; \
... ... @@ -134,8 +134,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
134 134 /*
135 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 139 if (SEQ_GT(q->ti_seq, ti->ti_seq))
140 140 break;
141 141  
... ... @@ -144,9 +144,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
144 144 * our data already. If so, drop the data from the incoming
145 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 148 register int i;
149   - q = (struct tcpiphdr *)q->ti_prev;
  149 + q = tcpiphdr_prev(q);
150 150 /* conversion to int (in i) handles seq wraparound */
151 151 i = q->ti_seq + q->ti_len - ti->ti_seq;
152 152 if (i > 0) {
... ... @@ -166,36 +166,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
166 166 ti->ti_len -= i;
167 167 ti->ti_seq += i;
168 168 }
169   - q = (struct tcpiphdr *)(q->ti_next);
  169 + q = tcpiphdr_next(q);
170 170 }
171 171 STAT(tcpstat.tcps_rcvoopack++);
172 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 176 * While we overlap succeeding segments trim them or,
177 177 * if they are completely covered, dequeue them.
178 178 */
179   - while (q != (struct tcpiphdr *)tp) {
  179 + while (!tcpfrag_list_end(q, tp)) {
180 180 register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
181 181 if (i <= 0)
182 182 break;
183 183 if (i < q->ti_len) {
184 184 q->ti_seq += i;
185 185 q->ti_len -= i;
186   - m_adj((struct mbuf *) REASS_MBUF(q), i);
  186 + m_adj(q->ti_mbuf, i);
187 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 192 m_freem(m);
193 193 }
194 194  
195 195 /*
196 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 200 present:
201 201 /*
... ... @@ -204,17 +204,17 @@ present:
204 204 */
205 205 if (!TCPS_HAVEESTABLISHED(tp->t_state))
206 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 209 return (0);
210 210 if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
211 211 return (0);
212 212 do {
213 213 tp->rcv_nxt += ti->ti_len;
214 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 218 /* if (so->so_state & SS_FCANTRCVMORE) */
219 219 if (so->so_state & SS_FCANTSENDMORE)
220 220 m_freem(m);
... ... @@ -302,7 +302,8 @@ tcp_input(m, iphlen, inso)
302 302 * Checksum extended TCP header and data.
303 303 */
304 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 307 ti->ti_x1 = 0;
307 308 ti->ti_len = htons((u_int16_t)tlen);
308 309 len = sizeof(struct ip ) + tlen;
... ... @@ -560,7 +561,7 @@ findso:
560 561 return;
561 562 }
562 563 } else if (ti->ti_ack == tp->snd_una &&
563   - tp->seg_next == (tcpiphdrp_32)tp &&
  564 + tcpfrag_list_empty(tp) &&
564 565 ti->ti_len <= sbspace(&so->so_rcv)) {
565 566 /*
566 567 * this is a pure, in-sequence data packet
... ...
slirp/tcp_subr.c
... ... @@ -73,7 +73,7 @@ tcp_template(tp)
73 73 struct socket *so = tp->t_socket;
74 74 register struct tcpiphdr *n = &tp->t_template;
75 75  
76   - n->ti_next = n->ti_prev = 0;
  76 + n->ti_mbuf = NULL;
77 77 n->ti_x1 = 0;
78 78 n->ti_pr = IPPROTO_TCP;
79 79 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
... ... @@ -156,7 +156,7 @@ tcp_respond(tp, ti, m, ack, seq, flags)
156 156 tlen += sizeof (struct tcpiphdr);
157 157 m->m_len = tlen;
158 158  
159   - ti->ti_next = ti->ti_prev = 0;
  159 + ti->ti_mbuf = 0;
160 160 ti->ti_x1 = 0;
161 161 ti->ti_seq = htonl(seq);
162 162 ti->ti_ack = htonl(ack);
... ... @@ -196,7 +196,7 @@ tcp_newtcpcb(so)
196 196 return ((struct tcpcb *)0);
197 197  
198 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 200 tp->t_maxseg = TCP_MSS;
201 201  
202 202 tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
... ... @@ -272,11 +272,11 @@ tcp_close(tp)
272 272 DEBUG_ARG("tp = %lx", (long )tp);
273 273  
274 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 280 m_freem(m);
281 281 }
282 282 /* It's static */
... ...
slirp/tcp_var.h
... ... @@ -40,18 +40,12 @@
40 40 #include "tcpip.h"
41 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 44 * Tcp control block, one per tcp; fields:
51 45 */
52 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 49 short t_state; /* state of this connection */
56 50 short t_timer[TCPT_NTIMERS]; /* tcp timers */
57 51 short t_rxtshift; /* log(2) of rexmt exp. backoff */
... ... @@ -170,21 +164,6 @@ struct tcpcb {
170 164 #define TCP_REXMTVAL(tp) \
171 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 167 #ifdef LOG_ENABLED
189 168 /*
190 169 * TCP statistics.
... ...
slirp/tcpip.h
... ... @@ -44,8 +44,7 @@ struct tcpiphdr {
44 44 struct ipovly ti_i; /* overlaid ip structure */
45 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 48 #define ti_x1 ti_i.ih_x1
50 49 #define ti_pr ti_i.ih_pr
51 50 #define ti_len ti_i.ih_len
... ... @@ -62,6 +61,14 @@ struct tcpiphdr {
62 61 #define ti_sum ti_t.th_sum
63 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 73 * Just a clean way to get to the first byte
67 74 * of the packet
... ...
slirp/udp.c
... ... @@ -136,8 +136,7 @@ udp_input(m, iphlen)
136 136 * Checksum extended UDP header and data.
137 137 */
138 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 140 ((struct ipovly *)ip)->ih_x1 = 0;
142 141 ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
143 142 /* keep uh_sum for ICMP reply
... ... @@ -283,7 +282,7 @@ int udp_output2(struct socket *so, struct mbuf *m,
283 282 * and addresses and length put into network format.
284 283 */
285 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 286 ui->ui_x1 = 0;
288 287 ui->ui_pr = IPPROTO_UDP;
289 288 ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
... ...
slirp/udp.h
... ... @@ -60,8 +60,7 @@ struct udpiphdr {
60 60 struct ipovly ui_i; /* overlaid ip structure */
61 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 64 #define ui_x1 ui_i.ih_x1
66 65 #define ui_pr ui_i.ih_pr
67 66 #define ui_len ui_i.ih_len
... ...