diff options
Diffstat (limited to 'slirp2')
-rw-r--r-- | slirp2/ip.h | 64 | ||||
-rw-r--r-- | slirp2/ip_input.c | 140 | ||||
-rw-r--r-- | slirp2/misc.c | 30 | ||||
-rw-r--r-- | slirp2/slirp.c | 2 | ||||
-rw-r--r-- | slirp2/slirp.h | 10 | ||||
-rw-r--r-- | slirp2/tcp_input.c | 45 | ||||
-rw-r--r-- | slirp2/tcp_subr.c | 18 | ||||
-rw-r--r-- | slirp2/tcp_var.h | 25 | ||||
-rw-r--r-- | slirp2/tcpip.h | 11 | ||||
-rw-r--r-- | slirp2/udp.c | 5 | ||||
-rw-r--r-- | slirp2/udp.h | 3 |
11 files changed, 144 insertions, 209 deletions
diff --git a/slirp2/ip.h b/slirp2/ip.h index 8b6ae30..8cdb735 100644 --- a/slirp2/ip.h +++ b/slirp2/ip.h @@ -185,35 +185,31 @@ struct ip_timestamp { #define IP_MSS 576 /* default maximum segment size */ -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include <sys/types32.h> -#else #if SIZEOF_CHAR_P == 4 -typedef caddr_t caddr32_t; -#else -typedef u_int32_t caddr32_t; -#endif -#endif - -#if SIZEOF_CHAR_P == 4 -typedef struct ipq *ipqp_32; -typedef struct ipasfrag *ipasfragp_32; +struct mbuf_ptr { + struct mbuf *mptr; + uint32_t dummy; +}; #else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; +struct mbuf_ptr { + struct mbuf *mptr; +}; #endif +struct qlink { + void* next, *prev; +}; /* * Overlay for ip header used by other protocols (tcp, udp). */ struct ipovly { - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ + struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ u_int8_t ih_x1; /* (unused) */ u_int8_t ih_pr; /* protocol */ u_int16_t ih_len; /* protocol length */ ipaddr_t ih_src; /* source internet address */ ipaddr_t ih_dst; /* destination internet address */ -}; +} __attribute__((packed)); /* * Ip reassembly queue structure. Each fragment @@ -223,44 +219,30 @@ struct ipovly { * size 28 bytes */ struct ipq { - ipqp_32 next,prev; /* to other reass headers */ + struct qlink frag_link; /* to ip headers of fragments */ + struct qlink ip_link; /* to other reass headers */ u_int8_t ipq_ttl; /* time for reass q to live */ u_int8_t ipq_p; /* protocol of this fragment */ u_int16_t ipq_id; /* sequence id for reassembly */ - ipasfragp_32 ipq_next,ipq_prev; - /* to ip headers of fragments */ ipaddr_t ipq_src,ipq_dst; }; /* * Ip header, when holding a fragment. * - * Note: ipf_next must be at same offset as ipq_next above + * Note: ipf_next must be at same offset as frag_link above */ struct ipasfrag { -#ifdef WORDS_BIGENDIAN - u_int ip_v:4, - ip_hl:4; -#else - u_int ip_hl:4, - ip_v:4; -#endif - /* BUG : u_int changed to u_int8_t. - * sizeof(u_int)==4 on linux 2.0 - */ - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit - * to avoid destroying tos (PPPDTRuu); - * copied from (ip_off&IP_MF) */ - u_int16_t ip_len; - u_int16_t ip_id; - u_int16_t ip_off; - u_int8_t ip_ttl; - u_int8_t ip_p; - u_int16_t ip_sum; - ipasfragp_32 ipf_next; /* next fragment */ - ipasfragp_32 ipf_prev; /* previous fragment */ + struct qlink ipf_link; + struct ip ipf_ip; }; +#define ipf_off ipf_ip.ip_off +#define ipf_tos ipf_ip.ip_tos +#define ipf_len ipf_ip.ip_len +#define ipf_next ipf_link.next +#define ipf_prev ipf_link.prev + /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. diff --git a/slirp2/ip_input.c b/slirp2/ip_input.c index a0013aa..7a9ebf1 100644 --- a/slirp2/ip_input.c +++ b/slirp2/ip_input.c @@ -43,6 +43,7 @@ */ #include <slirp.h> +#include <osdep.h> #include "ip_icmp.h" int ip_defttl; @@ -56,7 +57,7 @@ struct ipq ipq; void ip_init() { - ipq.next = ipq.prev = (ipqp_32)&ipq; + ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link; ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); @@ -159,18 +160,20 @@ ip_input(m) */ if (ip->ip_off &~ IP_DF) { register struct ipq *fp; + struct qlink *l; /* * Look for queue of fragments * of this datagram. */ - for (fp = (struct ipq *) ipq.next; fp != &ipq; - fp = (struct ipq *) fp->next) + for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) { + fp = container_of(l, struct ipq, ip_link); if (ip->ip_id == fp->ipq_id && ip_equal(ip->ip_src, fp->ipq_src) && ip_equal(ip->ip_dst, fp->ipq_dst) && ip->ip_p == fp->ipq_p) - goto found; - fp = 0; + goto found; + } + fp = NULL; found: /* @@ -180,9 +183,9 @@ ip_input(m) */ ip->ip_len -= hlen; if (ip->ip_off & IP_MF) - ((struct ipasfrag *)ip)->ipf_mff |= 1; + ip->ip_tos |= 1; else - ((struct ipasfrag *)ip)->ipf_mff &= ~1; + ip->ip_tos &= ~1; ip->ip_off <<= 3; @@ -191,9 +194,9 @@ ip_input(m) * or if this is not the first fragment, * attempt reassembly; if it succeeds, proceed. */ - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { + if (ip->ip_tos & 1 || ip->ip_off) { ipstat.ips_fragments++; - ip = ip_reass((struct ipasfrag *)ip, fp); + ip = ip_reass(ip, fp); if (ip == 0) return; ipstat.ips_reassembled++; @@ -229,6 +232,9 @@ bad: return; } +#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink))) +#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink))) + /* * Take incoming datagram fragment and try to * reassemble it into whole datagram. If a chain for @@ -237,7 +243,7 @@ bad: */ struct ip * ip_reass(ip, fp) - register struct ipasfrag *ip; + register struct ip *ip; register struct ipq *fp; { register MBuf m = MBUF_FROM(ip); @@ -265,13 +271,13 @@ ip_reass(ip, fp) MBuf t; if ((t = mbuf_alloc()) == NULL) goto dropfrag; fp = MBUF_TO(t, struct ipq *); - insque_32(fp, &ipq); + insque(&fp->ip_link, &ipq.ip_link); fp->ipq_ttl = IPFRAGTTL; fp->ipq_p = ip->ip_p; fp->ipq_id = ip->ip_id; - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; - fp->ipq_src = ((struct ip *)ip)->ip_src; - fp->ipq_dst = ((struct ip *)ip)->ip_dst; + fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; + fp->ipq_src = ip->ip_src; + fp->ipq_dst = ip->ip_src; q = (struct ipasfrag *)fp; goto insert; } @@ -279,19 +285,18 @@ ip_reass(ip, fp) /* * Find a segment which begins after this one does. */ - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *)q->ipf_next) - if (q->ip_off > ip->ip_off) - break; - + for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; + q = q->ipf_next) + if (q->ipf_off > ip->ip_off) + break; /* * If there is a preceding segment, it may provide some of * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if (q->ipf_prev != (ipasfragp_32)fp) { - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; + if (q->ipf_prev != &fp->frag_link) { + struct ipasfrag *pq = q->ipf_prev; + i = pq->ipf_off + pq->ipf_len - ip->ip_off; if (i > 0) { if (i >= ip->ip_len) goto dropfrag; @@ -305,17 +310,18 @@ ip_reass(ip, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; - q->ip_off += i; - mbuf_trim(MBUF_FROM(q), i); - break; + while (q != (struct ipasfrag *)&fp->frag_link && + ip->ip_off + ip->ip_len > q->ipf_off) { + i = (ip->ip_off + ip->ip_len) - q->ipf_off; + if (i < q->ipf_len) { + q->ipf_len -= i; + q->ipf_off += i; + mbuf_trim(MBUF_FROM(q), i); + break; } - q = (struct ipasfrag *) q->ipf_next; - mbuf_free(MBUF_FROM((struct ipasfrag *) q->ipf_prev)); - ip_deq((struct ipasfrag *) q->ipf_prev); + q = q->ipf_next; + mbuf_free(MBUF_FROM(q->ipf_prev)); + ip_deq(q->ipf_prev); } insert: @@ -323,27 +329,28 @@ insert: * Stick new segment in its place; * check for complete reassembly. */ - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); + ip_enq(iptofrag(ip), q->ipf_prev); next = 0; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *) q->ipf_next) { - if (q->ip_off != next) - return (0); - next += q->ip_len; + for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; + q = q->ipf_next) + { + if (q->ipf_off != next) + return (0); + + next += q->ipf_len; } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) + if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) return (0); /* * Reassembly is complete; concatenate fragments. */ - q = (struct ipasfrag *) fp->ipq_next; + q = fp->frag_link.next; m = MBUF_FROM(q); q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag *)fp) { - MBuf t; - t = MBUF_FROM(q); + while (q != (struct ipasfrag *)&fp->frag_link) { + MBuf t = MBUF_FROM(q); q = (struct ipasfrag *) q->ipf_next; mbuf_append(m, t); } @@ -354,7 +361,7 @@ insert: * dequeue and discard fragment reassembly header. * Make header visible. */ - ip = (struct ipasfrag *) fp->ipq_next; + q = fp->frag_link.next; /* * If the fragments concatenated to an mbuf that's @@ -366,23 +373,23 @@ insert: if (m->m_flags & M_EXT) { int delta; delta = (char *)ip - m->m_dat; - ip = (struct ipasfrag *)(m->m_ext + delta); + q = (struct ipasfrag *)(m->m_ext + delta); } /* DEBUG_ARG("ip = %lx", (long)ip); * ip=(struct ipasfrag *)m->m_data; */ - ip->ip_len = next; - ip->ipf_mff &= ~1; - ((struct ip *)ip)->ip_src = fp->ipq_src; - ((struct ip *)ip)->ip_dst = fp->ipq_dst; - remque_32(fp); + ip = fragtoip(q); + ip->ip_len = next; + ip->ip_tos &= ~1; + ip->ip_src = fp->ipq_src; + ip->ip_dst = fp->ipq_dst; + remque(&fp->ip_link); (void) mbuf_free(MBUF_FROM(fp)); - m = MBUF_FROM(ip); m->m_len += (ip->ip_hl << 2); m->m_data -= (ip->ip_hl << 2); - return ((struct ip *)ip); + return ip; dropfrag: ipstat.ips_fragdropped++; @@ -400,13 +407,12 @@ ip_freef(fp) { register struct ipasfrag *q, *p; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = p) { - p = (struct ipasfrag *) q->ipf_next; + for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; q = p) { + p = q->ipf_next; ip_deq(q); mbuf_free(MBUF_FROM(q)); } - remque_32(fp); + remque(&fp->ip_link); (void) mbuf_free(MBUF_FROM(fp)); } @@ -420,10 +426,10 @@ ip_enq(p, prev) { DEBUG_CALL("ip_enq"); DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = (ipasfragp_32) prev; + p->ipf_prev = prev; p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; - prev->ipf_next = (ipasfragp_32) p; + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; + prev->ipf_next = p; } /* @@ -445,20 +451,20 @@ ip_deq(p) void ip_slowtimo() { - register struct ipq *fp; + struct qlink *l; DEBUG_CALL("ip_slowtimo"); - fp = (struct ipq *) ipq.next; - if (fp == 0) + l = ipq.ip_link.next; + if (l == 0) return; - while (fp != &ipq) { - --fp->ipq_ttl; - fp = (struct ipq *) fp->next; - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { + while (l != &ipq.ip_link) { + struct ipq *fp = container_of(l, struct ipq, ip_link); + l = l->next; + if (--fp->ipq_ttl == 0) { ipstat.ips_fragtimeout++; - ip_freef((struct ipq *) fp->prev); + ip_freef(fp); } } } diff --git a/slirp2/misc.c b/slirp2/misc.c index e34ca77..9a2699a 100644 --- a/slirp2/misc.c +++ b/slirp2/misc.c @@ -62,36 +62,6 @@ getouraddr() our_addr_ip = loopback_addr_ip; } -#if SIZEOF_CHAR_P == 8 - -struct quehead_32 { - u_int32_t qh_link; - u_int32_t qh_rlink; -}; - -inline void -insque_32(void* a, void* b) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (u_int32_t)element; - element->qh_rlink = (u_int32_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (u_int32_t)element; -} - -inline void -remque_32(void* a) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#endif /* SIZEOF_CHAR_P == 8 */ - struct quehead { struct quehead *qh_link; struct quehead *qh_rlink; diff --git a/slirp2/slirp.c b/slirp2/slirp.c index d7bc545..8099aff 100644 --- a/slirp2/slirp.c +++ b/slirp2/slirp.c @@ -280,7 +280,7 @@ void slirp_select_fill(int *pnfds, * in the fragment queue, or there are TCP connections active */ do_slowtimo = ((tcb.so_next != &tcb) || - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); + (&ipq.ip_link != ipq.ip_link.next)); for (so = tcb.so_next; so != &tcb; so = so_next) { so_next = so->so_next; diff --git a/slirp2/slirp.h b/slirp2/slirp.h index bb21ff8..e69940b 100644 --- a/slirp2/slirp.h +++ b/slirp2/slirp.h @@ -211,14 +211,6 @@ void lprint _P((const char *, ...)); extern int do_echo; -#if SIZEOF_CHAR_P == 4 -# define insque_32 insque -# define remque_32 remque -#else - inline void insque_32 _P((void *, void *)); - inline void remque_32 _P((void *)); -#endif - #define DEFAULT_BAUD 115200 /* cksum.c */ @@ -231,7 +223,7 @@ void if_output _P((struct socket *, MBuf )); /* ip_input.c */ void ip_init _P((void)); void ip_input _P((MBuf )); -struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *)); +struct ip * ip_reass _P((register struct ip*, register struct ipq *)); void ip_freef _P((struct ipq *)); void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); void ip_deq _P((register struct ipasfrag *)); diff --git a/slirp2/tcp_input.c b/slirp2/tcp_input.c index 1c5a709..c3196d3 100644 --- a/slirp2/tcp_input.c +++ b/slirp2/tcp_input.c @@ -71,7 +71,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #ifdef TCP_ACK_HACK #define TCP_REASS(tp, ti, m, so, flags) {\ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) {\ if (ti->ti_flags & TH_PUSH) \ tp->t_flags |= TF_ACKNOW; \ @@ -94,7 +94,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #else #define TCP_REASS(tp, ti, m, so, flags) { \ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) { \ tp->t_flags |= TF_DELACK; \ (tp)->rcv_nxt += (ti)->ti_len; \ @@ -133,8 +133,8 @@ tcp_reass(tp, ti, m) /* * Find a segment which begins after this one does. */ - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) + for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); + q = tcpiphdr_next(q)) if (SEQ_GT(q->ti_seq, ti->ti_seq)) break; @@ -143,9 +143,9 @@ tcp_reass(tp, ti, m) * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { + if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { register int i; - q = (struct tcpiphdr *)q->ti_prev; + q = tcpiphdr_prev(q); /* conversion to int (in i) handles seq wraparound */ i = q->ti_seq + q->ti_len - ti->ti_seq; if (i > 0) { @@ -165,36 +165,36 @@ tcp_reass(tp, ti, m) ti->ti_len -= i; ti->ti_seq += i; } - q = (struct tcpiphdr *)(q->ti_next); + q = tcpiphdr_next(q); } tcpstat.tcps_rcvoopack++; tcpstat.tcps_rcvoobyte += ti->ti_len; - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ + ti->ti_mbuf = m; /* * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct tcpiphdr *)tp) { + while (!tcpfrag_list_end(q, tp)) { register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; if (i <= 0) break; if (i < q->ti_len) { q->ti_seq += i; q->ti_len -= i; - mbuf_trim((MBuf ) REASS_MBUF(q), i); + mbuf_trim(q->ti_mbuf, i); break; } - q = (struct tcpiphdr *)q->ti_next; - m = (MBuf ) REASS_MBUF((struct tcpiphdr *)q->ti_prev); - remque_32((void *)(q->ti_prev)); + q = tcpiphdr_next(q); + m = tcpiphdr_prev(q)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(q))); mbuf_free(m); } /* * Stick new segment in its place. */ - insque_32(ti, (void *)(q->ti_prev)); + insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); present: /* @@ -203,17 +203,17 @@ present: */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); - ti = (struct tcpiphdr *) tp->seg_next; - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) + ti = tcpfrag_list_first(tp); + if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt) return (0); if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) return (0); do { tp->rcv_nxt += ti->ti_len; flags = ti->ti_flags & TH_FIN; - remque_32(ti); - m = (MBuf ) REASS_MBUF(ti); /* XXX */ - ti = (struct tcpiphdr *)ti->ti_next; + remque(tcpiphdr2qlink(ti)); + m = ti->ti_mbuf; + ti = tcpiphdr_next(ti); /* if (so->so_state & SS_FCANTRCVMORE) */ if (so->so_state & SS_FCANTSENDMORE) mbuf_free(m); @@ -223,7 +223,7 @@ present: } else sbuf_append(so, m); } - } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); + } while (!tcpfrag_list_end(ti, tp) && ti->ti_seq == tp->rcv_nxt); /* sorwakeup(so); */ return (flags); } @@ -300,7 +300,8 @@ tcp_input(m, iphlen, inso) * Checksum extended TCP header and data. */ tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; + memset(&ti->ti_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); ti->ti_x1 = 0; ti->ti_len = htons((u_int16_t)tlen); len = sizeof(struct ip ) + tlen; @@ -555,7 +556,7 @@ findso: return; } } else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && + tcpfrag_list_empty(tp) && ti->ti_len <= sbuf_space(&so->so_rcv)) { /* * this is a pure, in-sequence data packet diff --git a/slirp2/tcp_subr.c b/slirp2/tcp_subr.c index fb55513..fdcb26c 100644 --- a/slirp2/tcp_subr.c +++ b/slirp2/tcp_subr.c @@ -85,7 +85,7 @@ tcp_template(tp) struct socket *so = tp->t_socket; register struct tcpiphdr *n = &tp->t_template; - n->ti_next = n->ti_prev = 0; + n->ti_mbuf = NULL; n->ti_x1 = 0; n->ti_pr = IPPROTO_TCP; n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); @@ -168,7 +168,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) tlen += sizeof (struct tcpiphdr); m->m_len = tlen; - ti->ti_next = ti->ti_prev = 0; + ti->ti_mbuf = 0; ti->ti_x1 = 0; ti->ti_seq = htonl(seq); ti->ti_ack = htonl(ack); @@ -208,7 +208,7 @@ tcp_newtcpcb(so) return ((struct tcpcb *)0); memset((char *) tp, 0, sizeof(struct tcpcb)); - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; + tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; tp->t_maxseg = tcp_mssdflt; tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; @@ -284,12 +284,12 @@ tcp_close(tp) DEBUG_ARG("tp = %lx", (long )tp); /* free the reassembly queue, if any */ - t = (struct tcpiphdr *) tp->seg_next; - while (t != (struct tcpiphdr *)tp) { - t = (struct tcpiphdr *)t->ti_next; - m = (MBuf ) REASS_MBUF((struct tcpiphdr *)t->ti_prev); - remque_32((struct tcpiphdr *) t->ti_prev); - mbuf_free(m); + t = tcpfrag_list_first(tp); + while (!tcpfrag_list_end(t, tp)) { + t = tcpiphdr_next(t); + m = tcpiphdr_prev(t)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(t))); + mbuf_free(m); } /* It's static */ /* if (tp->t_template) diff --git a/slirp2/tcp_var.h b/slirp2/tcp_var.h index b30a15d..3509ec8 100644 --- a/slirp2/tcp_var.h +++ b/slirp2/tcp_var.h @@ -41,18 +41,12 @@ #include "tcpip.h" #include "tcp_timer.h" -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif - /* * Tcp control block, one per tcp; fields: */ struct tcpcb { - tcpiphdrp_32 seg_next; /* sequencing queue */ - tcpiphdrp_32 seg_prev; + struct tcpiphdr *seg_next; /* sequencing queue */ + struct tcpiphdr *seg_prev; short t_state; /* state of this connection */ short t_timer[TCPT_NTIMERS]; /* tcp timers */ short t_rxtshift; /* log(2) of rexmt exp. backoff */ @@ -171,21 +165,6 @@ struct tcpcb { #define TCP_REXMTVAL(tp) \ (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) -/* XXX - * We want to avoid doing m_pullup on incoming packets but that - * means avoiding MBUF_FROM on the tcp reassembly code. That in turn means - * keeping an mbuf pointer in the reassembly queue (since we might - * have a cluster). As a quick hack, the source & destination - * port numbers (which are no longer needed once we've located the - * tcpcb) are overlayed with an mbuf pointer. - */ -#if SIZEOF_CHAR_P == 4 -typedef MBuf mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - /* * TCP statistics. * Many of these should be kept per connection, diff --git a/slirp2/tcpip.h b/slirp2/tcpip.h index 82708b0..891d699 100644 --- a/slirp2/tcpip.h +++ b/slirp2/tcpip.h @@ -44,8 +44,7 @@ struct tcpiphdr { struct ipovly ti_i; /* overlaid ip structure */ struct tcphdr ti_t; /* tcp header */ }; -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev +#define ti_mbuf ti_i.ih_mbuf.mptr #define ti_x1 ti_i.ih_x1 #define ti_pr ti_i.ih_pr #define ti_len ti_i.ih_len @@ -62,6 +61,14 @@ struct tcpiphdr { #define ti_sum ti_t.th_sum #define ti_urp ti_t.th_urp +#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink))) +#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink))) +#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) +#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) +#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) +#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T)) +#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T)) + /* * Just a clean way to get to the first byte * of the packet diff --git a/slirp2/udp.c b/slirp2/udp.c index d4296d7..9305cfd 100644 --- a/slirp2/udp.c +++ b/slirp2/udp.c @@ -133,8 +133,7 @@ udp_input(m, iphlen) * Checksum extended UDP header and data. */ if (udpcksum && uh->uh_sum) { - ((struct ipovly *)ip)->ih_next = 0; - ((struct ipovly *)ip)->ih_prev = 0; + memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); ((struct ipovly *)ip)->ih_x1 = 0; ((struct ipovly *)ip)->ih_len = uh->uh_ulen; /* keep uh_sum for ICMP reply @@ -282,7 +281,7 @@ int udp_output2_(struct socket* so, MBuf m, * and addresses and length put into network format. */ ui = MBUF_TO(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; + memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ diff --git a/slirp2/udp.h b/slirp2/udp.h index f1bb8c9..cadd17e 100644 --- a/slirp2/udp.h +++ b/slirp2/udp.h @@ -62,8 +62,7 @@ struct udpiphdr { struct ipovly ui_i; /* overlaid ip structure */ struct udphdr ui_u; /* udp header */ }; -#define ui_next ui_i.ih_next -#define ui_prev ui_i.ih_prev +#define ui_mbuf ui_i.ih_mbuf.mptr #define ui_x1 ui_i.ih_x1 #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len |