summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_esp3desmd5.c
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-06-24 12:15:28 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-06-24 12:15:28 +0000
commit6e79d83bde76cc1e88a4d6bf487189769ef11465 (patch)
tree79413ebba8b387f6a704b63bf112acec6759b2cf /sys/netinet/ip_esp3desmd5.c
parentd3aefd9008254bea4ccef33b0b71ee00ec825972 (diff)
handle IP options in AH + allow IP options in outgoing encapsulated packets
+ usage counters for later use with keymanagement processes
Diffstat (limited to 'sys/netinet/ip_esp3desmd5.c')
-rw-r--r--sys/netinet/ip_esp3desmd5.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/sys/netinet/ip_esp3desmd5.c b/sys/netinet/ip_esp3desmd5.c
index 749ca56b7fe..45b4153be6b 100644
--- a/sys/netinet/ip_esp3desmd5.c
+++ b/sys/netinet/ip_esp3desmd5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp3desmd5.c,v 1.7 1997/06/21 00:09:17 deraadt Exp $ */
+/* $OpenBSD: ip_esp3desmd5.c,v 1.8 1997/06/24 12:15:23 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -508,6 +508,11 @@ esp3desmd5_input(struct mbuf *m, struct tdb *tdb)
*ip = ipo;
ip->ip_sum = in_cksum(m, sizeof (struct ip));
+ /* Update the counters */
+ tdb->tdb_packets++;
+ tdb->tdb_bytes += NTOHS(ip->ip_len) - (ip->ip_hl << 2) + padsize +
+ 2 + ESP3DESMD5_ALEN;
+
return m;
}
@@ -521,9 +526,10 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
u_int32_t spi;
struct mbuf *mi, *mo, *ms;
u_char *pad, *idat, *odat;
- u_char iv[ESP3DESMD5_IVS], blk[8], auth[ESP3DESMD5_ALEN];
+ u_char iv[ESP3DESMD5_IVS], blk[8], auth[ESP3DESMD5_ALEN], opts[40];
MD5_CTX ctx;
-
+ int iphlen;
+
espstat.esps_output++;
m = m_pullup(m, sizeof (struct ip)); /* Get IP header in one mbuf */
if (m == NULL)
@@ -531,7 +537,25 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
ip = mtod(m, struct ip *);
spi = tdb->tdb_spi;
-
+ iphlen = ip->ip_hl << 2;
+
+ /*
+ * If options are present, pullup the IP header, the options
+ * and one DES block (8 bytes) of data.
+ */
+ if (iphlen != sizeof(struct ip))
+ {
+ m = m_pullup(m, iphlen + 8);
+ if (m == NULL)
+ return ENOBUFS;
+
+ ip = mtod(m, struct ip *);
+
+ /* Keep the options */
+ bcopy(mtod(m, u_char *) + sizeof(struct ip), opts,
+ iphlen - sizeof(struct ip));
+ }
+
xd = (struct esp3desmd5_xdata *)tdb->tdb_xdata;
ilen = ntohs(ip->ip_len); /* Size of the packet */
ohlen = sizeof (u_int32_t) + xd->edx_ivlen; /* size of plaintext ESP */
@@ -555,7 +579,7 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
#endif
/* Raw payload length */
- rlen = ESP3DESMD5_RPLENGTH + ilen - sizeof (struct ip);
+ rlen = ESP3DESMD5_RPLENGTH + ilen - iphlen;
padding = ((8 - ((rlen + 2) % 8)) % 8) + 2;
@@ -598,8 +622,7 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
printf("esp3desmd5_output: MD5'ing %d bytes\n", mi->m_len);
#endif
if (mi == m)
- MD5Update(&ctx, (u_char *)mi->m_data + sizeof(struct ip),
- mi->m_len - sizeof(struct ip));
+ MD5Update(&ctx, (u_char *)mi->m_data + iphlen, mi->m_len - iphlen);
else
MD5Update(&ctx, (u_char *)mi->m_data, mi->m_len);
mi = mi->m_next;
@@ -615,35 +638,33 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
* here we construct the whole packet before starting encrypting.
*/
- m = m_pullup(m, sizeof(struct ip) + ESP3DESMD5_RPLENGTH +
+ m = m_pullup(m, iphlen + ESP3DESMD5_RPLENGTH +
sizeof(u_int32_t) + xd->edx_ivlen);
if (m == NULL)
return ENOBUFS;
/* Copy data if necessary */
- if (m->m_len - sizeof(struct ip))
+ if (m->m_len - iphlen)
{
#ifdef ENCDEBUG
if (encdebug)
printf("esp3desmd5_output: pushing data\n");
#endif
- ms = m_copym(m, sizeof(struct ip), m->m_len - sizeof(struct ip),
- M_DONTWAIT);
+ ms = m_copym(m, iphlen, m->m_len - iphlen, M_DONTWAIT);
if (ms == NULL)
return ENOBUFS;
ms->m_next = m->m_next;
m->m_next = ms;
- m->m_len = sizeof(struct ip);
+ m->m_len = iphlen;
}
/* Copy SPI, IV (or not) and replay counter */
- bcopy((caddr_t)&spi, mtod(m, caddr_t) + sizeof (struct ip),
- sizeof (u_int32_t));
- bcopy((caddr_t)iv, mtod(m, caddr_t) + sizeof (struct ip) +
- sizeof (u_int32_t), xd->edx_ivlen);
- bcopy((caddr_t)&rplc, mtod(m, caddr_t) + sizeof(struct ip) +
- sizeof(u_int32_t) + xd->edx_ivlen, ESP3DESMD5_RPLENGTH);
+ bcopy((caddr_t)&spi, mtod(m, caddr_t) + iphlen, sizeof (u_int32_t));
+ bcopy((caddr_t)iv, mtod(m, caddr_t) + iphlen + sizeof (u_int32_t),
+ xd->edx_ivlen);
+ bcopy((caddr_t)&rplc, mtod(m, caddr_t) + iphlen + sizeof(u_int32_t) +
+ xd->edx_ivlen, ESP3DESMD5_RPLENGTH);
#ifdef ENCDEBUG
if (encdebug)
@@ -677,10 +698,9 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
m->m_pkthdr.len);
#endif
- ilen = olen = m->m_len - sizeof (struct ip) - sizeof(u_int32_t) -
- xd->edx_ivlen;
- idat = odat = mtod(m, u_char *) + sizeof (struct ip) +
- sizeof(u_int32_t) + xd->edx_ivlen;
+ ilen = olen = m->m_len - iphlen - sizeof(u_int32_t) - xd->edx_ivlen;
+ idat = odat = mtod(m, u_char *) + iphlen + sizeof(u_int32_t)
+ + xd->edx_ivlen;
i = 0;
mi = mo = m;
@@ -711,7 +731,7 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
des_ecb3_encrypt(blk, blk, (caddr_t)(xd->edx_eks[0]),
(caddr_t)(xd->edx_eks[1]),
(caddr_t)(xd->edx_eks[2]), 1);
- for (i=0; i<8; i++)
+ for (i = 0; i < 8; i++)
{
while (olen == 0)
{
@@ -740,11 +760,20 @@ esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st
bcopy(iv, xd->edx_iv, ESP3DESMD5_IVS); /* New IV */
/* Fix the length and the next protocol, copy back and off we go */
- ipo.ip_len = htons(sizeof (struct ip) + ohlen + rlen + padding +
- ESP3DESMD5_ALEN);
+ ipo.ip_len = htons(iphlen + ohlen + rlen + padding + ESP3DESMD5_ALEN);
ipo.ip_p = IPPROTO_ESP;
bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof(struct ip));
-
+
+ /* Copy back the options, if existing */
+ if (iphlen != sizeof(struct ip))
+ bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip),
+ iphlen - sizeof(struct ip));
+
*mp = m;
+
+ /* Update the counters */
+ tdb->tdb_packets++;
+ tdb->tdb_bytes += rlen + padding;
+
return 0;
}