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 | ... | ... |