diff options
-rw-r--r-- | sys/netinet/ip_ah.c | 363 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 529 |
2 files changed, 0 insertions, 892 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c deleted file mode 100644 index 551a5ae8023..00000000000 --- a/sys/netinet/ip_ah.c +++ /dev/null @@ -1,363 +0,0 @@ -/* $OpenBSD: ip_ah.c,v 1.31 1999/12/07 09:01:47 angelos Exp $ */ - -/* - * The authors of this code are John Ioannidis (ji@tla.org), - * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). - * - * This code was written by John Ioannidis for BSD/OS in Athens, Greece, - * in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis. - * - * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis - * and Niels Provos. - * - * Additional features in 1999 by Angelos D. Keromytis. - * - * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, - * Angelos D. Keromytis and Niels Provos. - * - * Permission to use, copy, and modify this software without fee - * is hereby granted, provided that this entire notice is included in - * all copies of any software which is or includes a copy or - * modification of this software. - * You may use this code under the GNU public license if you so wish. Please - * contribute changes back to the authors under this freer than GPL license - * so that we may further the use of strong encryption without limitations to - * all. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Authentication Header Processing - * Per RFC1826 (Atkinson, 1995) - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/domain.h> -#include <sys/protosw.h> -#include <sys/socket.h> -#include <sys/sysctl.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> -#include <net/bpf.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet/ip_icmp.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> - -#include <netinet/ip_ipsp.h> -#include <netinet/ip_ah.h> - -#include <net/if_enc.h> - -#include "bpfilter.h" - -extern struct enc_softc encif[]; - -#ifdef ENCDEBUG -#define DPRINTF(x) if (encdebug) printf x -#else -#define DPRINTF(x) -#endif - -#ifndef offsetof -#define offsetof(s, e) ((int)&((s *)0)->e) -#endif - -int ah_enable = 0; - -/* - * ah_input gets called when we receive an packet with an AH. - */ - -void -#if __STDC__ -ah_input(struct mbuf *m, ...) -#else -ah_input(m, va_alist) - register struct mbuf *m; -#endif -{ - int iphlen; - union sockaddr_union sunion; - struct ifqueue *ifq = NULL; - struct ah_old *ahp, ahn; - struct ip *ipo, ipn; - struct tdb *tdbp; - int s; - va_list ap; - - va_start(ap, m); - iphlen = va_arg(ap, int); - va_end(ap); - - ahstat.ahs_input++; - - if (!ah_enable) - { - m_freem(m); - ahstat.ahs_pdrops++; - return; - } - - /* - * Make sure that at least the fixed part of the AH header is - * in the first mbuf. - */ - - ipo = mtod(m, struct ip *); - if (m->m_len < iphlen + AH_OLD_FLENGTH) - { - if ((m = m_pullup(m, iphlen + AH_OLD_FLENGTH)) == 0) - { - ahstat.ahs_hdrops++; - return; - } - - ipo = mtod(m, struct ip *); - } - - ahp = (struct ah_old *) ((caddr_t) ipo + iphlen); - - /* - * Find tunnel control block and (indirectly) call the appropriate - * tranform routine. The resulting mbuf chain is a valid - * IP packet ready to go through input processing. - */ - - bzero(&sunion, sizeof(sunion)); - sunion.sin.sin_family = AF_INET; - sunion.sin.sin_len = sizeof(struct sockaddr_in); - sunion.sin.sin_addr = ipo->ip_dst; - s = spltdb(); - tdbp = gettdb(ahp->ah_spi, &sunion, IPPROTO_AH); - if (tdbp == NULL) - { - DPRINTF(("ah_input(): could not find SA for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo->ip_src), ipsp_address(sunion), ntohl(ahp->ah_spi))); - m_freem(m); - ahstat.ahs_notdb++; - return; - } - - if (tdbp->tdb_flags & TDBF_INVALID) - { - DPRINTF(("ah_input(): attempted to use invalid SA %08x, packet from %s to %s\n", ntohl(ahp->ah_spi), inet_ntoa4(ipo->ip_src), ipsp_address(sunion))); - m_freem(m); - ahstat.ahs_invalid++; - return; - } - - if (tdbp->tdb_xform == NULL) - { - DPRINTF(("ah_input(): attempted to use uninitialized SA %08x, packet from %s to %s\n", ntohl(ahp->ah_spi), inet_ntoa4(ipo->ip_src), ipsp_address(sunion))); - m_freem(m); - ahstat.ahs_noxform++; - return; - } - - if (tdbp->tdb_interface) - m->m_pkthdr.rcvif = (struct ifnet *) tdbp->tdb_interface; - else - m->m_pkthdr.rcvif = &encif[0].sc_if; - - /* Register first use, setup expiration timer */ - if (tdbp->tdb_first_use == 0) - { - tdbp->tdb_first_use = time.tv_sec; - tdb_expiration(tdbp, TDBEXP_TIMEOUT); - } - - ipn = *ipo; - ahn = *ahp; - - m = (*(tdbp->tdb_xform->xf_input))(m, tdbp, ipo->ip_hl << 2, - offsetof(struct ip, ip_p)); - if (m == NULL) - { - ahstat.ahs_badkcr++; - return; - } - - if ((m = m_pullup(m, ipn.ip_hl << 2)) == 0) - { - ahstat.ahs_hdrops++; - return; - } - - ipo = mtod(m, struct ip *); - ipo->ip_len = htons(m->m_pkthdr.len); - HTONS(ipo->ip_id); - HTONS(ipo->ip_off); - ipo->ip_sum = 0; - ipo->ip_sum = in_cksum(m, ipo->ip_hl << 2); - - if (ipo->ip_p == IPPROTO_IPIP) /* IP-in-IP encapsulation */ - { - /* ipn will now contain the inner IP header */ - m_copydata(m, ipo->ip_hl << 2, sizeof(struct ip), (caddr_t) &ipn); - - if (tdbp->tdb_flags & TDBF_UNIQUE) - if ((ipn.ip_src.s_addr != ipo->ip_src.s_addr) || - (ipn.ip_dst.s_addr != ipo->ip_dst.s_addr)) - { - DPRINTF(("ah_input(): AH-tunnel with different internal addresses %s->%s (%s->%s), SA %s/%08x\n", inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet_ntoa4(ipn.ip_src), ipsp_address(sunion), ipsp_address(tdbp->tdb_dst), ntohl(tdbp->tdb_spi))); - m_freem(m); - ahstat.ahs_hdrops++; - return; - } - - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if ((tdbp->tdb_proxy.sin.sin_addr.s_addr != INADDR_ANY) && - (ipn.ip_src.s_addr != tdbp->tdb_proxy.sin.sin_addr.s_addr)) - { - DPRINTF(("ah_input(): inner source address %s doesn't correspond to expected proxy source %s, SA %s/%08x\n", inet_ntoa4(ipo->ip_src), ipsp_address(tdbp->tdb_proxy), ipsp_address(tdbp->tdb_dst), ntohl(tdbp->tdb_spi))); - m_free(m); - ahstat.ahs_hdrops++; - return; - } - } - - /* - * Check that the outter source address is an expected one, if we know - * what it's supposed to be. This avoids source address spoofing. - */ - if ((tdbp->tdb_src.sin.sin_addr.s_addr != INADDR_ANY) && - (ipo->ip_src.s_addr != tdbp->tdb_src.sin.sin_addr.s_addr)) - { - DPRINTF(("ah_input(): source address %s doesn't correspond to expected source %s, SA %s/%08x\n", inet_ntoa4(ipo->ip_src), ipsp_address(tdbp->tdb_src), ipsp_address(tdbp->tdb_dst), ntohl(tdbp->tdb_spi))); - m_free(m); - ahstat.ahs_hdrops++; - return; - } - - if (ipo->ip_p == IPPROTO_TCP || ipo->ip_p == IPPROTO_UDP) - { - struct tdb_ident *tdbi = NULL; - - if (tdbp->tdb_bind_out) - { - tdbi = m->m_pkthdr.tdbi; - if (!(m->m_flags & M_PKTHDR)) - { - DPRINTF(("ah_input(): mbuf is not a packet header!\n")); - } - MALLOC(tdbi, struct tdb_ident *, sizeof(struct tdb_ident), - M_TEMP, M_NOWAIT); - - if (!tdbi) - goto no_mem; - - tdbi->spi = tdbp->tdb_bind_out->tdb_spi; - tdbi->dst = tdbp->tdb_bind_out->tdb_dst; - tdbi->proto = tdbp->tdb_bind_out->tdb_sproto; - } - - no_mem: - m->m_pkthdr.tdbi = tdbi; - } else - m->m_pkthdr.tdbi = NULL; - - /* Packet is authentic */ - m->m_flags |= M_AUTH; - -#if NBPFILTER > 0 - if (m->m_pkthdr.rcvif->if_bpf) - { - /* - * We need to prepend the address family as - * a four byte field. Cons up a dummy header - * to pacify bpf. This is safe because bpf - * will only read from the mbuf (i.e., it won't - * try to free it or keep a pointer a to it). - */ - struct mbuf m0; - struct enchdr hdr; - - hdr.af = AF_INET; - hdr.spi = tdbp->tdb_spi; - hdr.flags = m->m_flags & (M_AUTH|M_CONF); - - m0.m_next = m; - m0.m_len = ENC_HDRLEN; - m0.m_data = (char *) &hdr; - - bpf_mtap(m->m_pkthdr.rcvif->if_bpf, &m0); - } -#endif - - splx(s); - - /* - * Interface pointer is already in first mbuf; chop off the - * `outer' header and reschedule. - */ - - ifq = &ipintrq; - - s = splimp(); /* isn't it already? */ - if (IF_QFULL(ifq)) - { - IF_DROP(ifq); - if (m->m_pkthdr.tdbi) - free(m->m_pkthdr.tdbi, M_TEMP); - m_freem(m); - ahstat.ahs_qfull++; - splx(s); - DPRINTF(("ah_input(): dropped packet because of full IP queue\n")); - return; - } - - IF_ENQUEUE(ifq, m); - schednetisr(NETISR_IP); - splx(s); - return; -} - -int -ah_sysctl(name, namelen, oldp, oldlenp, newp, newlen) - int *name; - u_int namelen; - void *oldp; - size_t *oldlenp; - void *newp; - size_t newlen; -{ - /* All sysctl names at this level are terminal. */ - if (namelen != 1) - return (ENOTDIR); - - switch (name[0]) { - case AHCTL_ENABLE: - return (sysctl_int(oldp, oldlenp, newp, newlen, &ah_enable)); - default: - return (ENOPROTOOPT); - } - /* NOTREACHED */ -} diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c deleted file mode 100644 index bea5f7fb206..00000000000 --- a/sys/netinet/ip_esp.c +++ /dev/null @@ -1,529 +0,0 @@ -/* $OpenBSD: ip_esp.c,v 1.29 1999/12/09 03:46:03 angelos Exp $ */ - -/* - * The authors of this code are John Ioannidis (ji@tla.org), - * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). - * - * This code was written by John Ioannidis for BSD/OS in Athens, Greece, - * in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis. - * - * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis - * and Niels Provos. - * - * Additional features in 1999 by Angelos D. Keromytis. - * - * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, - * Angelos D. Keromytis and Niels Provos. - * - * Permission to use, copy, and modify this software without fee - * is hereby granted, provided that this entire notice is included in - * all copies of any software which is or includes a copy or - * modification of this software. - * You may use this code under the GNU public license if you so wish. Please - * contribute changes back to the authors under this freer than GPL license - * so that we may further the use of strong encryption without limitations to - * all. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/domain.h> -#include <sys/protosw.h> -#include <sys/socket.h> -#include <sys/sysctl.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/kernel.h> -#include <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> -#include <net/bpf.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> - -#ifdef INET6 -#include <netinet6/in6.h> -#include <netinet6/ip6.h> -#endif/ * INET6 */ - -#include <sys/socketvar.h> -#include <net/raw_cb.h> - -#include <netinet/ip_icmp.h> -#include <netinet/ip_ipsp.h> -#include <netinet/ip_esp.h> - -#include <net/if_enc.h> - -#include "bpfilter.h" - -extern struct enc_softc encif[]; - -#ifdef ENCDEBUG -#define DPRINTF(x) if (encdebug) printf x -#else -#define DPRINTF(x) -#endif - -#ifndef offsetof -#define offsetof(s, e) ((int)&((s *)0)->e) -#endif - -int esp_enable = 0; - -/* - * esp_common_input() gets called when we receive an ESP-protected packet - * in IPv4 or IPv6. - */ - -static void -esp_common_input(struct mbuf *m, int skip, int protoff, int af) -{ - union sockaddr_union sunion; - struct ifqueue *ifq = NULL; - struct tdb *tdbp; - u_int32_t spi; - u_int8_t prot; - int s; - -#ifdef INET - struct ip *ip, ipn; -#endif /* INET */ - -#ifdef INET6 - struct ip6_hdr *ip6, ip6n; -#endif /* INET6 */ - - espstat.esps_input++; - - if (!esp_enable) - { - m_freem(m); - espstat.esps_pdrops++; - return; - } - - /* Retrieve the SPI from the ESP header */ - m_copydata(m, skip , sizeof(u_int32_t), (unsigned char *) &spi); - - /* - * Find tunnel control block and (indirectly) call the appropriate - * kernel crypto routine. The resulting mbuf chain is a valid - * IP packet ready to go through input processing. - */ - - bzero(&sunion, sizeof(sunion)); - sunion.sin.sin_family = af; - -#ifdef INET - if (af == AF_INET) - { - sunion.sin.sin_len = sizeof(struct sockaddr_in); - m_copydata(m, offsetof(struct ip, ip_dst), sizeof(struct in_addr), - (unsigned char *) &(sunion.sin.sin_addr)); - } -#endif /* INET */ - -#ifdef INET6 - if (af == AF_INET6) - { - sunion.sin6.sin6_len = sizeof(struct sockaddr_in6); - m_copydata(m, offsetof(struct ip6_hdr, ip6_dst), - sizeof(struct in6_addr), - (unsigned char *) &(sunion.sin6.sin6_addr)); - } -#endif /* INET6 */ - - s = spltdb(); - tdbp = gettdb(spi, &sunion, IPPROTO_ESP); - if (tdbp == NULL) - { - DPRINTF(("esp_input(): could not find SA for packet to %s, spi %08x\n", ipsp_address(sunion), ntohl(spi))); - m_freem(m); - espstat.esps_notdb++; - return; - } - - if (tdbp->tdb_flags & TDBF_INVALID) - { - DPRINTF(("esp_input(): attempted to use invalid SA %s/%08x\n", - ipsp_address(sunion), ntohl(spi))); - m_freem(m); - espstat.esps_invalid++; - return; - } - - if (tdbp->tdb_xform == NULL) - { - DPRINTF(("esp_input(): attempted to use uninitialized SA %s/%08x\n", - ipsp_address(sunion), ntohl(spi))); - m_freem(m); - espstat.esps_noxform++; - return; - } - - if (tdbp->tdb_interface) - m->m_pkthdr.rcvif = (struct ifnet *) tdbp->tdb_interface; - else - m->m_pkthdr.rcvif = &encif[0].sc_if; - - /* Register first use, setup expiration timer */ - if (tdbp->tdb_first_use == 0) - { - tdbp->tdb_first_use = time.tv_sec; - tdb_expiration(tdbp, TDBEXP_TIMEOUT); - } - - m = (*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff); - if (m == NULL) - { - /* esp_xxx_input() will print a message if necessary */ - espstat.esps_badkcr++; - return; - } - -#ifdef INET - /* Fix IPv4 header */ - if (af == AF_INET) - { - if ((m = m_pullup(m, skip)) == 0) - { - DPRINTF(("esp_input(): processing failed for SA %s/%08x\n", - ipsp_address(tdbp->tdb_dst), ntohl(spi))); - espstat.esps_hdrops++; - return; - } - - ip = mtod(m, struct ip *); - ip->ip_len = htons(m->m_pkthdr.len); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, ip->ip_hl << 2); - prot = ip->ip_p; - - /* IP-in-IP encapsulation */ - if (prot == IPPROTO_IPIP) - { - /* ipn will now contain the inner IPv4 header */ - m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), (caddr_t) &ipn); - - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if (((tdbp->tdb_proxy.sa.sa_family == AF_INET) && - (tdbp->tdb_proxy.sin.sin_addr.s_addr != INADDR_ANY) && - (ipn.ip_src.s_addr != tdbp->tdb_proxy.sin.sin_addr.s_addr)) || - ((tdbp->tdb_proxy.sa.sa_family != AF_INET6) && - (tdbp->tdb_proxy.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): inner source address %s doesn't correspond to expected proxy source %s, SA %s/%08x\n", inet_ntoa4(ipn.ip_src), ipsp_address(tdbp->tdb_proxy), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } - -#if INET6 - /* IPv6-in-IP encapsulation */ - if (prot == IPPROTO_IPV6) - { - /* ip6n will now contain the inner IPv6 header */ - m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), - (caddr_t) &ip6n); - - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if (((tdbp->tdb_proxy.sa.sa_family == AF_INET6) && - !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) && - !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, - &tdbp->tdb_proxy.sin6.sin6_addr)) || - ((tdbp->tdb_proxy.sa.sa_family != AF_INET6) && - (tdbp->tdb_proxy.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): inner source address %s doesn't correspond to expected proxy source %s, SA %s/%08x\n", inet6_ntoa4(ip6n.ip6_src), ipsp_address(tdbp->tdb_proxy), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } -#endif /* INET6 */ - - /* - * Check that the source address is an expected one, if we know what - * it's supposed to be. This avoids source address spoofing. - */ - if (((tdbp->tdb_src.sa.sa_family == AF_INET) && - (tdbp->tdb_src.sin.sin_addr.s_addr != INADDR_ANY) && - (ip->ip_src.s_addr != tdbp->tdb_src.sin.sin_addr.s_addr)) || - ((tdbp->tdb_src.sa.sa_family != AF_INET) && - (tdbp->tdb_src.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): source address %s doesn't correspond to expected source %s, SA %s/%08x\n", inet_ntoa4(ip->ip_src), ipsp_address(tdbp->tdb_src), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } -#endif /* INET */ - -#ifdef INET6 - /* Fix IPv6 header */ - if (af == INET6) - { - if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) - { - DPRINTF(("esp_input(): processing failed for SA %s/%08x\n", - ipsp_address(tdbp->tdb_dst), ntohl(spi))); - espstat.esps_hdrops++; - return; - } - - ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_plen = htons(m->m_pkthdr.len); - - /* Save protocol */ - m_copydata(m, protoff, 1, (unsigned char *) &prot); - -#ifdef INET - /* IP-in-IP encapsulation */ - if (prot == IPPROTO_IPIP) - { - /* ipn will now contain the inner IPv4 header */ - m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn); - - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if (((tdbp->tdb_proxy.sa.sa_family == AF_INET) && - (tdbp->tdb_proxy.sin.sin_addr.s_addr != INADDR_ANY) && - (ipn.ip_src.s_addr != tdbp->tdb_proxy.sin.sin_addr.s_addr)) || - ((tdbp->tdb_proxy.sa.sa_family != AF_INET) && - (tdbp->tdb_proxy.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): inner source address %s doesn't correspond to expected proxy source %s, SA %s/%08x\n", inet_ntoa4(ipn.ip_src), ipsp_address(tdbp->tdb_proxy), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } -#endif /* INET */ - - /* IPv6-in-IP encapsulation */ - if (prot == IPPROTO_IPV6) - { - /* ip6n will now contain the inner IPv6 header */ - m_copydata(m, skip, sizeof(struct ip6_hdr), (caddr_t) &ip6n); - - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if (((tdbp->tdb_proxy.sa.sa_family == AF_INET6) && - !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) && - !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, - &tdbp->tdb_proxy.sin6.sin6_addr)) || - ((tdbp->tdb_proxy.sa.sa_family != AF_INET6) && - (tdbp->tdb_proxy.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): inner source address %s doesn't correspond to expected proxy source %s, SA %s/%08x\n", inet6_ntoa4(ip6n.ip6_src), ipsp_address(tdbp->tdb_proxy), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } - - /* - * Check that the source address is an expected one, if we know what - * it's supposed to be. This avoids source address spoofing. - */ - if (((tdbp->tdb_src.sa.sa_family == AF_INET6) && - !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_src.sin6.sin6_addr) && - !IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, - &tdbp->tdb_src.sin6.sin6_addr)) || - ((tdbp->tdb_src.sa.sa_family != AF_INET6) && - (tdbp->tdb_src.sa.sa_family != 0))) - { - DPRINTF(("esp_input(): source address %s doesn't correspond to expected source %s, SA %s/%08x\n", inet6_ntoa4(ip6->ip6_src), ipsp_address(tdbp->tdb_src), ipsp_address(tdbp->tdb_dst), ntohl(spi))); - m_free(m); - espstat.esps_hdrops++; - return; - } - } -#endif /* INET6 */ - - if (prot == IPPROTO_TCP || prot == IPPROTO_UDP) - { - struct tdb_ident *tdbi = NULL; - - if (tdbp->tdb_bind_out) - { - tdbi = m->m_pkthdr.tdbi; - if (!(m->m_flags & M_PKTHDR)) - DPRINTF(("esp_input(): mbuf is not a packet header!\n")); - - MALLOC(tdbi, struct tdb_ident *, sizeof(struct tdb_ident), - M_TEMP, M_NOWAIT); - - if (tdbi == NULL) - m->m_pkthdr.tdbi = NULL; - else - { - tdbi->spi = tdbp->tdb_bind_out->tdb_spi; - tdbi->dst = tdbp->tdb_bind_out->tdb_dst; - tdbi->proto = tdbp->tdb_bind_out->tdb_sproto; - } - } - } - else - m->m_pkthdr.tdbi = NULL; - - /* Packet is confidental */ - m->m_flags |= M_CONF; - -#if NBPFILTER > 0 - if (m->m_pkthdr.rcvif->if_bpf) - { - /* - * We need to prepend the address family as - * a four byte field. Cons up a dummy header - * to pacify bpf. This is safe because bpf - * will only read from the mbuf (i.e., it won't - * try to free it or keep a pointer a to it). - */ - struct mbuf m0; - struct enchdr hdr; - - hdr.af = af; - hdr.spi = tdbp->tdb_spi; - hdr.flags = m->m_flags & (M_AUTH|M_CONF); - - m0.m_next = m; - m0.m_len = ENC_HDRLEN; - m0.m_data = (char *) &hdr; - - bpf_mtap(m->m_pkthdr.rcvif->if_bpf, &m0); - } -#endif - splx(s); - - /* - * Interface pointer is already in first mbuf; chop off the - * `outer' header and reschedule. - */ - -#ifdef INET - if (af == AF_INET) - ifq = &ipintrq; -#endif /* INET */ - -#ifdef INET6 - if (af == AF_INET6) - ifq = &ip6intrq; -#endif /* INET6 */ - - s = splimp(); /* isn't it already? */ - if (IF_QFULL(ifq)) - { - IF_DROP(ifq); - if (m->m_pkthdr.tdbi) - free(m->m_pkthdr.tdbi, M_TEMP); - m_freem(m); - espstat.esps_qfull++; - splx(s); - DPRINTF(("esp_input(): dropped packet because of full IP queue\n")); - return; - } - - IF_ENQUEUE(ifq, m); - -#ifdef INET - if (af == AF_INET) - schednetisr(NETISR_IP); -#endif /* INET */ - -#ifdef INET6 - if (af == AF_INET6) - schednetisr(NETISR_IPV6); -#endif /* INET6 */ - - splx(s); - return; -} - -int -esp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) - int *name; - u_int namelen; - void *oldp; - size_t *oldlenp; - void *newp; - size_t newlen; -{ - /* All sysctl names at this level are terminal. */ - if (namelen != 1) - return (ENOTDIR); - - switch (name[0]) { - case ESPCTL_ENABLE: - return (sysctl_int(oldp, oldlenp, newp, newlen, &esp_enable)); - default: - return (ENOPROTOOPT); - } - /* NOTREACHED */ -} - -#ifdef INET -/* IPv4 ESP wrapper */ -void -esp_input(struct mbuf *m, ...) -{ - int skip; - - va_list ap; - va_start(ap, m); - skip = va_arg(ap, int); - va_end(ap); - - esp_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET); -} -#endif /* INET */ - -#ifdef INET6 -/* IPv6 ESP wrapper */ -void -esp6_input(struct mbuf *m, ...) -{ - int skip, protoff; - - va_list ap; - - va_start(ap, m); - skip = va_arg(ap, int); - protoff = va_arg(ap, int); - va_end(ap); - - esp_common_input(m, skip, protoff, AF_INET6); -} -#endif /* INET6 */ |