Commit 429d0a3db8138ae6a545500b92dbe532629a24e1
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
Showing
11 changed files
with
138 additions
and
207 deletions
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 | ... | ... |