diff --git a/sys/netipsec/xform_tcp.c b/sys/netipsec/xform_tcp.c --- a/sys/netipsec/xform_tcp.c +++ b/sys/netipsec/xform_tcp.c @@ -55,6 +55,7 @@ #include #include #include +#include #include @@ -136,15 +137,20 @@ { struct ippseudo ipp; struct ip *ip; + int hdr_len; ip = mtod(m, struct ip *); ipp.ippseudo_src.s_addr = ip->ip_src.s_addr; ipp.ippseudo_dst.s_addr = ip->ip_dst.s_addr; ipp.ippseudo_p = IPPROTO_TCP; ipp.ippseudo_pad = 0; - ipp.ippseudo_len = htons(m->m_pkthdr.len - (ip->ip_hl << 2)); + hdr_len = ip->ip_hl << 2; + if (ip->ip_p == IPPROTO_UDP) + /* TCP over UDP */ + hdr_len += sizeof(struct udphdr); + ipp.ippseudo_len = htons(m->m_pkthdr.len - hdr_len); MD5Update(ctx, (char *)&ipp, sizeof(ipp)); - return (ip->ip_hl << 2); + return (hdr_len); } #endif @@ -158,14 +164,20 @@ uint32_t nxt; } ip6p __aligned(4); struct ip6_hdr *ip6; + int hdr_len; ip6 = mtod(m, struct ip6_hdr *); ip6p.src = ip6->ip6_src; ip6p.dst = ip6->ip6_dst; - ip6p.len = htonl(m->m_pkthdr.len - sizeof(*ip6)); /* XXX: ext headers */ + hdr_len = sizeof(struct ip6_hdr); + if (ip6->ip6_nxt == IPPROTO_UDP) + /* TCP over UDP */ + hdr_len += sizeof(struct udphdr); + /* XXX: ext headers */ + ip6p.len = htonl(m->m_pkthdr.len - hdr_len); ip6p.nxt = htonl(IPPROTO_TCP); MD5Update(ctx, (char *)&ip6p, sizeof(ip6p)); - return (sizeof(*ip6)); + return (hdr_len); } #endif