summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_ah_new.c
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>1999-02-24 22:33:08 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>1999-02-24 22:33:08 +0000
commitbc6ad109752ee01f946571f9488d7335d751b7fe (patch)
tree51a5f44fa5bf81542dfc5c8ad510f1f8cf4a6691 /sys/netinet/ip_ah_new.c
parent689ba6c5dcae1e6d1086d01cfc27fd19a8e11b03 (diff)
Remove encap.h include; saner debugging printfs; fix buglets; work with
pfkeyv2.
Diffstat (limited to 'sys/netinet/ip_ah_new.c')
-rw-r--r--sys/netinet/ip_ah_new.c455
1 files changed, 177 insertions, 278 deletions
diff --git a/sys/netinet/ip_ah_new.c b/sys/netinet/ip_ah_new.c
index a6061bfc4d7..ad6cfc3463e 100644
--- a/sys/netinet/ip_ah_new.c
+++ b/sys/netinet/ip_ah_new.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah_new.c,v 1.21 1999/01/11 22:52:09 deraadt Exp $ */
+/* $OpenBSD: ip_ah_new.c,v 1.22 1999/02/24 22:32:59 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -65,10 +65,9 @@
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
-#include <net/encap.h>
-
#include <netinet/ip_ipsp.h>
#include <netinet/ip_ah.h>
+#include <net/pfkeyv2.h>
#ifdef ENCDEBUG
#define DPRINTF(x) if (encdebug) printf x
@@ -76,25 +75,23 @@
#define DPRINTF(x)
#endif
-extern void encap_sendnotify(int, struct tdb *, void *);
-
-struct ah_hash ah_new_hash[] = {
- { ALG_AUTH_MD5, "HMAC-MD5-96",
- AH_MD5_ALEN,
+struct auth_hash ah_new_hash[] = {
+ { SADB_AALG_MD5HMAC96, "HMAC-MD5-96",
+ MD5HMAC96_KEYSIZE, AH_MD5_ALEN,
sizeof(MD5_CTX),
(void (*)(void *)) MD5Init,
(void (*)(void *, u_int8_t *, u_int16_t)) MD5Update,
(void (*)(u_int8_t *, void *)) MD5Final
},
- { ALG_AUTH_SHA1, "HMAC-SHA1-96",
- AH_SHA1_ALEN,
+ { SADB_AALG_SHA1HMAC96, "HMAC-SHA1-96",
+ SHA1HMAC96_KEYSIZE, AH_SHA1_ALEN,
sizeof(SHA1_CTX),
(void (*)(void *)) SHA1Init,
(void (*)(void *, u_int8_t *, u_int16_t)) SHA1Update,
(void (*)(u_int8_t *, void *)) SHA1Final
},
- { ALG_AUTH_RMD160, "HMAC-RIPEMD-160-96",
- AH_RMD160_ALEN,
+ { SADB_AALG_X_RIPEMD160HMAC96, "HMAC-RIPEMD-160-96",
+ RIPEMD160HMAC96_KEYSIZE, AH_RMD160_ALEN,
sizeof(RMD160_CTX),
(void (*)(void *)) RMD160Init,
(void (*)(void *, u_int8_t *, u_int16_t)) RMD160Update,
@@ -110,127 +107,66 @@ struct ah_hash ah_new_hash[] = {
int
ah_new_attach()
{
- DPRINTF(("ah_new_attach(): setting up\n"));
return 0;
}
/*
- * ah_new_init() is called when an SPI is being set up. It interprets the
- * encap_msghdr present in m, and sets up the transformation data.
+ * ah_new_init() is called when an SPI is being set up.
*/
int
-ah_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m)
+ah_new_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
{
- struct ah_new_xdata *xd;
- struct ah_new_xencap txd;
- struct encap_msghdr *em;
- struct ah_hash *thash;
- caddr_t buffer = NULL;
- int blocklen, i;
-
- if (m->m_len < ENCAP_MSG_FIXED_LEN)
- {
- if ((m = m_pullup(m, ENCAP_MSG_FIXED_LEN)) == NULL)
- {
- DPRINTF(("ah_new_init(): m_pullup failed\n"));
- return ENOBUFS;
- }
- }
+ struct auth_hash *thash = NULL;
+ int i;
- em = mtod(m, struct encap_msghdr *);
- if (em->em_msglen - EMT_SETSPI_FLEN <= AH_NEW_XENCAP_LEN)
- {
- DPRINTF(("ah_new_init() initialization failed\n"));
- return EINVAL;
- }
-
- /* Just copy the standard fields */
- m_copydata(m, EMT_SETSPI_FLEN, AH_NEW_XENCAP_LEN, (caddr_t) &txd);
+ for (i = sizeof(ah_new_hash) / sizeof(struct auth_hash) - 1;
+ i >= 0; i--)
+ if (ii->ii_authalg == ah_new_hash[i].type)
+ break;
- /* Check whether the hash algorithm is supported */
- for (i = sizeof(ah_new_hash) / sizeof(struct ah_hash) - 1; i >= 0; i--)
- if (txd.amx_hash_algorithm == ah_new_hash[i].type)
- break;
if (i < 0)
{
- DPRINTF(("ah_new_init(): unsupported authentication algorithm %d specified\n", txd.amx_hash_algorithm));
+ DPRINTF(("ah_new_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
return EINVAL;
}
- DPRINTF(("ah_new_init(): initalized TDB with hash algorithm %d: %s\n",
- txd.amx_hash_algorithm, ah_new_hash[i].name));
+
thash = &ah_new_hash[i];
- blocklen = HMAC_BLOCK_LEN;
- if (txd.amx_keylen + EMT_SETSPI_FLEN + AH_NEW_XENCAP_LEN != em->em_msglen)
+ if (ii->ii_authkeylen != thash->keysize)
{
- DPRINTF(("ah_new_init(): message length (%d) doesn't match\n",
- em->em_msglen));
+ DPRINTF(("ah_new_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
return EINVAL;
}
- MALLOC(tdbp->tdb_xdata, caddr_t, sizeof(struct ah_new_xdata),
- M_XDATA, M_WAITOK);
- if (tdbp->tdb_xdata == NULL)
- {
- DPRINTF(("ah_new_init(): MALLOC failed\n"));
- return ENOBUFS;
- }
-
- MALLOC(buffer, caddr_t,
- (txd.amx_keylen < blocklen ? blocklen : txd.amx_keylen),
- M_TEMP, M_WAITOK);
- if (buffer == NULL)
- {
- DPRINTF(("ah_new_init(): MALLOC failed\n"));
- free(tdbp->tdb_xdata, M_XDATA);
- return ENOBUFS;
- }
-
- bzero(buffer, (txd.amx_keylen < blocklen ? blocklen : txd.amx_keylen));
- bzero(tdbp->tdb_xdata, sizeof(struct ah_new_xdata));
- xd = (struct ah_new_xdata *) tdbp->tdb_xdata;
-
- /* Copy the key to the buffer */
- m_copydata(m, EMT_SETSPI_FLEN + AH_NEW_XENCAP_LEN, txd.amx_keylen, buffer);
-
- xd->amx_hash = thash;
- /* Shorten the key if necessary */
- if (txd.amx_keylen > blocklen)
- {
- xd->amx_hash->Init(&(xd->amx_ictx));
- xd->amx_hash->Update(&(xd->amx_ictx), buffer, txd.amx_keylen);
- bzero(buffer,
- (txd.amx_keylen < blocklen ? blocklen : txd.amx_keylen));
- xd->amx_hash->Final(buffer, &(xd->amx_ictx));
- }
-
- /* Pointer to the transform */
tdbp->tdb_xform = xsp;
+ tdbp->tdb_authalgxform = thash;
+ tdbp->tdb_bitmap = 0;
+ tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
- /* Pass name of auth algorithm for kernfs */
- tdbp->tdb_authname = xd->amx_hash->name;
-
- xd->amx_hash_algorithm = txd.amx_hash_algorithm;
- xd->amx_rpl = AH_HMAC_INITIAL_RPL;
- xd->amx_wnd = txd.amx_wnd;
- xd->amx_bitmap = 0;
+ DPRINTF(("ah_new_init(): initialized TDB with hash algorithm %s\n",
+ thash->name));
/* Precompute the I and O pads of the HMAC */
- for (i = 0; i < blocklen; i++)
- buffer[i] ^= HMAC_IPAD_VAL;
-
- xd->amx_hash->Init(&(xd->amx_ictx));
- xd->amx_hash->Update(&(xd->amx_ictx), buffer, blocklen);
-
- for (i = 0; i < blocklen; i++)
- buffer[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
-
- xd->amx_hash->Init(&(xd->amx_octx));
- xd->amx_hash->Update(&(xd->amx_octx), buffer, blocklen);
-
- bzero(buffer, blocklen); /* paranoid */
- free(buffer, M_TEMP);
+ for (i = 0; i < ii->ii_authkeylen; i++)
+ ii->ii_authkey[i] ^= HMAC_IPAD_VAL;
+
+ MALLOC(tdbp->tdb_ictx, u_int8_t *, thash->ctxsize, M_XDATA, M_WAITOK);
+ bzero(tdbp->tdb_ictx, thash->ctxsize);
+ thash->Init(tdbp->tdb_ictx);
+ thash->Update(tdbp->tdb_ictx, ii->ii_authkey, ii->ii_authkeylen);
+ thash->Update(tdbp->tdb_ictx, hmac_ipad_buffer,
+ HMAC_BLOCK_LEN - ii->ii_authkeylen);
+
+ for (i = 0; i < ii->ii_authkeylen; i++)
+ ii->ii_authkey[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+
+ MALLOC(tdbp->tdb_octx, u_int8_t *, thash->ctxsize, M_XDATA, M_WAITOK);
+ bzero(tdbp->tdb_octx, thash->ctxsize);
+ thash->Init(tdbp->tdb_octx);
+ thash->Update(tdbp->tdb_octx, ii->ii_authkey, ii->ii_authkeylen);
+ thash->Update(tdbp->tdb_octx, hmac_opad_buffer,
+ HMAC_BLOCK_LEN - ii->ii_authkeylen);
bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */
@@ -241,12 +177,18 @@ ah_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m)
int
ah_new_zeroize(struct tdb *tdbp)
{
- DPRINTF(("ah_new_zeroize(): freeing memory\n"));
- if (tdbp->tdb_xdata)
+ if (tdbp->tdb_ictx)
{
- FREE(tdbp->tdb_xdata, M_XDATA);
- tdbp->tdb_xdata = NULL;
+ FREE(tdbp->tdb_ictx, M_XDATA);
+ tdbp->tdb_ictx = NULL;
}
+
+ if (tdbp->tdb_octx)
+ {
+ FREE(tdbp->tdb_octx, M_XDATA);
+ tdbp->tdb_octx = NULL;
+ }
+
return 0;
}
@@ -258,7 +200,7 @@ ah_new_zeroize(struct tdb *tdbp)
struct mbuf *
ah_new_input(struct mbuf *m, struct tdb *tdb)
{
- struct ah_new_xdata *xd;
+ struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
struct ip *ip, ipo;
struct ah_new *aho, *ah;
int ohlen, len, count, off, errc;
@@ -273,9 +215,6 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
u_char buffer[40];
aho = (struct ah_new *) buffer;
-
- xd = (struct ah_new_xdata *) tdb->tdb_xdata;
-
ohlen = sizeof(struct ip) + AH_NEW_FLENGTH;
if (m->m_len < ohlen)
@@ -310,29 +249,57 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
if (ah->ah_hl * sizeof(u_int32_t) != AH_HMAC_HASHLEN + AH_HMAC_RPLENGTH)
{
- DPRINTF(("ah_new_input(): bad authenticator length for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
+ DPRINTF(("ah_new_input(): bad authenticator length for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_badauthl++;
m_freem(m);
return NULL;
}
+ /* Update the counters */
+ tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2) -
+ ah->ah_hl * sizeof(u_int32_t);
+ ahstat.ahs_ibytes += ip->ip_len - (ip->ip_hl << 2) -
+ ah->ah_hl * sizeof(u_int32_t);
+
+ /* Hard expiration */
+ if ((tdb->tdb_flags & TDBF_BYTES) &&
+ (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
+ {
+/* XXX
+ encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
+*/
+ tdb_delete(tdb, 0);
+ m_freem(m);
+ return NULL;
+ }
+
+ /* Notify on expiration */
+ if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
+ (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes))
+ {
+/* XXX
+ encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
+*/
+ tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
+ }
+
/* Replay window checking */
- if (xd->amx_wnd >= 0)
+ if (tdb->tdb_wnd > 0)
{
btsx = ntohl(ah->ah_rpl);
- if ((errc = checkreplaywindow32(btsx, 0, &(xd->amx_rpl), xd->amx_wnd,
- &(xd->amx_bitmap))) != 0)
+ if ((errc = checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), tdb->tdb_wnd,
+ &(tdb->tdb_bitmap))) != 0)
{
switch(errc)
{
case 1:
- DPRINTF(("ah_new_input(): replay counter wrapped for packets from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
+ DPRINTF(("ah_new_input(): replay counter wrapped for packets from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_wrap++;
break;
case 2:
case 3:
- DPRINTF(("ah_new_input(): duplicate packet received, %x->%x spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
+ DPRINTF(("ah_new_input(): duplicate packet received from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_replay++;
break;
}
@@ -351,8 +318,8 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
ipo.ip_ttl = 0;
ipo.ip_sum = 0;
- bcopy(&(xd->amx_ictx), &ctx, xd->amx_hash->ctxsize);
- xd->amx_hash->Update(&ctx, (unsigned char *) &ipo, sizeof(struct ip));
+ bcopy(tdb->tdb_ictx, &ctx, ahx->ctxsize);
+ ahx->Update(&ctx, (unsigned char *) &ipo, sizeof(struct ip));
/* Options */
if ((ip->ip_hl << 2) > sizeof(struct ip))
@@ -362,13 +329,13 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
switch (optval)
{
case IPOPT_EOL:
- xd->amx_hash->Update(&ctx, ipseczeroes, 1);
+ ahx->Update(&ctx, ipseczeroes, 1);
off = ip->ip_hl << 2;
break;
case IPOPT_NOP:
- xd->amx_hash->Update(&ctx, ipseczeroes, 1);
+ ahx->Update(&ctx, ipseczeroes, 1);
off++;
break;
@@ -378,7 +345,7 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
case 134:
optval = ((u_int8_t *) ip)[off + 1];
- xd->amx_hash->Update(&ctx, (u_int8_t *) ip + off, optval);
+ ahx->Update(&ctx, (u_int8_t *) ip + off, optval);
off += optval;
break;
@@ -386,16 +353,15 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
default:
optval = ((u_int8_t *) ip)[off + 1];
- xd->amx_hash->Update(&ctx, ipseczeroes, optval);
+ ahx->Update(&ctx, ipseczeroes, optval);
off += optval;
break;
}
}
- xd->amx_hash->Update(&ctx, (unsigned char *) ah, AH_NEW_FLENGTH -
- AH_HMAC_HASHLEN);
- xd->amx_hash->Update(&ctx, ipseczeroes, AH_HMAC_HASHLEN);
+ ahx->Update(&ctx, (unsigned char *) ah, AH_NEW_FLENGTH - AH_HMAC_HASHLEN);
+ ahx->Update(&ctx, ipseczeroes, AH_HMAC_HASHLEN);
/*
* Code shamelessly stolen from m_copydata
@@ -408,7 +374,7 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
{
if (m0 == 0)
{
- DPRINTF(("ah_new_input(): bad mbuf chain for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
+ DPRINTF(("ah_new_input(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_hdrops++;
m_freem(m);
return NULL;
@@ -425,7 +391,7 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
{
if (m0 == 0)
{
- DPRINTF(("ah_new_input(): bad mbuf chain for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
+ DPRINTF(("ah_new_input(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_hdrops++;
m_freem(m);
return NULL;
@@ -433,36 +399,21 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
count = min(m0->m_len - off, len);
- xd->amx_hash->Update(&ctx, mtod(m0, unsigned char *) + off, count);
+ ahx->Update(&ctx, mtod(m0, unsigned char *) + off, count);
len -= count;
off = 0;
m0 = m0->m_next;
}
- xd->amx_hash->Final((unsigned char *) (aho->ah_data), &ctx);
- bcopy(&(xd->amx_octx), &ctx, xd->amx_hash->ctxsize);
- xd->amx_hash->Update(&ctx, (unsigned char *) (aho->ah_data),
- xd->amx_hash->hashsize);
- xd->amx_hash->Final((unsigned char *) (aho->ah_data), &ctx);
+ ahx->Final((unsigned char *) (aho->ah_data), &ctx);
+ bcopy(tdb->tdb_octx, &ctx, ahx->ctxsize);
+ ahx->Update(&ctx, (unsigned char *) (aho->ah_data), ahx->hashsize);
+ ahx->Final((unsigned char *) (aho->ah_data), &ctx);
if (bcmp(aho->ah_data, ah->ah_data, AH_HMAC_HASHLEN))
{
- DPRINTF(("ah_new_input(): authentication failed for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(ah->ah_spi)));
-#ifdef ENCDEBUG
- if (encdebug)
- {
- printf("Received authenticator: ");
- for (off = 0; off < AH_HMAC_HASHLEN; off++)
- printf("%02x ", ah->ah_data[off]);
- printf("\n");
-
- printf("Computed authenticator: ");
- for (off = 0; off < AH_HMAC_HASHLEN; off++)
- printf("%02x ", aho->ah_data[off]);
- printf("\n");
- }
-#endif
+ DPRINTF(("ah_new_input(): authentication failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(ah->ah_spi)));
ahstat.ahs_badauth++;
m_freem(m);
return NULL;
@@ -492,44 +443,6 @@ ah_new_input(struct mbuf *m, struct tdb *tdb)
ip->ip_sum = in_cksum(m, (ip->ip_hl << 2));
- /* Update the counters */
- tdb->tdb_cur_packets++;
- tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2);
- ahstat.ahs_ibytes += ntohs(ip->ip_len) - (ip->ip_hl << 2);
-
- /* Notify on expiration */
- if (tdb->tdb_flags & TDBF_SOFT_PACKETS)
- {
- if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets)
- {
- encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
- tdb->tdb_flags &= ~TDBF_SOFT_PACKETS;
- }
- else
- if (tdb->tdb_flags & TDBF_SOFT_BYTES)
- if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)
- {
- encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
- tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
- }
- }
-
- if (tdb->tdb_flags & TDBF_PACKETS)
- {
- if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets)
- {
- encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
- tdb_delete(tdb, 0);
- }
- else
- if (tdb->tdb_flags & TDBF_BYTES)
- if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)
- {
- encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
- tdb_delete(tdb, 0);
- }
- }
-
return m;
}
@@ -537,40 +450,37 @@ int
ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
struct mbuf **mp)
{
- struct ah_new_xdata *xd;
+ struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
struct ip *ip, ipo;
struct ah_new aho, *ah;
- register int len, off, count;
- register struct mbuf *m0;
+ register int len, off, count, ilen;
union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
RMD160_CTX rmd160ctx;
} ctx;
- int ilen, ohlen;
u_int8_t optval;
- u_char buffer[AH_ALEN_MAX], opts[40];
+ u_char opts[40];
ahstat.ahs_output++;
m = m_pullup(m, sizeof(struct ip));
if (m == NULL)
{
- DPRINTF(("ah_new_output(): m_pullup() failed, SA %x/%08x\n",
- tdb->tdb_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): m_pullup() failed, SA %s/%08x\n",
+ ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
ahstat.ahs_hdrops++;
return ENOBUFS;
}
ip = mtod(m, struct ip *);
- xd = (struct ah_new_xdata *) tdb->tdb_xdata;
-
if ((ip->ip_hl << 2) > sizeof(struct ip))
{
if ((m = m_pullup(m, ip->ip_hl << 2)) == NULL)
{
- DPRINTF(("ah_new_output(): m_pullup() failed, SA &x/%08x\n",
- tdb->tdb_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): m_pullup() failed, SA %s/%08x\n",
+ ipsp_address(tdb->tdb_dst),
+ ntohl(tdb->tdb_spi)));
ahstat.ahs_hdrops++;
return ENOBUFS;
}
@@ -578,18 +488,44 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
ip = mtod(m, struct ip *);
}
+ /* Update the counters */
+ tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2);
+ ahstat.ahs_obytes += ntohs(ip->ip_len) - (ip->ip_hl << 2);
+
+ /* Hard expiration */
+ if ((tdb->tdb_flags & TDBF_BYTES) &&
+ (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
+ {
+/* XXX
+ encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
+*/
+ tdb_delete(tdb, 0);
+ m_freem(m);
+ return EINVAL;
+ }
+
+ /* Notify on expiration */
+ if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
+ (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes))
+ {
+/* XXX
+ encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
+*/
+ tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
+ }
+
/* Save options */
m_copydata(m, sizeof(struct ip), (ip->ip_hl << 2) - sizeof(struct ip),
(caddr_t) opts);
- DPRINTF(("ah_new_output(): using hash algorithm %s\n", xd->amx_hash->name));
+ DPRINTF(("ah_new_output(): using hash algorithm %s\n", ahx->name));
ilen = ntohs(ip->ip_len);
- ohlen = AH_NEW_FLENGTH;
- if (ohlen + ilen > IP_MAXPACKET) {
- DPRINTF(("ah_new_output(): packet in SA %x/%0x8 got too big\n",
- tdb->tdb_dst, ntohl(tdb->tdb_spi)));
+ if (AH_NEW_FLENGTH + ilen > IP_MAXPACKET)
+ {
+ DPRINTF(("ah_new_output(): packet in SA %s/%08x got too big\n",
+ ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
m_freem(m);
ahstat.ahs_toobig++;
return EMSGSIZE;
@@ -598,7 +534,7 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
ipo.ip_v = IPVERSION;
ipo.ip_hl = ip->ip_hl;
ipo.ip_tos = 0;
- ipo.ip_len = htons(ohlen + ilen);
+ ipo.ip_len = htons(AH_NEW_FLENGTH + ilen);
ipo.ip_id = ip->ip_id;
ipo.ip_off = 0;
ipo.ip_ttl = 0;
@@ -614,19 +550,19 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
aho.ah_rv = 0;
aho.ah_spi = tdb->tdb_spi;
- if (xd->amx_rpl == 0)
+ if (tdb->tdb_rpl == 0)
{
- DPRINTF(("ah_new_output(): SA %x/%0x8 should have expired\n",
- tdb->tdb_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): SA %s/%08x should have expired\n",
+ ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
m_freem(m);
ahstat.ahs_wrap++;
return NULL;
}
- aho.ah_rpl = htonl(xd->amx_rpl++);
+ aho.ah_rpl = htonl(tdb->tdb_rpl++);
- bcopy((caddr_t)&(xd->amx_ictx), (caddr_t)&ctx, xd->amx_hash->ctxsize);
- xd->amx_hash->Update(&ctx, (unsigned char *) &ipo, sizeof(struct ip));
+ bcopy(tdb->tdb_ictx, (caddr_t)&ctx, ahx->ctxsize);
+ ahx->Update(&ctx, (unsigned char *) &ipo, sizeof(struct ip));
/* Options */
if ((ip->ip_hl << 2) > sizeof(struct ip))
@@ -636,13 +572,13 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
switch (optval)
{
case IPOPT_EOL:
- xd->amx_hash->Update(&ctx, ipseczeroes, 1);
+ ahx->Update(&ctx, ipseczeroes, 1);
off = ip->ip_hl << 2;
break;
case IPOPT_NOP:
- xd->amx_hash->Update(&ctx, ipseczeroes, 1);
+ ahx->Update(&ctx, ipseczeroes, 1);
off++;
break;
@@ -652,7 +588,7 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
case 134:
optval = ((u_int8_t *) ip)[off + 1];
- xd->amx_hash->Update(&ctx, (u_int8_t *) ip + off, optval);
+ ahx->Update(&ctx, (u_int8_t *) ip + off, optval);
off += optval;
break;
@@ -660,14 +596,14 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
default:
optval = ((u_int8_t *) ip)[off + 1];
- xd->amx_hash->Update(&ctx, ipseczeroes, optval);
+ ahx->Update(&ctx, ipseczeroes, optval);
off += optval;
break;
}
}
- xd->amx_hash->Update(&ctx, (unsigned char *) &aho, AH_NEW_FLENGTH);
+ ahx->Update(&ctx, (unsigned char *) &aho, AH_NEW_FLENGTH);
off = ip->ip_hl << 2;
@@ -676,44 +612,46 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
*/
len = m->m_pkthdr.len - off;
- m0 = m;
+ *mp = m;
while (len > 0)
{
- if (m0 == 0)
+ if ((*mp) == 0)
{
- DPRINTF(("ah_new_output(): bad mbuf chain for packet from %x to %x, spi %08x\n", ipo.ip_src, ipo.ip_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi)));
ahstat.ahs_hdrops++;
m_freem(m);
return EMSGSIZE;
}
- count = min(m0->m_len - off, len);
+ count = min((*mp)->m_len - off, len);
- xd->amx_hash->Update(&ctx, mtod(m0, unsigned char *) + off, count);
+ ahx->Update(&ctx, mtod(*mp, unsigned char *) + off, count);
len -= count;
off = 0;
- m0 = m0->m_next;
+ *mp = (*mp)->m_next;
}
+ *mp = NULL;
+
ipo.ip_tos = ip->ip_tos;
ipo.ip_id = ip->ip_id;
ipo.ip_off = ip->ip_off;
ipo.ip_ttl = ip->ip_ttl;
/* ipo.ip_len = ntohs(ipo.ip_len); */
- M_PREPEND(m, ohlen, M_DONTWAIT);
+ M_PREPEND(m, AH_NEW_FLENGTH, M_DONTWAIT);
if (m == NULL)
{
- DPRINTF(("ah_new_output(): M_PREPEND() failed for packet from %x to %x, spi %08x\n", ipo.ip_src, ipo.ip_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): M_PREPEND() failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi)));
return ENOBUFS;
}
- m = m_pullup(m, ohlen + (ipo.ip_hl << 2));
+ m = m_pullup(m, AH_NEW_FLENGTH + (ipo.ip_hl << 2));
if (m == NULL)
{
- DPRINTF(("ah_new_output(): m_pullup() failed for packet from %x to %x, spi %08x\n", ipo.ip_src, ipo.ip_dst, ntohl(tdb->tdb_spi)));
+ DPRINTF(("ah_new_output(): m_pullup() failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi)));
ahstat.ahs_hdrops++;
return ENOBUFS;
}
@@ -727,58 +665,19 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
ah->ah_spi = aho.ah_spi;
ah->ah_rpl = aho.ah_rpl;
- xd->amx_hash->Final(buffer, &ctx);
- bcopy(&(xd->amx_octx), &ctx, xd->amx_hash->ctxsize);
- xd->amx_hash->Update(&ctx, buffer, xd->amx_hash->hashsize);
- xd->amx_hash->Final(buffer, &ctx);
-
/* Restore the options */
- m_copyback(m, sizeof(struct ip), (ip->ip_hl << 2) - sizeof(struct ip),
- (caddr_t) opts);
+ bcopy(opts, (caddr_t) (ip + 1), (ip->ip_hl << 2) - sizeof(struct ip));
+
+ /* Finish computing the authenticator */
+ ahx->Final(opts, &ctx);
+ bcopy(tdb->tdb_octx, &ctx, ahx->ctxsize);
+ ahx->Update(&ctx, opts, ahx->hashsize);
+ ahx->Final(opts, &ctx);
/* Copy the authenticator */
- bcopy(buffer, ah->ah_data, AH_HMAC_HASHLEN);
+ bcopy(opts, ah->ah_data, AH_HMAC_HASHLEN);
*mp = m;
- /* Update the counters */
- tdb->tdb_cur_packets++;
- tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) -
- AH_NEW_FLENGTH;
- ahstat.ahs_obytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) - AH_NEW_FLENGTH;
-
- /* Notify on expiration */
- if (tdb->tdb_flags & TDBF_SOFT_PACKETS)
- {
- if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets)
- {
- encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
- tdb->tdb_flags &= ~TDBF_SOFT_PACKETS;
- }
- else
- if (tdb->tdb_flags & TDBF_SOFT_BYTES)
- if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)
- {
- encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL);
- tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
- }
- }
-
- if (tdb->tdb_flags & TDBF_PACKETS)
- {
- if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets)
- {
- encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
- tdb_delete(tdb, 0);
- }
- else
- if (tdb->tdb_flags & TDBF_BYTES)
- if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)
- {
- encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL);
- tdb_delete(tdb, 0);
- }
- }
-
return 0;
}