- }
- ip6 = mtod(m, struct ip6_hdr *);
- /* ECN consideration. */
- ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
- if (!key_checktunnelsanity(sav, AF_INET6,
- (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
- ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
- "in IPv6 ESP input: %s %s\n",
- ipsec6_logpacketstr(ip6, spi),
- ipsec_logsastr(sav)));
- IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
- goto bad;
+ if (!key_checktunnelsanity(sav, AF_INET6,
+ (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
+ ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
+ "in IPv6 ESP input: %s %s\n",
+ ipsec6_logpacketstr(ip6, spi),
+ ipsec_logsastr(sav)));
+ IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
+ goto bad;
+ }
+
+ bzero(&addr, sizeof(addr));
+ ip6addr = (__typeof__(ip6addr))&addr;
+ ip6addr->sin6_family = AF_INET6;
+ ip6addr->sin6_len = sizeof(*ip6addr);
+ ip6addr->sin6_addr = ip6->ip6_dst;
+ } else if (ifamily == AF_INET) {
+ struct sockaddr_in *ipaddr;
+
+ if (m->m_len < sizeof(*ip)) {
+ m = m_pullup(m, sizeof(*ip));
+ if (!m) {
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ 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 "
+ "in ESP input: %s %s\n",
+ ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ goto bad;
+ }
+
+ bzero(&addr, sizeof(addr));
+ ipaddr = (__typeof__(ipaddr))&addr;
+ ipaddr->sin_family = AF_INET;
+ ipaddr->sin_len = sizeof(*ipaddr);
+ ipaddr->sin_addr = ip->ip_dst;