summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ah_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/ah_output.c')
-rw-r--r--sys/netinet6/ah_output.c117
1 files changed, 72 insertions, 45 deletions
diff --git a/sys/netinet6/ah_output.c b/sys/netinet6/ah_output.c
index c33dfe8..477c589 100644
--- a/sys/netinet6/ah_output.c
+++ b/sys/netinet6/ah_output.c
@@ -1,3 +1,6 @@
+/* $FreeBSD$ */
+/* $KAME: ah_output.c,v 1.22 2000/07/03 13:23:28 itojun Exp $ */
+
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
@@ -25,18 +28,14 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
* RFC1826/2402 authentication header.
*/
+#include "opt_inet.h"
#include "opt_inet6.h"
-#include "opt_ipsec.h"
-
-#define ahdprintf(x) printf x
#include <sys/param.h>
#include <sys/systm.h>
@@ -57,27 +56,23 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_var.h>
-#include <netinet/in_pcb.h>
#ifdef INET6
-#include <netinet6/ip6.h>
+#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
-#include <netinet6/icmp6.h>
+#include <netinet/icmp6.h>
#endif
#include <netinet6/ipsec.h>
-#include <netinet6/ah.h>
#ifdef INET6
#include <netinet6/ipsec6.h>
+#endif
+#include <netinet6/ah.h>
+#ifdef INET6
#include <netinet6/ah6.h>
#endif
#include <netkey/key.h>
#include <netkey/keydb.h>
-#ifdef IPSEC_DEBUG
-#include <netkey/key_debug.h>
-#else
-#define KEYDEBUG(lev,arg)
-#endif
#include <net/net_osdep.h>
@@ -103,15 +98,15 @@ ah_hdrsiz(isr)
panic("unsupported mode passed to ah_hdrsiz");
if (isr->sav == NULL)
- goto contrive;
+ goto estimate;
if (isr->sav->state != SADB_SASTATE_MATURE
&& isr->sav->state != SADB_SASTATE_DYING)
- goto contrive;
+ goto estimate;
/* we need transport mode AH. */
algo = &ah_algorithms[isr->sav->alg_auth];
if (!algo)
- goto contrive;
+ goto estimate;
/*
* XXX
@@ -128,7 +123,7 @@ ah_hdrsiz(isr)
return hdrsiz;
- contrive:
+ estimate:
/* ASSUMING:
* sizeof(struct newah) > sizeof(struct ah).
* 16 = (16 + 3) & ~(4 - 1).
@@ -166,12 +161,11 @@ ah4_output(m, isr)
struct ip *ip;
ip = mtod(m, struct ip *);
- printf("ah4_output: internal error: "
- "sav->replay is null: "
- "%x->%x, SPI=%u\n",
+ ipseclog((LOG_DEBUG, "ah4_output: internal error: "
+ "sav->replay is null: %x->%x, SPI=%u\n",
(u_int32_t)ntohl(ip->ip_src.s_addr),
(u_int32_t)ntohl(ip->ip_dst.s_addr),
- (u_int32_t)ntohl(sav->spi));
+ (u_int32_t)ntohl(sav->spi)));
ipsecstat.out_inval++;
m_freem(m);
return EINVAL;
@@ -209,7 +203,8 @@ ah4_output(m, isr)
struct mbuf *n;
MGET(n, M_DONTWAIT, MT_DATA);
if (!n) {
- printf("ENOBUFS in ah4_output %d\n", __LINE__);
+ ipseclog((LOG_DEBUG, "ENOBUFS in ah4_output %d\n",
+ __LINE__));
m_freem(m);
return ENOBUFS;
}
@@ -249,6 +244,17 @@ ah4_output(m, isr)
ahdr->ah_nxt = ip->ip_p;
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
+ if (sav->replay->count == ~0) {
+ if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
+ /* XXX Is it noisy ? */
+ ipseclog((LOG_WARNING,
+ "replay counter overflowed. %s\n",
+ ipsec_logsastr(sav)));
+ ipsecstat.out_inval++;
+ m_freem(m);
+ return EINVAL;
+ }
+ }
sav->replay->count++;
/*
* XXX sequence number must not be cycled, if the SA is
@@ -265,7 +271,7 @@ ah4_output(m, isr)
if (ahlen < (IP_MAXPACKET - ntohs(ip->ip_len)))
ip->ip_len = htons(ntohs(ip->ip_len) + ahlen);
else {
- printf("IPv4 AH output: size exceeds limit\n");
+ ipseclog((LOG_ERR, "IPv4 AH output: size exceeds limit\n"));
ipsecstat.out_inval++;
m_freem(m);
return EMSGSIZE;
@@ -288,9 +294,11 @@ ah4_output(m, isr)
* calcurate the checksum, based on security association
* and the algorithm specified.
*/
- error = ah4_calccksum(m, (caddr_t)ahsumpos, algo, sav);
+ error = ah4_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav);
if (error) {
- printf("error after ah4_calccksum, called from ah4_output");
+ ipseclog((LOG_ERR,
+ "error after ah4_calccksum, called from ah4_output"));
+ m_freem(m);
m = NULL;
ipsecstat.out_inval++;
return error;
@@ -314,7 +322,7 @@ ah_hdrlen(sav)
{
struct ah_algorithm *algo;
int plen, ahlen;
-
+
algo = &ah_algorithms[sav->alg_auth];
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
@@ -352,7 +360,7 @@ ah6_output(m, nexthdrp, md, isr)
struct ip6_hdr *ip6;
if (m->m_len < sizeof(struct ip6_hdr)) {
- printf("ah6_output: first mbuf too short\n");
+ ipseclog((LOG_DEBUG, "ah6_output: first mbuf too short\n"));
m_freem(m);
return EINVAL;
}
@@ -364,7 +372,7 @@ ah6_output(m, nexthdrp, md, isr)
for (mprev = m; mprev && mprev->m_next != md; mprev = mprev->m_next)
;
if (!mprev || mprev->m_next != md) {
- printf("ah6_output: md is not in chain\n");
+ ipseclog((LOG_DEBUG, "ah6_output: md is not in chain\n"));
m_freem(m);
return EINVAL;
}
@@ -389,7 +397,8 @@ ah6_output(m, nexthdrp, md, isr)
/* fix plen */
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) > IPV6_MAXPACKET) {
- printf("ip6_output: AH with IPv6 jumbogram is not supported\n");
+ ipseclog((LOG_ERR,
+ "ip6_output: AH with IPv6 jumbogram is not supported\n"));
m_freem(m);
return EINVAL;
}
@@ -397,11 +406,12 @@ ah6_output(m, nexthdrp, md, isr)
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
- printf("ah6_output: internal error: "
+ ipseclog((LOG_DEBUG, "ah6_output: internal error: "
"sav->replay is null: SPI=%u\n",
- (u_int32_t)ntohl(sav->spi));
+ (u_int32_t)ntohl(sav->spi)));
ipsec6stat.out_inval++;
- return 0; /* no change at all */
+ m_freem(m);
+ return EINVAL;
}
algo = &ah_algorithms[sav->alg_auth];
@@ -431,6 +441,17 @@ ah6_output(m, nexthdrp, md, isr)
ahdr->ah_len = (plen >> 2) + 1; /* plus one for seq# */
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
+ if (sav->replay->count == ~0) {
+ if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
+ /* XXX Is it noisy ? */
+ ipseclog((LOG_WARNING,
+ "replay counter overflowed. %s\n",
+ ipsec_logsastr(sav)));
+ ipsecstat.out_inval++;
+ m_freem(m);
+ return EINVAL;
+ }
+ }
sav->replay->count++;
/*
* XXX sequence number must not be cycled, if the SA is
@@ -444,13 +465,15 @@ ah6_output(m, nexthdrp, md, isr)
* calcurate the checksum, based on security association
* and the algorithm specified.
*/
- error = ah6_calccksum(m, (caddr_t)ahsumpos, algo, sav);
- if (error)
+ error = ah6_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav);
+ if (error) {
ipsec6stat.out_inval++;
- else
+ m_freem(m);
+ } else {
ipsec6stat.out_success++;
+ key_sa_recordxfer(sav, m);
+ }
ipsec6stat.out_ahhist[sav->alg_auth]++;
- key_sa_recordxfer(sav, m);
return(error);
}
@@ -480,7 +503,8 @@ ah4_finaldst(m)
hlen = (ip->ip_hl << 2);
if (m->m_len < hlen) {
- printf("ah4_finaldst: parameter mbuf wrong (not pulled up)\n");
+ ipseclog((LOG_DEBUG,
+ "ah4_finaldst: parameter mbuf wrong (not pulled up)\n"));
return NULL;
}
@@ -489,7 +513,8 @@ ah4_finaldst(m)
optlen = hlen - sizeof(struct ip);
if (optlen < 0) {
- printf("ah4_finaldst: wrong optlen %d\n", optlen);
+ ipseclog((LOG_DEBUG, "ah4_finaldst: wrong optlen %d\n",
+ optlen));
return NULL;
}
@@ -507,9 +532,10 @@ ah4_finaldst(m)
case IPOPT_SSRR:
if (q[i + IPOPT_OLEN] <= 0
|| optlen - i < q[i + IPOPT_OLEN]) {
- printf("ip_finaldst: invalid IP option "
- "(code=%02x len=%02x)\n",
- q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]);
+ ipseclog((LOG_ERR,
+ "ip_finaldst: invalid IP option "
+ "(code=%02x len=%02x)\n",
+ q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]));
return NULL;
}
i += q[i + IPOPT_OLEN] - sizeof(struct in_addr);
@@ -517,9 +543,10 @@ ah4_finaldst(m)
default:
if (q[i + IPOPT_OLEN] <= 0
|| optlen - i < q[i + IPOPT_OLEN]) {
- printf("ip_finaldst: invalid IP option "
- "(code=%02x len=%02x)\n",
- q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]);
+ ipseclog((LOG_ERR,
+ "ip_finaldst: invalid IP option "
+ "(code=%02x len=%02x)\n",
+ q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]));
return NULL;
}
i += q[i + IPOPT_OLEN];
OpenPOWER on IntegriCloud