summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_subr.c')
-rw-r--r--sys/netinet/tcp_subr.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 3857b75..06849be 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -443,7 +443,10 @@ tcp_respond(tp, ipgen, th, m, ack, seq, flags)
tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0);
#endif
#ifdef IPSEC
- ipsec_setsocket(m, tp ? tp->t_inpcb->inp_socket : NULL);
+ if (ipsec_setsocket(m, tp ? tp->t_inpcb->inp_socket : NULL) != 0) {
+ m_freem(m);
+ return;
+ }
#endif
#ifdef INET6
if (isipv6) {
@@ -1020,13 +1023,17 @@ tcp6_ctlinput(cmd, sa, d)
struct sockaddr *sa;
void *d;
{
- register struct tcphdr *thp;
struct tcphdr th;
void (*notify) __P((struct inpcb *, int)) = tcp_notify;
- struct sockaddr_in6 sa6;
struct ip6_hdr *ip6;
struct mbuf *m;
+ struct ip6ctlparam *ip6cp = NULL;
+ const struct sockaddr_in6 *sa6_src = NULL;
int off;
+ struct tcp_portonly {
+ u_int16_t th_sport;
+ u_int16_t th_dport;
+ } *thp;
if (sa->sa_family != AF_INET6 ||
sa->sa_len != sizeof(struct sockaddr_in6))
@@ -1042,56 +1049,36 @@ tcp6_ctlinput(cmd, sa, d)
/* if the parameter is from icmp6, decode it. */
if (d != NULL) {
- struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
+ ip6cp = (struct ip6ctlparam *)d;
m = ip6cp->ip6c_m;
ip6 = ip6cp->ip6c_ip6;
off = ip6cp->ip6c_off;
+ sa6_src = ip6cp->ip6c_src;
} else {
m = NULL;
ip6 = NULL;
off = 0; /* fool gcc */
+ sa6_src = &sa6_any;
}
- /*
- * Translate addresses into internal form.
- * Sa check if it is AF_INET6 is done at the top of this funciton.
- */
- sa6 = *(struct sockaddr_in6 *)sa;
- if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr) != 0 && m != NULL &&
- m->m_pkthdr.rcvif != NULL)
- sa6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
-
if (ip6) {
/*
* XXX: We assume that when IPV6 is non NULL,
* M and OFF are valid.
*/
- struct in6_addr s;
-
- /* translate addresses into internal form */
- memcpy(&s, &ip6->ip6_src, sizeof(s));
- if (IN6_IS_ADDR_LINKLOCAL(&s) != 0 && m != NULL &&
- m->m_pkthdr.rcvif != NULL)
- s.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
/* check if we can safely examine src and dst ports */
- if (m->m_pkthdr.len < off + sizeof(th))
+ if (m->m_pkthdr.len < off + sizeof(*thp))
return;
- if (m->m_len < off + sizeof(th)) {
- /*
- * this should be rare case
- * because now MINCLSIZE is "(MHLEN + 1)",
- * so we compromise on this copy...
- */
- m_copydata(m, off, sizeof(th), (caddr_t)&th);
- thp = &th;
- } else
- thp = (struct tcphdr *)(mtod(m, caddr_t) + off);
- in6_pcbnotify(&tcb, (struct sockaddr *)&sa6, thp->th_dport,
- &s, thp->th_sport, cmd, notify);
+ bzero(&th, sizeof(th));
+ m_copydata(m, off, sizeof(*thp), (caddr_t)&th);
+
+ in6_pcbnotify(&tcb, sa, th.th_dport,
+ (struct sockaddr *)ip6cp->ip6c_src,
+ th.th_sport, cmd, notify);
} else
- in6_pcbnotify(&tcb, (struct sockaddr *)&sa6, 0, &zeroin6_addr,
+ in6_pcbnotify(&tcb, sa, 0, (struct sockaddr *)sa6_src,
0, cmd, notify);
}
#endif /* INET6 */
@@ -1323,9 +1310,12 @@ tcp_rtlookup6(inp)
if (rt == NULL || !(rt->rt_flags & RTF_UP)) {
/* No route yet, so try to acquire one */
if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
- ro6->ro_dst.sin6_family = AF_INET6;
- ro6->ro_dst.sin6_len = sizeof(ro6->ro_dst);
- ro6->ro_dst.sin6_addr = inp->in6p_faddr;
+ struct sockaddr_in6 *dst6;
+
+ dst6 = (struct sockaddr_in6 *)&ro6->ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(ro6->ro_dst);
+ dst6->sin6_addr = inp->in6p_faddr;
rtalloc((struct route *)ro6);
rt = ro6->ro_rt;
}
@@ -1376,6 +1366,7 @@ ipsec_hdrsiz_tcp(tp)
sizeof(struct ip));
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
sizeof(struct tcphdr));
+ ip->ip_vhl = IP_VHL_BORING;
hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
}
OpenPOWER on IntegriCloud