From 6e79d83bde76cc1e88a4d6bf487189769ef11465 Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Tue, 24 Jun 1997 12:15:28 +0000 Subject: handle IP options in AH + allow IP options in outgoing encapsulated packets + usage counters for later use with keymanagement processes --- sys/netinet/ip_ah.c | 4 ++- sys/netinet/ip_ahhmacmd5.c | 67 ++++++++++++++++++++++++++++++++++--- sys/netinet/ip_ahhmacsha1.c | 68 ++++++++++++++++++++++++++++++++++--- sys/netinet/ip_ahmd5.c | 61 ++++++++++++++++++++++++++++++++-- sys/netinet/ip_ahsha1.c | 60 +++++++++++++++++++++++++++++++-- sys/netinet/ip_esp3des.c | 56 +++++++++++++++++++++++++------ sys/netinet/ip_esp3desmd5.c | 81 ++++++++++++++++++++++++++++++--------------- sys/netinet/ip_espdes.c | 60 +++++++++++++++++++++++++-------- sys/netinet/ip_espdesmd5.c | 80 ++++++++++++++++++++++++++++++-------------- sys/netinet/ip_ip4.c | 21 ++++++++---- sys/netinet/ip_ipsp.c | 6 ++-- sys/netinet/ip_ipsp.h | 12 +++++-- sys/netinet/ip_output.c | 25 ++++++++++---- 13 files changed, 489 insertions(+), 112 deletions(-) (limited to 'sys/netinet') diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index add29eba25f..cd550282775 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.4 1997/06/20 05:41:46 provos Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.5 1997/06/24 12:15:19 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -76,6 +76,7 @@ ah_input(register struct mbuf *m, int iphlen) ahstat.ahs_input++; +#if 0 /* We need them to verify the packet */ /* * Strip IP options, if any. */ @@ -85,6 +86,7 @@ ah_input(register struct mbuf *m, int iphlen) ip_stripoptions(m, (struct mbuf *)0); iphlen = sizeof (struct ip); } +#endif /* * Make sure that at least the fixed part of the AH header is diff --git a/sys/netinet/ip_ahhmacmd5.c b/sys/netinet/ip_ahhmacmd5.c index 109d1c4b027..00344beee1c 100644 --- a/sys/netinet/ip_ahhmacmd5.c +++ b/sys/netinet/ip_ahhmacmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahhmacmd5.c,v 1.8 1997/06/20 05:41:47 provos Exp $ */ +/* $OpenBSD: ip_ahhmacmd5.c,v 1.9 1997/06/24 12:15:20 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -158,7 +158,8 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) u_int64_t btsx; struct mbuf *m0; MD5_CTX ctx; - + u_int8_t optval; + xd = (struct ahhmacmd5_xdata *)tdb->tdb_xdata; ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; if (xd->amx_wnd >= 0) @@ -184,7 +185,22 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) } ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); + + if ((ip->ip_hl << 2) > sizeof(struct ip)) + { + if ((m = m_pullup(m, ohlen - sizeof (struct ip) + + (ip->ip_hl << 2))) == NULL) + { + ahstat.ahs_hdrops++; + return NULL; + } + + ip = mtod(m, struct ip *); + ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); + } + else + ah = (struct ah *)(ip + 1); + ahp = (struct ahhmacmd5 *)ah; if (xd->amx_wnd >= 0) @@ -205,7 +221,7 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) ipo = *ip; ipo.ip_tos = 0; - ipo.ip_len += sizeof (struct ip); /* adjusted in ip_intr() */ + ipo.ip_len += sizeof(struct ip); /* adjusted in ip_intr() */ HTONS(ipo.ip_len); HTONS(ipo.ip_id); ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ @@ -213,7 +229,37 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) ipo.ip_sum = 0; ctx = xd->amx_ictx; - MD5Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); + MD5Update(&ctx, (unsigned char *)&ipo, sizeof(struct ip)); + + /* Options */ + if ((ip->ip_hl << 2 > sizeof(struct ip))) + for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) + { + optval = ((u_int8_t *)ip)[off]; + MD5Update(&ctx, &optval, 1); + switch (IPOPT_NUMBER(optval)) + { + case IPOPT_EOL: + case IPOPT_NOP: + off++; + continue; + + case IPOPT_SECURITY: + case 133: + case 134: + optval = ((u_int8_t *)ip)[off + 1]; + MD5Update(&ctx, (u_int8_t *)ip + off + 1, optval - 1); + off += optval; + continue; + + default: + MD5Update(&ctx, &optval, 1); + MD5Update(&ctx, ipseczeroes, optval - 2); + off += optval; + continue; + } + } + if (xd->amx_wnd >= 0) MD5Update(&ctx, (unsigned char *)ahp, AH_FLENGTH + HMACMD5_RPLENGTH); else @@ -313,6 +359,10 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) ip->ip_sum = 0; 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); + return m; } @@ -460,5 +510,12 @@ ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str *mp = m; + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - + xd->amx_alen; + if (xd->amx_wnd >= 0) + tdb->tdb_bytes -= HMACMD5_RPLENGTH; + return 0; } diff --git a/sys/netinet/ip_ahhmacsha1.c b/sys/netinet/ip_ahhmacsha1.c index 9e1c2b7d6fc..53270358894 100644 --- a/sys/netinet/ip_ahhmacsha1.c +++ b/sys/netinet/ip_ahhmacsha1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahhmacsha1.c,v 1.6 1997/06/20 05:41:48 provos Exp $ */ +/* $OpenBSD: ip_ahhmacsha1.c,v 1.7 1997/06/24 12:15:20 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -158,7 +158,8 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) u_int64_t btsx; struct mbuf *m0; SHA1_CTX ctx; - + u_int8_t optval; + xd = (struct ahhmacsha1_xdata *)tdb->tdb_xdata; ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; if (xd->amx_wnd >= 0) @@ -184,7 +185,23 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) } ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); + + ip = mtod(m, struct ip *); + + if ((ip->ip_hl << 2) > sizeof(struct ip)) + { + if ((m = m_pullup(m, ohlen - sizeof (struct ip) + + (ip->ip_hl << 2))) == NULL) + { + ahstat.ahs_hdrops++; + return NULL; + } + + ip = mtod(m, struct ip *); + ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); + } + else + ah = (struct ah *)(ip + 1); ahp = (struct ahhmacsha1 *)ah; if (xd->amx_wnd >= 0) @@ -205,7 +222,7 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) ipo = *ip; ipo.ip_tos = 0; - ipo.ip_len += sizeof (struct ip); /* adjusted in ip_intr() */ + ipo.ip_len += sizeof(struct ip); /* adjusted in ip_intr() */ HTONS(ipo.ip_len); HTONS(ipo.ip_id); ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ @@ -213,7 +230,37 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) ipo.ip_sum = 0; ctx = xd->amx_ictx; - SHA1Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); + SHA1Update(&ctx, (unsigned char *)&ipo, sizeof(struct ip)); + + /* Options */ + if ((ip->ip_hl << 2 > sizeof(struct ip))) + for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) + { + optval = ((u_int8_t *)ip)[off]; + SHA1Update(&ctx, &optval, 1); + switch (IPOPT_NUMBER(optval)) + { + case IPOPT_EOL: + case IPOPT_NOP: + off++; + continue; + + case IPOPT_SECURITY: + case 133: + case 134: + optval = ((u_int8_t *)ip)[off + 1]; + SHA1Update(&ctx, (u_int8_t *)ip + off + 1, optval - 1); + off += optval; + continue; + + default: + SHA1Update(&ctx, &optval, 1); + SHA1Update(&ctx, ipseczeroes, optval - 2); + off += optval; + continue; + } + } + if (xd->amx_wnd >= 0) SHA1Update(&ctx, (unsigned char *)ahp, AH_FLENGTH + HMACSHA1_RPLENGTH); @@ -315,6 +362,10 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) ip->ip_sum = 0; 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); + return m; } @@ -464,5 +515,12 @@ ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, st *mp = m; + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - + xd->amx_alen; + if (xd->amx_wnd >= 0) + tdb->tdb_bytes -= HMACSHA1_RPLENGTH; + return 0; } diff --git a/sys/netinet/ip_ahmd5.c b/sys/netinet/ip_ahmd5.c index cac7363768c..fdd9fa1c232 100644 --- a/sys/netinet/ip_ahmd5.c +++ b/sys/netinet/ip_ahmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahmd5.c,v 1.5 1997/06/20 05:41:48 provos Exp $ */ +/* $OpenBSD: ip_ahmd5.c,v 1.6 1997/06/24 12:15:21 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -132,6 +132,7 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb) int ohlen, len, count, off; struct mbuf *m0; MD5_CTX ctx; + u_int8_t optval; xd = (struct ahmd5_xdata *)tdb->tdb_xdata; ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; @@ -156,7 +157,21 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb) } ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); + + if ((ip->ip_hl << 2) > sizeof(struct ip)) + { + if ((m = m_pullup(m, ohlen - sizeof (struct ip) + + (ip->ip_hl << 2))) == NULL) + { + ahstat.ahs_hdrops++; + return NULL; + } + + ip = mtod(m, struct ip *); + ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); + } + else + ah = (struct ah *)(ip + 1); ipo = *ip; ipo.ip_tos = 0; @@ -171,6 +186,37 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb) MD5Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); MD5Final(NULL, &ctx); /* non-std usage of MD5Final! */ MD5Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); + + /* Options */ + if ((ip->ip_hl << 2 > sizeof(struct ip))) + for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) + { + optval = ((u_int8_t *)ip)[off]; + MD5Update(&ctx, &optval, 1); + switch (optval) + { + case IPOPT_EOL: + case IPOPT_NOP: + off++; + continue; + + case IPOPT_SECURITY: + case 133: + case 134: + optval = ((u_int8_t *)ip)[off + 1]; + MD5Update(&ctx, (u_int8_t *)ip + off + 1, optval - 1); + off += optval; + continue; + + default: + MD5Update(&ctx, &optval, 1); + MD5Update(&ctx, ipseczeroes, optval - 2); + off += optval; + continue; + } + } + + MD5Update(&ctx, (unsigned char *)ah, AH_FLENGTH); MD5Update(&ctx, ipseczeroes, xd->amx_alen); @@ -233,6 +279,10 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb) ip->ip_sum = 0; 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); + return m; } @@ -351,6 +401,11 @@ ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct MD5Final(&(ah->ah_data[0]), &ctx); *mp = m; - + + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - + xd->amx_alen; + return 0; } diff --git a/sys/netinet/ip_ahsha1.c b/sys/netinet/ip_ahsha1.c index bcfd9804af4..883383eb3b7 100644 --- a/sys/netinet/ip_ahsha1.c +++ b/sys/netinet/ip_ahsha1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahsha1.c,v 1.1 1997/06/20 05:41:49 provos Exp $ */ +/* $OpenBSD: ip_ahsha1.c,v 1.2 1997/06/24 12:15:21 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -132,7 +132,8 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb) int ohlen, len, count, off; struct mbuf *m0; SHA1_CTX ctx; - + u_int8_t optval; + xd = (struct ahsha1_xdata *)tdb->tdb_xdata; ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; @@ -156,7 +157,21 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb) } ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); + + if ((ip->ip_hl << 2) > sizeof(struct ip)) + { + if ((m = m_pullup(m, ohlen - sizeof (struct ip) + + (ip->ip_hl << 2))) == NULL) + { + ahstat.ahs_hdrops++; + return NULL; + } + + ip = mtod(m, struct ip *); + ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); + } + else + ah = (struct ah *)(ip + 1); ipo = *ip; ipo.ip_tos = 0; @@ -170,6 +185,36 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb) SHA1Init(&ctx); SHA1Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); SHA1Final(NULL, &ctx); /* non-std usage of SHA1Final! */ + + /* Options */ + if ((ip->ip_hl << 2 > sizeof(struct ip))) + for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) + { + optval = ((u_int8_t *)ip)[off]; + SHA1Update(&ctx, &optval, 1); + switch (IPOPT_NUMBER(optval)) + { + case IPOPT_EOL: + case IPOPT_NOP: + off++; + continue; + + case IPOPT_SECURITY: + case 133: + case 134: + optval = ((u_int8_t *)ip)[off + 1]; + SHA1Update(&ctx, (u_int8_t *)ip + off + 1, optval - 1); + off += optval; + continue; + + default: + SHA1Update(&ctx, &optval, 1); + SHA1Update(&ctx, ipseczeroes, optval - 2); + off += optval; + continue; + } + } + SHA1Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); SHA1Update(&ctx, (unsigned char *)ah, AH_FLENGTH); SHA1Update(&ctx, ipseczeroes, xd->amx_alen); @@ -233,6 +278,10 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb) ip->ip_sum = 0; 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); + return m; } @@ -352,5 +401,10 @@ ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct *mp = m; + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - + xd->amx_alen; + return 0; } diff --git a/sys/netinet/ip_esp3des.c b/sys/netinet/ip_esp3des.c index 18791ee7309..fb189eec04a 100644 --- a/sys/netinet/ip_esp3des.c +++ b/sys/netinet/ip_esp3des.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp3des.c,v 1.3 1997/06/21 00:09:17 deraadt Exp $ */ +/* $OpenBSD: ip_esp3des.c,v 1.4 1997/06/24 12:15:22 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -299,6 +299,10 @@ esp3des_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) + blk[6] + 2; + return m; } @@ -311,7 +315,8 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc u_int32_t spi; struct mbuf *mi, *mo; u_char *pad, *idat, *odat; - u_char iv[8], blk[8]; + u_char iv[8], blk[8], opts[40]; + int iphlen; espstat.esps_output++; m = m_pullup(m, sizeof (struct ip)); @@ -320,7 +325,25 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc 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 esp3des_xdata *)tdb->tdb_xdata; ilen = ntohs(ip->ip_len); ohlen = sizeof (u_int32_t) + xd->edx_ivlen; @@ -328,7 +351,7 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc ipo = *ip; nh = ipo.ip_p; - rlen = ilen - sizeof (struct ip); /* raw payload length */ + rlen = ilen - iphlen; /* raw payload length */ padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; pad = (u_char *)m_pad(m, padding); @@ -340,8 +363,8 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc plen = rlen + padding; mi = mo = m; - ilen = olen = m->m_len - sizeof (struct ip); - idat = odat = mtod(m, u_char *) + sizeof (struct ip); + ilen = olen = m->m_len - iphlen; + idat = odat = mtod(m, u_char *) + iphlen; i = 0; /* @@ -390,7 +413,7 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc 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) { @@ -419,11 +442,11 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc if (m == NULL) return ENOBUFS; - m = m_pullup(m, sizeof(struct ip) + xd->edx_ivlen + sizeof(u_int32_t)); + m = m_pullup(m, iphlen + ohlen); if (m == NULL) return ENOBUFS; - ipo.ip_len = htons(sizeof (struct ip) + ohlen + rlen + padding); + ipo.ip_len = htons(iphlen + ohlen + rlen + padding); ipo.ip_p = IPPROTO_ESP; iv[0] = xd->edx_iv[0]; @@ -439,11 +462,22 @@ esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struc } bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof (struct ip)); - bcopy((caddr_t)&spi, mtod(m, caddr_t) + sizeof (struct ip), + + /* Copy options, if existing */ + if (iphlen != sizeof(struct ip)) + bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), + iphlen - sizeof(struct ip)); + + 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) + + bcopy((caddr_t)iv, mtod(m, caddr_t) + sizeof(struct ip) + sizeof (u_int32_t), xd->edx_ivlen); *mp = m; + + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += rlen + padding; + return 0; } 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; } diff --git a/sys/netinet/ip_espdes.c b/sys/netinet/ip_espdes.c index 9cf7f6f8876..476144dcc0d 100644 --- a/sys/netinet/ip_espdes.c +++ b/sys/netinet/ip_espdes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_espdes.c,v 1.5 1997/06/21 00:09:18 deraadt Exp $ */ +/* $OpenBSD: ip_espdes.c,v 1.6 1997/06/24 12:15:23 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -286,6 +286,10 @@ espdes_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) + blk[6] + 2; + return m; } @@ -298,7 +302,8 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct u_int32_t spi; struct mbuf *mi, *mo; u_char *pad, *idat, *odat; - u_char iv[8], blk[8]; + u_char iv[8], blk[8], opts[40]; + int iphlen; espstat.esps_output++; m = m_pullup(m, sizeof (struct ip)); @@ -307,7 +312,25 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct 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 espdes_xdata *)tdb->tdb_xdata; ilen = ntohs(ip->ip_len); ohlen = sizeof (u_int32_t) + xd->edx_ivlen; @@ -315,7 +338,7 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct ipo = *ip; nh = ipo.ip_p; - rlen = ilen - sizeof (struct ip); /* raw payload length */ + rlen = ilen - iphlen; /* raw payload length */ padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; pad = (u_char *)m_pad(m, padding); @@ -327,8 +350,8 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct plen = rlen + padding; mi = mo = m; - ilen = olen = m->m_len - sizeof (struct ip); - idat = odat = mtod(m, u_char *) + sizeof (struct ip); + ilen = olen = m->m_len - iphlen; + idat = odat = mtod(m, u_char *) + iphlen; i = 0; /* @@ -375,7 +398,7 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct if (i == 8) { des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 1); - for (i=0; i<8; i++) + for (i = 0; i < 8; i++) { while (olen == 0) { @@ -404,11 +427,11 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct if (m == NULL) return ENOBUFS; - m = m_pullup(m, sizeof(struct ip) + xd->edx_ivlen + sizeof(u_int32_t)); + m = m_pullup(m, iphlen + ohlen); if (m == NULL) return ENOBUFS; - ipo.ip_len = htons(sizeof (struct ip) + ohlen + rlen + padding); + ipo.ip_len = htons(iphlen + ohlen + rlen + padding); ipo.ip_p = IPPROTO_ESP; iv[0] = xd->edx_iv[0]; @@ -423,12 +446,23 @@ espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct iv[7] = xd->edx_iv[7]; } - bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof (struct ip)); - 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)&ipo, mtod(m, caddr_t), sizeof(struct ip)); + + /* Copy options, if existing */ + if (iphlen != sizeof(struct ip)) + bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), + iphlen - sizeof(struct ip)); + + 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); *mp = m; + + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += rlen + padding; + return 0; } diff --git a/sys/netinet/ip_espdesmd5.c b/sys/netinet/ip_espdesmd5.c index f35d227748a..9b0f8f8ab64 100644 --- a/sys/netinet/ip_espdesmd5.c +++ b/sys/netinet/ip_espdesmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_espdesmd5.c,v 1.7 1997/06/21 00:09:18 deraadt Exp $ */ +/* $OpenBSD: ip_espdesmd5.c,v 1.8 1997/06/24 12:15:24 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -492,6 +492,11 @@ espdesmd5_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 + ESPDESMD5_ALEN; + return m; } @@ -505,9 +510,10 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str u_int32_t spi; struct mbuf *mi, *mo, *ms; u_char *pad, *idat, *odat; - u_char iv[ESPDESMD5_IVS], blk[8], auth[ESPDESMD5_ALEN]; + u_char iv[ESPDESMD5_IVS], blk[8], auth[ESPDESMD5_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) @@ -515,7 +521,25 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str 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 espdesmd5_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 */ @@ -539,7 +563,7 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str #endif /* Raw payload length */ - rlen = ESPDESMD5_RPLENGTH + ilen - sizeof (struct ip); + rlen = ESPDESMD5_RPLENGTH + ilen - iphlen; padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; @@ -582,8 +606,8 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str printf("espdesmd5_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; @@ -599,35 +623,33 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str * here we construct the whole packet before starting encrypting. */ - m = m_pullup(m, sizeof(struct ip) + ESPDESMD5_RPLENGTH + + m = m_pullup(m, iphlen + ESPDESMD5_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("espdesmd5_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, ESPDESMD5_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, ESPDESMD5_RPLENGTH); #ifdef ENCDEBUG if (encdebug) @@ -661,10 +683,9 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str 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; @@ -693,7 +714,7 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str if (i == 8) /* We have full block */ { des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 1); - for (i=0; i<8; i++) + for (i = 0; i < 8; i++) { while (olen == 0) { @@ -718,15 +739,24 @@ espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, str printf("espdesmd5_output: almost done now\n"); #endif - if (xd->edx_ivlen) + if (xd->edx_ivlen != 0) bcopy(iv, xd->edx_iv, ESPDESMD5_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 + + ipo.ip_len = htons(iphlen + ohlen + rlen + padding + ESPDESMD5_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)); + + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += rlen + padding; + *mp = m; return 0; } diff --git a/sys/netinet/ip_ip4.c b/sys/netinet/ip_ip4.c index a6f5a1fc4b4..ba5cedcc307 100644 --- a/sys/netinet/ip_ip4.c +++ b/sys/netinet/ip_ip4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ip4.c,v 1.7 1997/06/24 02:20:23 angelos Exp $ */ +/* $OpenBSD: ip_ip4.c,v 1.8 1997/06/24 12:15:25 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -196,14 +196,21 @@ ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct m ipo->ip_src = gw->sen_ipsp_src; ipo->ip_dst = gw->sen_ipsp_dst; -/* printf("ip4_output: [%x->%x](l=%d, p=%d)", - ntohl(ipi->ip_src.s_addr), ntohl(ipi->ip_dst.s_addr), - ilen, ipi->ip_p); - printf(" through [%x->%x](l=%d, p=%d)\n", - ntohl(ipo->ip_src.s_addr), ntohl(ipo->ip_dst.s_addr), - ipo->ip_len, ipo->ip_p);*/ +/* + * printf("ip4_output: [%x->%x](l=%d, p=%d)", + * ntohl(ipi->ip_src.s_addr), ntohl(ipi->ip_dst.s_addr), + * ilen, ipi->ip_p); + * printf(" through [%x->%x](l=%d, p=%d)\n", + * ntohl(ipo->ip_src.s_addr), ntohl(ipo->ip_dst.s_addr), + * ipo->ip_len, ipo->ip_p); + */ *mp = m; + + /* Update the counters */ + tdb->tdb_packets++; + tdb->tdb_bytes += ntohs(ipo->ip_len) - (ipo->ip_hl << 2); + return 0; /* return ip_output(m, NULL, NULL, IP_ENCAPSULATED, NULL);*/ diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index dabe093ee63..1388be11ed6 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.8 1997/06/21 00:09:19 deraadt Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.9 1997/06/24 12:15:25 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -90,10 +90,10 @@ struct xformsw xformsw[] = { { XF_AHHMACSHA1, XFT_AUTH, "HMAC SHA1 Authentication", ahhmacsha1_attach, ahhmacsha1_init, ahhmacsha1_zeroize, ahhmacsha1_input, ahhmacsha1_output, }, - { XF_ESPDESMD5, XFT_CONF, "DES-CBC Encryption + MD5 Authentication", + { XF_ESPDESMD5, XFT_CONF|XFT_AUTH, "DES-CBC Encryption + MD5 Authentication", espdesmd5_attach, espdesmd5_init, espdesmd5_zeroize, espdesmd5_input, espdesmd5_output, }, - { XF_ESP3DESMD5, XFT_CONF, "3DES-CBC Encryption + MD5 Authentication", + { XF_ESP3DESMD5, XFT_CONF|XFT_AUTH, "3DES-CBC Encryption + MD5 Authentication", esp3desmd5_attach, esp3desmd5_init, esp3desmd5_zeroize, esp3desmd5_input, esp3desmd5_output, }, }; diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 53b42ab198d..b9c9c27e64d 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.6 1997/06/21 00:09:19 deraadt Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.7 1997/06/24 12:15:26 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -36,11 +36,17 @@ struct tdb /* tunnel descriptor block */ u_int32_t tdb_flags; /* Flags related to this TDB */ #define TDBF_UNIQUE 0x0001 /* This should not be used by others */ #define TDBF_TIMER 0x0002 /* Check the timers */ -#define TDBF_BYTES 0x0004 /* Update the byte counters */ +#define TDBF_BYTES 0x0004 /* Check the byte counters */ +#define TDBF_PACKETS 0x0008 /* Check the packet counters */ +#define TDBF_INVALID 0x0010 /* This SPI is no longer valid */ + u_int64_t tdb_packets; /* Expire after so many packets s|r */ + u_int64_t tdb_soft_packets; /* Expiration warning */ + u_int64_t tdb_cur_packets; /* Current number of packets s|r'ed */ u_int64_t tdb_bytes; /* Expire after so many bytes passed */ + u_int64_t tdb_soft_bytes; /* Expiration warning */ u_int64_t tdb_cur_bytes; /* Current count of bytes */ + u_int64_t tdb_timeout; /* When does the SPI expire */ u_int64_t tdb_soft_timeout; /* Send a soft-expire warning */ - u_int64_t tdb_hard_timeout; /* When does the SPI expire */ u_int64_t tdb_established; /* When was the SPI established */ struct in_addr tdb_dst; /* dest address for this SPI */ struct ifnet *tdb_rcvif; /* related rcv encap interface */ diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 93452d3d465..e82ca8a8592 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.12 1997/06/16 06:32:51 deraadt Exp $ */ +/* $OpenBSD: ip_output.c,v 1.13 1997/06/24 12:15:27 provos Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -240,11 +240,6 @@ ip_output(m0, va_alist) ip->ip_src = sinp->sin_addr; } - if (hlen > sizeof (struct ip)) { /* XXX IPOPT */ - ip_stripoptions(m, (struct mbuf *)0); - hlen = sizeof (struct ip); - } - #ifdef ENCDEBUG if (encdebug) printf("ip_output: encapsulating %x->%x through %x->%x\n", @@ -254,7 +249,6 @@ ip_output(m0, va_alist) ip->ip_len = htons((u_short)ip->ip_len); ip->ip_off = htons((u_short)ip->ip_off); ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, hlen); /* * At this point we have an IPSP "gateway" (tunnel) spec. @@ -266,6 +260,23 @@ ip_output(m0, va_alist) tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, gw->sen_ipsp_dst); + /* + * If we're doing IP-in-IP first, let the options be. + * Otherwise, get rid of them. + * XXX This means we don't send packets with IP options + * XXX unless they're encapsulated (and, presumably, + * XXX subsequently authenticated). + */ + if (tdb && tdb->tdb_xform) + if (tdb->tdb_xform->xf_type != XF_IP4) + if (hlen > sizeof (struct ip)) { /* XXX IPOPT */ + ip_stripoptions(m, (struct mbuf *)0); + hlen = sizeof (struct ip); + } + + /* Now fix the checksum */ + ip->ip_sum = in_cksum(m, hlen); + #ifdef ENCDEBUG if (encdebug) printf("ip_output: tdb=0x%x, tdb->tdb_xform=0x%x, tdb->tdb_xform->xf_output=%x\n", tdb, tdb->tdb_xform, tdb->tdb_xform->xf_output); -- cgit v1.2.3