mirror of
https://github.com/openbsd/src.git
synced 2025-01-10 06:47:55 -08:00
use m_pulldown not m_pullup2. fix some bugs in IPv6 tcp_trace().
This commit is contained in:
parent
3a42e73970
commit
24773939e6
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_debug.c,v 1.14 2003/05/14 01:12:27 jason Exp $ */
|
||||
/* $OpenBSD: tcp_debug.c,v 1.15 2003/05/29 00:35:18 itojun Exp $ */
|
||||
/* $NetBSD: tcp_debug.c,v 1.10 1996/02/13 23:43:36 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -113,16 +113,16 @@ int tcpconsdebug = 0;
|
||||
#endif
|
||||
|
||||
struct tcp_debug tcp_debug[TCP_NDEBUG];
|
||||
int tcp_debx;
|
||||
int tcp_debx = 0;
|
||||
|
||||
/*
|
||||
* Tcp debug routines
|
||||
*/
|
||||
void
|
||||
tcp_trace(act, ostate, tp, headers, req, len)
|
||||
tcp_trace(act, ostate, tp, m, req, len)
|
||||
short act, ostate;
|
||||
struct tcpcb *tp;
|
||||
caddr_t headers;
|
||||
struct mbuf *m;
|
||||
int req;
|
||||
int len;
|
||||
{
|
||||
@ -130,15 +130,27 @@ tcp_trace(act, ostate, tp, headers, req, len)
|
||||
tcp_seq seq, ack;
|
||||
int flags;
|
||||
#endif
|
||||
struct tcp_debug *td = &tcp_debug[tcp_debx++];
|
||||
struct tcpiphdr *ti = (struct tcpiphdr *)headers;
|
||||
caddr_t headers;
|
||||
struct tcp_debug *td;
|
||||
struct tcpiphdr *ti;
|
||||
struct tcphdr *th;
|
||||
#ifdef INET6
|
||||
struct tcpipv6hdr *ti6 = (struct tcpipv6hdr *)ti;
|
||||
#endif
|
||||
|
||||
td = &tcp_debug[tcp_debx++];
|
||||
if (tcp_debx == TCP_NDEBUG)
|
||||
tcp_debx = 0;
|
||||
|
||||
if (m)
|
||||
headers = mtod(m, caddr_t);
|
||||
else
|
||||
headers = NULL;
|
||||
ti = (struct tcpiphdr *)headers;
|
||||
#ifdef INET6
|
||||
ti6 = (struct tcpipv6hdr *)headers;
|
||||
#endif
|
||||
|
||||
td->td_time = iptime();
|
||||
td->td_act = act;
|
||||
td->td_ostate = ostate;
|
||||
@ -150,7 +162,7 @@ tcp_trace(act, ostate, tp, headers, req, len)
|
||||
switch (tp->pf) {
|
||||
#ifdef INET6
|
||||
case PF_INET6:
|
||||
if (ti) {
|
||||
if (ti6) {
|
||||
th = &ti6->ti6_t;
|
||||
td->td_ti6 = *ti6;
|
||||
} else
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_input.c,v 1.127 2003/05/19 02:03:28 dhartmei Exp $ */
|
||||
/* $OpenBSD: tcp_input.c,v 1.128 2003/05/29 00:35:18 itojun Exp $ */
|
||||
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -101,9 +101,6 @@
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
struct tcpiphdr tcp_saveti;
|
||||
struct tcpipv6hdr tcp_saveti6;
|
||||
|
||||
/* for the packet header length in the mbuf */
|
||||
#define M_PH_LEN(m) (((struct mbuf *)(m))->m_pkthdr.len)
|
||||
#define M_V6_LEN(m) (M_PH_LEN(m) - sizeof(struct ip6_hdr))
|
||||
@ -111,7 +108,6 @@ struct tcpipv6hdr tcp_saveti6;
|
||||
#endif /* INET6 */
|
||||
|
||||
int tcprexmtthresh = 3;
|
||||
struct tcpiphdr tcp_saveti;
|
||||
int tcptv_keep_init = TCPTV_KEEP_INIT;
|
||||
|
||||
extern u_long sb_max;
|
||||
@ -417,7 +413,7 @@ tcp_input(struct mbuf *m, ...)
|
||||
u_long tiwin;
|
||||
u_int32_t ts_val, ts_ecr;
|
||||
int ts_present = 0;
|
||||
int iphlen;
|
||||
int iphlen, toff;
|
||||
va_list ap;
|
||||
struct tcphdr *th;
|
||||
#ifdef INET6
|
||||
@ -431,12 +427,13 @@ tcp_input(struct mbuf *m, ...)
|
||||
int error, s;
|
||||
#endif /* IPSEC */
|
||||
int af;
|
||||
struct mbuf *tcp_saveti = NULL;
|
||||
#ifdef TCP_ECN
|
||||
u_char iptos;
|
||||
#endif
|
||||
|
||||
va_start(ap, m);
|
||||
iphlen = va_arg(ap, int);
|
||||
toff = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
|
||||
tcpstat.tcps_rcvtotal++;
|
||||
@ -466,101 +463,44 @@ tcp_input(struct mbuf *m, ...)
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
#ifdef DIAGNOSTIC
|
||||
if (iphlen < sizeof(struct ip)) {
|
||||
if (toff < sizeof(struct ip)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif /* DIAGNOSTIC */
|
||||
if (iphlen > sizeof(struct ip)) {
|
||||
#if 0 /*XXX*/
|
||||
ip_stripoptions(m, (struct mbuf *)0);
|
||||
iphlen = sizeof(struct ip);
|
||||
#else
|
||||
m_freem(m);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#ifdef DIAGNOSTIC
|
||||
if (iphlen < sizeof(struct ip6_hdr)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif /* DIAGNOSTIC */
|
||||
if (iphlen > sizeof(struct ip6_hdr)) {
|
||||
#if 0 /*XXX*/
|
||||
ipv6_stripoptions(m, iphlen);
|
||||
iphlen = sizeof(struct ip6_hdr);
|
||||
#else
|
||||
m_freem(m);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->m_len < iphlen + sizeof(struct tcphdr)) {
|
||||
m = m_pullup2(m, iphlen + sizeof(struct tcphdr));
|
||||
if (m == NULL) {
|
||||
ip = mtod(m, struct ip *);
|
||||
iphlen = sizeof(*ip);
|
||||
IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
|
||||
sizeof(struct tcphdr));
|
||||
if (th == NULL) {
|
||||
tcpstat.tcps_rcvshort++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ip = NULL;
|
||||
#ifdef INET6
|
||||
ip6 = NULL;
|
||||
#endif
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
{
|
||||
struct tcpiphdr *ti;
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
#if 1
|
||||
tlen = m->m_pkthdr.len - iphlen;
|
||||
#else
|
||||
tlen = ((struct ip *)ti)->ip_len;
|
||||
#endif
|
||||
ti = mtod(m, struct tcpiphdr *);
|
||||
|
||||
len = m->m_pkthdr.len;
|
||||
tlen = len - toff;
|
||||
#ifdef TCP_ECN
|
||||
/* save ip_tos before clearing it for checksum */
|
||||
iptos = ip->ip_tos;
|
||||
#endif
|
||||
/*
|
||||
* Checksum extended TCP header and data.
|
||||
*/
|
||||
len = sizeof(struct ip) + tlen;
|
||||
bzero(ti->ti_x1, sizeof ti->ti_x1);
|
||||
ti->ti_len = (u_int16_t)tlen;
|
||||
HTONS(ti->ti_len);
|
||||
if ((m->m_pkthdr.csum & M_TCP_CSUM_IN_OK) == 0) {
|
||||
if (m->m_pkthdr.csum & M_TCP_CSUM_IN_BAD) {
|
||||
tcpstat.tcps_inhwcsum++;
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
if ((ti->ti_sum = in_cksum(m, len)) != 0) {
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
} else {
|
||||
m->m_pkthdr.csum &= ~M_TCP_CSUM_IN_OK;
|
||||
tcpstat.tcps_inhwcsum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#ifdef DIAGNOSTIC
|
||||
if (toff < sizeof(struct ip6_hdr)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif /* DIAGNOSTIC */
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
tlen = m->m_pkthdr.len - iphlen;
|
||||
iphlen = sizeof(*ip6);
|
||||
IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
|
||||
sizeof(struct tcphdr));
|
||||
if (th == NULL) {
|
||||
tcpstat.tcps_rcvshort++;
|
||||
return;
|
||||
}
|
||||
len = m->m_pkthdr.len;
|
||||
tlen = len - toff;
|
||||
#ifdef TCP_ECN
|
||||
iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
|
||||
#endif
|
||||
@ -585,6 +525,36 @@ tcp_input(struct mbuf *m, ...)
|
||||
goto drop;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
/*
|
||||
* Checksum extended TCP header and data.
|
||||
*/
|
||||
HTONS(ip->ip_len);
|
||||
if ((m->m_pkthdr.csum & M_TCP_CSUM_IN_OK) == 0) {
|
||||
if (m->m_pkthdr.csum & M_TCP_CSUM_IN_BAD) {
|
||||
tcpstat.tcps_inhwcsum++;
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
if (in4_cksum(m, IPPROTO_TCP, toff, tlen) != 0) {
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
} else {
|
||||
m->m_pkthdr.csum &= ~M_TCP_CSUM_IN_OK;
|
||||
tcpstat.tcps_inhwcsum++;
|
||||
}
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
/*
|
||||
* Checksum extended TCP header and data.
|
||||
*/
|
||||
@ -597,8 +567,6 @@ tcp_input(struct mbuf *m, ...)
|
||||
}
|
||||
#endif /* TUBA_INCLUDE */
|
||||
|
||||
th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
|
||||
|
||||
/*
|
||||
* Check that TCP offset makes sense,
|
||||
* pull out TCP options and adjust length. XXX
|
||||
@ -610,25 +578,13 @@ tcp_input(struct mbuf *m, ...)
|
||||
}
|
||||
tlen -= off;
|
||||
if (off > sizeof(struct tcphdr)) {
|
||||
if (m->m_len < iphlen + off) {
|
||||
if ((m = m_pullup2(m, iphlen + off)) == NULL) {
|
||||
tcpstat.tcps_rcvshort++;
|
||||
return;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
ip = mtod(m, struct ip *);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
|
||||
IP6_EXTHDR_GET(th, struct tcphdr *, m, toff, off);
|
||||
if (th == NULL) {
|
||||
tcpstat.tcps_rcvshort++;
|
||||
return;
|
||||
}
|
||||
optlen = off - sizeof(struct tcphdr);
|
||||
optp = mtod(m, u_int8_t *) + iphlen + sizeof(struct tcphdr);
|
||||
optp = mtod(m, u_int8_t *) + toff + sizeof(struct tcphdr);
|
||||
/*
|
||||
* Do quick retrieval of timestamp options ("options
|
||||
* prediction?"). If timestamp is the only option and it's
|
||||
@ -716,16 +672,28 @@ findpcb:
|
||||
if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
|
||||
if (so->so_options & SO_DEBUG) {
|
||||
ostate = tp->t_state;
|
||||
switch (af) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
tcp_saveti6 = *(mtod(m, struct tcpipv6hdr *));
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
tcp_saveti = *(mtod(m, struct tcpiphdr *));
|
||||
break;
|
||||
tcp_saveti = NULL;
|
||||
MGETHDR(tcp_saveti, M_DONTWAIT, MT_HEADER);
|
||||
if (!tcp_saveti)
|
||||
goto nosave;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (iphlen + sizeof(struct tcphdr) > MCLBYTES) {
|
||||
printf("cannot save to tcp_saveti\n");
|
||||
goto nosave;
|
||||
}
|
||||
#endif
|
||||
if (iphlen + sizeof(struct tcphdr) > MHLEN) {
|
||||
MCLGET(tcp_saveti, M_DONTWAIT);
|
||||
if ((tcp_saveti->m_flags & M_EXT) == 0) {
|
||||
m_freem(tcp_saveti);
|
||||
tcp_saveti = NULL;
|
||||
goto nosave;
|
||||
}
|
||||
}
|
||||
m_copydata(m, 0, iphlen, mtod(tcp_saveti, caddr_t));
|
||||
m_copydata(m, toff, sizeof(struct tcphdr),
|
||||
mtod(tcp_saveti, caddr_t) + iphlen);
|
||||
nosave:;
|
||||
}
|
||||
if (so->so_options & SO_ACCEPTCONN) {
|
||||
struct socket *so1;
|
||||
@ -883,7 +851,7 @@ findpcb:
|
||||
tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
|
||||
} else
|
||||
tdb = NULL;
|
||||
ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_IN,
|
||||
ipsp_spd_lookup(m, af, toff, &error, IPSP_DIRECTION_IN,
|
||||
tdb, inp);
|
||||
if (error) {
|
||||
splx(s);
|
||||
@ -1080,7 +1048,7 @@ findpcb:
|
||||
if (so->so_state & SS_CANTRCVMORE)
|
||||
m_freem(m);
|
||||
else {
|
||||
m_adj(m, iphlen + off);
|
||||
m_adj(m, toff + off);
|
||||
sbappendstream(&so->so_rcv, m);
|
||||
}
|
||||
sorwakeup(so);
|
||||
@ -1094,7 +1062,7 @@ findpcb:
|
||||
/*
|
||||
* Compute mbuf offset to TCP data segment.
|
||||
*/
|
||||
hdroptlen = iphlen + off;
|
||||
hdroptlen = toff + off;
|
||||
|
||||
/*
|
||||
* Calculate amount of space in receive window,
|
||||
@ -2242,20 +2210,8 @@ dodata: /* XXX */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (so->so_options & SO_DEBUG) {
|
||||
switch (tp->pf) {
|
||||
#ifdef INET6
|
||||
case PF_INET6:
|
||||
tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6,
|
||||
0, tlen);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
case PF_INET:
|
||||
tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti,
|
||||
0, tlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (so->so_options & SO_DEBUG)
|
||||
tcp_trace(TA_INPUT, ostate, tp, tcp_saveti, 0, tlen);
|
||||
|
||||
/*
|
||||
* Return any desired output.
|
||||
@ -2263,6 +2219,7 @@ dodata: /* XXX */
|
||||
if (needoutput || (tp->t_flags & TF_ACKNOW)) {
|
||||
(void) tcp_output(tp);
|
||||
}
|
||||
m_freem(tcp_saveti);
|
||||
return;
|
||||
|
||||
dropafterack:
|
||||
@ -2275,6 +2232,7 @@ dropafterack:
|
||||
m_freem(m);
|
||||
tp->t_flags |= TF_ACKNOW;
|
||||
(void) tcp_output(tp);
|
||||
m_freem(tcp_saveti);
|
||||
return;
|
||||
|
||||
dropwithreset_ratelim:
|
||||
@ -2324,27 +2282,17 @@ dropwithreset:
|
||||
/* destroy temporarily created socket */
|
||||
if (dropsocket)
|
||||
(void) soabort(so);
|
||||
m_freem(tcp_saveti);
|
||||
return;
|
||||
|
||||
drop:
|
||||
/*
|
||||
* Drop space held by incoming segment and return.
|
||||
*/
|
||||
if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) {
|
||||
switch (tp->pf) {
|
||||
#ifdef INET6
|
||||
case PF_INET6:
|
||||
tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6,
|
||||
0, tlen);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
case PF_INET:
|
||||
tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti,
|
||||
0, tlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
|
||||
tcp_trace(TA_DROP, ostate, tp, tcp_saveti, 0, tlen);
|
||||
|
||||
m_freem(tcp_saveti);
|
||||
m_freem(m);
|
||||
/* destroy temporarily created socket */
|
||||
if (dropsocket)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_output.c,v 1.54 2003/01/25 15:27:29 markus Exp $ */
|
||||
/* $OpenBSD: tcp_output.c,v 1.55 2003/05/29 00:35:18 itojun Exp $ */
|
||||
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
|
||||
|
||||
/*
|
||||
@ -1071,9 +1071,20 @@ send:
|
||||
/*
|
||||
* Trace.
|
||||
*/
|
||||
if (so->so_options & SO_DEBUG)
|
||||
tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, caddr_t), 0,
|
||||
len);
|
||||
if (so->so_options & SO_DEBUG) {
|
||||
/* TCP template does not fill ip version, so fill it in here */
|
||||
struct ip *sip;
|
||||
sip = mtod(m, struct ip *);
|
||||
switch (tp->pf) {
|
||||
case AF_INET:
|
||||
sip->ip_v = 4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sip->ip_v = 6;
|
||||
break;
|
||||
}
|
||||
tcp_trace(TA_OUTPUT, tp->t_state, tp, m, 0, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in IP length and desired time to live and
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_usrreq.c,v 1.68 2003/02/12 14:41:08 jason Exp $ */
|
||||
/* $OpenBSD: tcp_usrreq.c,v 1.69 2003/05/29 00:35:18 itojun Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -488,7 +488,7 @@ tcp_usrreq(so, req, m, nam, control)
|
||||
panic("tcp_usrreq");
|
||||
}
|
||||
if (tp && (so->so_options & SO_DEBUG))
|
||||
tcp_trace(TA_USER, ostate, tp, (caddr_t)0, req, 0);
|
||||
tcp_trace(TA_USER, ostate, tp, NULL, req, 0);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_var.h,v 1.48 2003/05/26 05:01:55 itojun Exp $ */
|
||||
/* $OpenBSD: tcp_var.h,v 1.49 2003/05/29 00:35:18 itojun Exp $ */
|
||||
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -424,7 +424,7 @@ void tcp_setpersist(struct tcpcb *);
|
||||
void tcp_slowtimo(void);
|
||||
struct mbuf *
|
||||
tcp_template(struct tcpcb *);
|
||||
void tcp_trace(int, int, struct tcpcb *, caddr_t, int, int);
|
||||
void tcp_trace(int, int, struct tcpcb *, struct mbuf *, int, int);
|
||||
struct tcpcb *
|
||||
tcp_usrclosed(struct tcpcb *);
|
||||
int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
||||
|
Loading…
Reference in New Issue
Block a user