m->m_len -= stripsiz;
m->m_pkthdr.len -= stripsiz;
ip6 = mtod(m, __typeof__(ip6));
- ip6->ip6_plen = ip6->ip6_plen - stripsiz;
+ ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
ip6->ip6_nxt = IPPROTO_ESP;
return ip6;
}
* XXX more sanity checks
* XXX relationship with gif?
*/
- u_int8_t tos;
+ u_int8_t tos, otos;
+ int sum;
tos = ip->ip_tos;
m_adj(m, off + esplen + ivlen);
}
ip = mtod(m, struct ip *);
/* ECN consideration. */
+
+ otos = ip->ip_tos;
if (ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos) == 0) {
IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
goto bad;
}
+
+ if (otos != ip->ip_tos) {
+ sum = ~ntohs(ip->ip_sum) & 0xffff;
+ sum += (~otos & 0xffff) + ip->ip_tos;
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16); /* add carry */
+ ip->ip_sum = htons(~sum & 0xffff);
+ }
+
if (!key_checktunnelsanity(sav, AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
goto bad;
}
}
+
+ u_int8_t otos;
+ int sum;
+
ip = mtod(m, struct ip *);
+ otos = ip->ip_tos;
/* ECN consideration. */
if (ip46_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip->ip_tos) == 0) {
IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
goto bad;
}
+
+ if (otos != ip->ip_tos) {
+ sum = ~ntohs(ip->ip_sum) & 0xffff;
+ sum += (~otos & 0xffff) + ip->ip_tos;
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16); /* add carry */
+ ip->ip_sum = htons(~sum & 0xffff);
+ }
+
if (!key_checktunnelsanity(sav, AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
}
}
- if (proto_input(PF_INET6, m) != 0)
+ if (proto_input(ifamily == AF_INET ? PF_INET : PF_INET6, m) != 0)
goto bad;
nxt = IPPROTO_DONE;
} else {
goto bad;
}
+ /*
+ * Set the csum valid flag, if we authenticated the
+ * packet, the payload shouldn't be corrupt unless
+ * it was corrupted before being signed on the other
+ * side.
+ */
+ if (nxt == IPPROTO_TCP || nxt == IPPROTO_UDP) {
+ m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xFFFF;
+ }
+
// Input via IPSec interface
if (sav->sah->ipsec_if != NULL) {
if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {