summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/ipsecadm/ipsecadm.c75
-rw-r--r--sys/net/pfkeyv2.c47
-rw-r--r--sys/net/pfkeyv2.h3
-rw-r--r--sys/net/pfkeyv2_parsemessage.c8
-rw-r--r--sys/netinet/in.h4
-rw-r--r--sys/netinet/in_pcb.c4
-rw-r--r--sys/netinet/in_pcb.h5
-rw-r--r--sys/netinet/ip_ah.c30
-rw-r--r--sys/netinet/ip_esp.c30
-rw-r--r--sys/netinet/ip_ipsp.c149
-rw-r--r--sys/netinet/ip_ipsp.h15
-rw-r--r--sys/netinet/ip_output.c85
-rw-r--r--sys/netinet/tcp_input.c52
-rw-r--r--sys/netinet/tcp_var.h3
-rw-r--r--sys/netinet/udp_usrreq.c39
-rw-r--r--sys/netinet/udp_var.h3
-rw-r--r--sys/sys/mbuf.h4
-rw-r--r--usr.bin/netstat/inet.c6
18 files changed, 461 insertions, 101 deletions
diff --git a/sbin/ipsecadm/ipsecadm.c b/sbin/ipsecadm/ipsecadm.c
index 9569cd0c9e0..3bea6f5f325 100644
--- a/sbin/ipsecadm/ipsecadm.c
+++ b/sbin/ipsecadm/ipsecadm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecadm.c,v 1.14 1999/03/15 15:37:02 deraadt Exp $ */
+/* $OpenBSD: ipsecadm.c,v 1.15 1999/03/27 21:04:18 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -72,6 +72,7 @@
#define DEL_SPI 0x30
#define GRP_SPI 0x40
#define FLOW 0x50
+#define BINDSA 0x60
#define ENC_IP 0x80
#define CMD_MASK 0xf0
@@ -176,7 +177,8 @@ void
usage()
{
fprintf(stderr, "usage: ipsecadm [command] <modifier...>\n"
- "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4, flow\n"
+ "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4\n"
+ "\t\t flow, bind\n"
"\tPossible modifiers:\n"
"\t -enc <alg>\t\t\t encryption algorithm\n"
"\t -auth <alg>\t\t\t authentication algorithm\n"
@@ -206,6 +208,7 @@ main(int argc, char **argv)
int dport = -1, sport = -1, tproto = -1;
u_int32_t spi = 0, spi2 = 0;
union sockaddr_union src, dst, dst2, osrc, odst, osmask, odmask, proxy;
+ int srcset = 0, dstset = 0, dst2set = 0;
u_char *keyp = NULL, *authp = NULL;
struct protoent *tp;
struct servent *svp;
@@ -346,28 +349,36 @@ main(int argc, char **argv)
i++;
}
else
- if (!strcmp(argv[1], "flow"))
+ if (!strcmp(argv[1], "bind"))
{
- /* It may not be ADDFLOW, but never mind that for now */
- smsg.sadb_msg_type = SADB_X_ADDFLOW;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- mode = FLOW;
+ smsg.sadb_msg_type = SADB_X_BINDSA;
+ smsg.sadb_msg_satype = SADB_SATYPE_ESP;
+ mode = BINDSA;
i++;
}
else
- if (!strcmp(argv[1], "ip4"))
+ if (!strcmp(argv[1], "flow"))
{
- mode = ENC_IP;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_SATYPE_X_IPIP;
+ /* It may not be ADDFLOW, but never mind that for now */
+ smsg.sadb_msg_type = SADB_X_ADDFLOW;
+ smsg.sadb_msg_satype = SADB_SATYPE_ESP;
+ mode = FLOW;
i++;
}
else
- {
- fprintf(stderr, "%s: unknown command: %s", argv[0], argv[1]);
- exit(1);
- }
-
+ if (!strcmp(argv[1], "ip4"))
+ {
+ mode = ENC_IP;
+ smsg.sadb_msg_type = SADB_ADD;
+ smsg.sadb_msg_satype = SADB_SATYPE_X_IPIP;
+ i++;
+ }
+ else
+ {
+ fprintf(stderr, "%s: unknown command: %s", argv[0], argv[1]);
+ exit(1);
+ }
+
for (i++; i < argc; i++)
{
if (argv[i][0] != '-')
@@ -472,7 +483,7 @@ main(int argc, char **argv)
}
if (!strcmp(argv[i] + 1, "spi2") && spi2 == 0 &&
- iscmd(mode, GRP_SPI) && (i + 1 < argc))
+ (iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA) && (i + 1 < argc))
{
if ((spi2 = htonl(strtoul(argv[i + 1], NULL, 16))) == 0)
{
@@ -489,7 +500,7 @@ main(int argc, char **argv)
{
src.sin.sin_family = AF_INET;
src.sin.sin_len = sizeof(struct sockaddr_in);
- src.sin.sin_addr.s_addr = inet_addr(argv[i + 1]);
+ srcset = inet_aton(argv[i + 1], &src.sin.sin_addr) != -1 ? 1 : 0;
sad1.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
sad1.sadb_address_len = 1 + sizeof(struct sockaddr_in) / 8;
i++;
@@ -674,27 +685,27 @@ main(int argc, char **argv)
sizeof(struct sockaddr_in)) / 8;
dst.sin.sin_family = AF_INET;
dst.sin.sin_len = sizeof(struct sockaddr_in);
- dst.sin.sin_addr.s_addr = inet_addr(argv[i + 1]);
+ dstset = inet_aton(argv[i + 1], &dst.sin.sin_addr) != -1 ? 1 : 0;
i++;
continue;
}
if (!strcmp(argv[i] + 1, "dst2") &&
- iscmd(mode, GRP_SPI) && (i + 1 < argc))
+ (iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA) && (i + 1 < argc))
{
sad8.sadb_address_len = (sizeof(sad8) +
sizeof(struct sockaddr_in)) / 8;
sad8.sadb_address_exttype = SADB_EXT_X_DST2;
dst2.sin.sin_family = AF_INET;
dst2.sin.sin_len = sizeof(struct sockaddr_in);
- dst2.sin.sin_addr.s_addr = inet_addr(argv[i + 1]);
+ dst2set = inet_aton(argv[i + 1], &dst2.sin.sin_addr) != -1 ? 1 : 0;
i++;
continue;
}
if (!strcmp(argv[i] + 1, "proto") && (i + 1 < argc) &&
(iscmd(mode, FLOW) || iscmd(mode, GRP_SPI) ||
- iscmd(mode, DEL_SPI)))
+ iscmd(mode, DEL_SPI) || iscmd(mode, BINDSA)))
{
if (isalpha(argv[i + 1][0]))
{
@@ -855,36 +866,37 @@ main(int argc, char **argv)
exit(1);
}
- if (iscmd(mode, GRP_SPI) && spi2 == 0)
+ if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) && spi2 == 0)
{
fprintf(stderr, "%s: no SPI2 specified\n", argv[0]);
exit(1);
}
- if ((isencauth(mode) || iscmd(mode, ENC_IP)) &&
- src.sin.sin_addr.s_addr == 0)
+ if ((isencauth(mode) || iscmd(mode, ENC_IP)) && !srcset)
{
fprintf(stderr, "%s: no source address specified\n", argv[0]);
exit(1);
}
- if ((iscmd(mode, DEL_SPI) || iscmd(mode, GRP_SPI) || iscmd(mode, FLOW)) &&
- proto != IPPROTO_ESP && proto != IPPROTO_AH && proto != IPPROTO_IPIP)
+ if ((iscmd(mode, DEL_SPI) || iscmd(mode, GRP_SPI) || iscmd(mode, FLOW) ||
+ iscmd(mode, BINDSA)) && proto != IPPROTO_ESP &&
+ proto != IPPROTO_AH && proto != IPPROTO_IPIP)
{
fprintf(stderr, "%s: security protocol is none of AH, ESP or IPIP\n",
argv[0]);
exit(1);
}
- if (iscmd(mode, GRP_SPI) && proto2 != IPPROTO_ESP &&
- proto2 != IPPROTO_AH && proto2 != IPPROTO_IPIP)
+ if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) &&
+ proto2 != IPPROTO_ESP && proto2 != IPPROTO_AH &&
+ proto2 != IPPROTO_IPIP)
{
fprintf(stderr, "%s: security protocol2 is none of AH, ESP or IPIP\n",
argv[0]);
exit(1);
}
- if (dst.sin.sin_addr.s_addr == 0)
+ if (!dstset)
{
fprintf(stderr, "%s: no destination address for the SA specified\n",
argv[0]);
@@ -907,7 +919,7 @@ main(int argc, char **argv)
exit(1);
}
- if (iscmd(mode, GRP_SPI) && dst2.sin.sin_addr.s_addr == 0)
+ if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) && !dst2set)
{
fprintf(stderr, "%s: no destination address2 specified\n", argv[0]);
exit(1);
@@ -1005,6 +1017,7 @@ main(int argc, char **argv)
switch(mode & CMD_MASK)
{
case GRP_SPI:
+ case BINDSA:
/* SA header */
iov[cnt].iov_base = &sa;
iov[cnt++].iov_len = sizeof(sa);
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index b57ff0f9903..f0879bb1a96 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1339,6 +1339,53 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
break;
+ case SADB_X_BINDSA:
+ {
+ struct tdb *tdb1, *tdb2;
+
+ tdb1 = gettdb(((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_spi,
+ (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
+ sizeof(struct sadb_address)),
+ SADB_GETSPROTO(((struct sadb_msg *)headers[0])->sadb_msg_satype));
+ if (tdb1 == NULL) {
+ rval = ESRCH;
+ goto ret;
+ }
+
+ if (TAILQ_FIRST(&tdb1->tdb_bind_in)) {
+ /* Incoming SA has not list of referencing incoming SAs */
+ rval = EINVAL;
+ goto ret;
+ }
+
+ tdb2 = gettdb(((struct sadb_sa *)headers[SADB_EXT_X_SA2])->sadb_sa_spi,
+ (union sockaddr_union *)(headers[SADB_EXT_X_DST2] +
+ sizeof(struct sadb_address)),
+ SADB_GETSPROTO(((struct sadb_protocol *)headers[SADB_EXT_X_PROTOCOL])->sadb_protocol_proto));
+
+ if (tdb2 == NULL) {
+ rval = ESRCH;
+ goto ret;
+ }
+
+ if (tdb2->tdb_bind_out) {
+ /* Outgoing SA has no pointer to an outgoing SA */
+ rval = EINVAL;
+ goto ret;
+ }
+
+ /* Maintenance */
+ if (tdb1->tdb_bind_out)
+ TAILQ_REMOVE(&tdb1->tdb_bind_out->tdb_bind_in, tdb1,
+ tdb_bind_in_next);
+
+ /* Link them */
+ tdb1->tdb_bind_out = tdb2;
+ TAILQ_INSERT_TAIL(&tdb2->tdb_bind_in, tdb1, tdb_bind_in_next);
+ }
+
+ break;
+
case SADB_X_PROMISC:
if (len >= 2 * sizeof(struct sadb_msg)) {
struct mbuf *packet;
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index 6945f81951e..7051fca9696 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -29,7 +29,8 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#define SADB_X_ADDFLOW 12
#define SADB_X_DELFLOW 13
#define SADB_X_GRPSPIS 14
-#define SADB_MAX 14
+#define SADB_X_BINDSA 15
+#define SADB_MAX 15
struct sadb_msg {
uint8_t sadb_msg_version;
diff --git a/sys/net/pfkeyv2_parsemessage.c b/sys/net/pfkeyv2_parsemessage.c
index 7c56c9823f5..46b83dedadf 100644
--- a/sys/net/pfkeyv2_parsemessage.c
+++ b/sys/net/pfkeyv2_parsemessage.c
@@ -88,6 +88,8 @@ uint32_t sadb_exts_allowed_in[SADB_MAX+1] =
/* X_DELFLOW */
BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_SA,
/* X_GRPSPIS */
+ BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
+ /* X_BINDSA */
BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL
};
@@ -122,6 +124,8 @@ uint32_t sadb_exts_required_in[SADB_MAX+1] =
/* X_DELFLOW */
BITMAP_SA | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW,
/* X_GRPSPIS */
+ BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
+ /* X_BINDSA */
BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL
};
@@ -156,6 +160,8 @@ uint32_t sadb_exts_allowed_out[SADB_MAX+1] =
/* X_DELFLOW */
BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_SA,
/* X_GRPSPIS */
+ BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
+ /* X_BINDSA */
BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL
};
@@ -190,6 +196,8 @@ uint32_t sadb_exts_required_out[SADB_MAX+1] =
/* X_DELFLOW */
BITMAP_SA | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW,
/* X_GRPSPIS */
+ BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
+ /* X_BINDSA */
BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL
};
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 38bd73db826..d58c46f1bc5 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.h,v 1.20 1999/03/24 02:31:03 cmetz Exp $ */
+/* $OpenBSD: in.h,v 1.21 1999/03/27 21:04:21 provos Exp $ */
/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
/*
@@ -379,6 +379,8 @@ struct ip_opts {
#define ICMPV6_FILTER 38 /* struct icmpv6_filter; get/set filter */
#define ICMP6_FILTER ICMP6_FILTER
+#define IPSEC_OUTSA 39 /* set the outbound SA for a socket */
+
/*
* Security levels - IPsec, not IPSO
*/
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 23c656d635b..66fc00db939 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.31 1999/03/24 02:28:21 cmetz Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.32 1999/03/27 21:04:18 provos Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -529,6 +529,8 @@ in_pcbdetach(v)
ip_freemoptions(inp->inp_moptions);
#ifdef IPSEC
/* XXX IPsec cleanup here */
+ if (inp->inp_tdb)
+ TAILQ_REMOVE(&inp->inp_tdb->tdb_inp, inp, inp_tdb_next);
#endif
s = splnet();
LIST_REMOVE(inp, inp_hash);
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 176ce07a742..cb753c3ae82 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.16 1999/03/24 02:33:02 cmetz Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.17 1999/03/27 21:04:19 provos Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -40,6 +40,7 @@
#include <netinet6/ipv6.h>
#include <netinet6/ipv6_var.h>
#include <netinet6/icmpv6.h>
+#include <netinet/ip_ipsp.h>
union inpaddru {
struct in6_addr iau_addr6;
@@ -99,6 +100,8 @@ struct inpcb {
#define SR_FAILED 1 /* Negotiation failed permanently */
#define SR_SUCCESS 2 /* SA successfully established */
#define SR_WAIT 3 /* Waiting for SA */
+ TAILQ_ENTRY(inpcb) inp_tdb_next;
+ struct tdb *inp_tdb; /* If tdb_dst matches our dst, use */
int inp_fflowinfo; /* Foreign flowlabel & priority */
int inp_csumoffset;
struct icmpv6_filter inp_filter;
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index afa4cbe472b..4fdb5d29813 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.18 1999/02/24 23:45:46 angelos Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.19 1999/03/27 21:04:19 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -238,6 +238,32 @@ ah_input(register struct mbuf *m, int iphlen)
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"));
+ }
+ if (!tdbi || !(m->m_flags & (M_CONF|M_AUTH)))
+ 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;
+ }
+
+ m->m_pkthdr.tdbi = tdbi;
+ no_mem:
+ }
+
/* Packet is authentic */
m->m_flags |= M_AUTH;
@@ -277,6 +303,8 @@ ah_input(register struct mbuf *m, int iphlen)
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);
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index f2da8435264..b099bdd1579 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.18 1999/02/24 23:45:49 angelos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.19 1999/03/27 21:04:19 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -237,6 +237,32 @@ esp_input(register struct mbuf *m, int iphlen)
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(("esp_input(): mbuf is not a packet header!\n"));
+ }
+ if (!tdbi || !(m->m_flags & (M_CONF|M_AUTH)))
+ 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;
+ }
+
+ m->m_pkthdr.tdbi = tdbi;
+ no_mem:
+ }
+
/* Packet is confidental */
m->m_flags |= M_CONF;
@@ -276,6 +302,8 @@ esp_input(register struct mbuf *m, int iphlen)
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);
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index 21ba455bca3..a6eef7e135a 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.38 1999/03/24 17:00:47 niklas Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.39 1999/03/27 21:04:19 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -184,6 +184,7 @@ check_ipsec_policy(struct inpcb *inp, u_int32_t daddr)
struct sockaddr_encap *dst;
u_int8_t sa_require, sa_have;
int error, i;
+ struct tdb *tdb = NULL;
if (inp == NULL || ((so = inp->inp_socket) == 0))
return (EINVAL);
@@ -191,59 +192,60 @@ check_ipsec_policy(struct inpcb *inp, u_int32_t daddr)
/* If IPSEC is not required just use what we got */
if (!(sa_require = inp->inp_secrequire))
return 0;
-
- bzero((caddr_t) re, sizeof(*re));
- dst = (struct sockaddr_encap *) &re->re_dst;
- dst->sen_family = PF_KEY;
- dst->sen_len = SENT_IP4_LEN;
- dst->sen_type = SENT_IP4;
- dst->sen_ip_src = inp->inp_laddr;
- dst->sen_ip_dst.s_addr = inp->inp_faddr.s_addr ?
- inp->inp_faddr.s_addr : daddr;
- dst->sen_proto = so->so_proto->pr_protocol;
- switch (dst->sen_proto)
+
+ if (!inp->inp_tdb)
{
- case IPPROTO_UDP:
- case IPPROTO_TCP:
+ bzero((caddr_t) re, sizeof(*re));
+ dst = (struct sockaddr_encap *) &re->re_dst;
+ dst->sen_family = PF_KEY;
+ dst->sen_len = SENT_IP4_LEN;
+ dst->sen_type = SENT_IP4;
+ dst->sen_ip_src = inp->inp_laddr;
+ dst->sen_ip_dst.s_addr = inp->inp_faddr.s_addr ?
+ inp->inp_faddr.s_addr : daddr;
+ dst->sen_proto = so->so_proto->pr_protocol;
+ switch (dst->sen_proto)
+ {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
dst->sen_sport = inp->inp_lport;
dst->sen_dport = inp->inp_fport;
break;
- default:
+ default:
dst->sen_sport = 0;
dst->sen_dport = 0;
- }
+ }
- /* Try to find a flow */
- rtalloc((struct route *) re);
+ /* Try to find a flow */
+ rtalloc((struct route *) re);
- if (re->re_rt != NULL)
- {
- struct tdb *tdb;
- struct sockaddr_encap *gw;
-
- gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway);
-
- if (gw->sen_type == SENT_IPSP) {
- sunion.sin.sin_family = AF_INET;
- sunion.sin.sin_len = sizeof(struct sockaddr_in);
- sunion.sin.sin_addr = gw->sen_ipsp_dst;
+ if (re->re_rt != NULL)
+ {
+ struct sockaddr_encap *gw;
- tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,
- gw->sen_ipsp_sproto);
-
- SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb);
+ gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway);
+
+ if (gw->sen_type == SENT_IPSP) {
+ sunion.sin.sin_family = AF_INET;
+ sunion.sin.sin_len = sizeof(struct sockaddr_in);
+ sunion.sin.sin_addr = gw->sen_ipsp_dst;
+
+ tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,
+ gw->sen_ipsp_sproto);
+ }
+ RTFREE(re->re_rt);
}
- else
- sa_have = 0;
-
- RTFREE(re->re_rt);
-
- /* Check if our requirements are met */
- if (!(sa_require & ~sa_have))
- return 0;
- }
- else
- sa_have = 0;
+ } else
+ tdb = inp->inp_tdb;
+
+ if (tdb) {
+ SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb);
+ } else
+ sa_have = 0;
+
+ /* Check if our requirements are met */
+ if (!(sa_require & ~sa_have))
+ return 0;
error = i = 0;
@@ -290,6 +292,24 @@ check_ipsec_policy(struct inpcb *inp, u_int32_t daddr)
}
/*
+ * Add an inpcb to the list of inpcb which reference this tdb directly.
+ */
+
+void
+tdb_add_inp(struct tdb *tdb, struct inpcb *inp)
+{
+ if (inp->inp_tdb) {
+ if (inp->inp_tdb == tdb)
+ return;
+ TAILQ_REMOVE(&inp->inp_tdb->tdb_inp, inp, inp_tdb_next);
+ }
+ inp->inp_tdb = tdb;
+ TAILQ_INSERT_TAIL(&tdb->tdb_inp, inp, inp_tdb_next);
+
+ DPRINTF(("tdb_add_inp: tdb: %p, inp: %p\n", tdb, inp));
+}
+
+/*
* Reserve an SPI; the SA is not valid yet though. Zero is reserved as
* an error return value. If tspi is not zero, we try to allocate that
* SPI.
@@ -659,6 +679,7 @@ tdb_delete(struct tdb *tdbp, int delchain)
{
u_int8_t *ptr = (u_int8_t *) &tdbp->tdb_dst;
struct tdb *tdbpp;
+ struct inpcb *inp;
u_int32_t hashval = tdbp->tdb_sproto + tdbp->tdb_spi, i;
for (i = 0; i < SA_LEN(&tdbp->tdb_dst.sa); i++)
@@ -706,6 +727,24 @@ tdb_delete(struct tdb *tdbp, int delchain)
ipsec_in_use--;
}
+ /* Cleanup SA-Bindings */
+ for (tdbpp = TAILQ_FIRST(&tdbp->tdb_bind_in); tdbpp;
+ tdbpp = TAILQ_FIRST(&tdbp->tdb_bind_in))
+ {
+ TAILQ_REMOVE(&tdbpp->tdb_bind_in, tdbpp, tdb_bind_in_next);
+ tdbpp->tdb_bind_out = NULL;
+ }
+ /* Cleanup inp references */
+ for (inp = TAILQ_FIRST(&tdbp->tdb_inp); inp;
+ inp = TAILQ_FIRST(&tdbp->tdb_inp))
+ {
+ TAILQ_REMOVE(&tdbp->tdb_inp, inp, inp_tdb_next);
+ inp->inp_tdb = NULL;
+ }
+
+ if (tdbp->tdb_bind_out)
+ TAILQ_REMOVE(&tdbp->tdb_bind_out->tdb_bind_in, tdbp, tdb_bind_in_next);
+
/* removal of a larval SA should not remove the mature SA's expirations */
if ((tdbp->tdb_flags & TDBF_INVALID) == 0)
cleanup_expirations(&tdbp->tdb_dst, tdbp->tdb_spi, tdbp->tdb_sproto);
@@ -733,6 +772,10 @@ tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
tdbp->tdb_established = time.tv_sec;
tdbp->tdb_epoch = kernfs_epoch - 1;
+ /* Init Incoming SA-Binding Queues */
+ TAILQ_INIT(&tdbp->tdb_bind_in);
+ TAILQ_INIT(&tdbp->tdb_inp);
+
for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++)
if (xsp->xf_type == alg)
return (*(xsp->xf_init))(tdbp, xsp, ii);
@@ -752,7 +795,7 @@ ipsp_kern(int off, char **bufp, int len)
{
static char buffer[IPSEC_KERNFS_BUFSIZE];
struct flow *flow;
- struct tdb *tdb;
+ struct tdb *tdb, *tdbp;
int l, i;
if (off == 0)
@@ -866,6 +909,22 @@ ipsp_kern(int off, char **bufp, int len)
l += sprintf(buffer + l, "\t\tAuthentication = <%s>\n",
tdb->tdb_authalgxform->name);
+ if (tdb->tdb_bind_out)
+ l += sprintf(buffer + l,
+ "\tBound SA: SPI = %08x, "
+ "Destination = %s, Sproto = %u\n",
+ ntohl(tdb->tdb_bind_out->tdb_spi),
+ ipsp_address(tdb->tdb_bind_out->tdb_dst),
+ tdb->tdb_bind_out->tdb_sproto);
+ for (i = 0, tdbp = TAILQ_FIRST(&tdb->tdb_bind_in); tdbp;
+ tdbp = TAILQ_NEXT(tdbp, tdb_bind_in_next))
+ i++;
+
+ if (i > 0)
+ l += sprintf(buffer + l,
+ "\tReferenced by %d incoming SA%s\n",
+ i, i == 1 ? "" : "s");
+
if (tdb->tdb_onext)
l += sprintf(buffer + l,
"\tNext SA: SPI = %08x, "
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index f0048366b3c..e963410849f 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.27 1999/02/25 01:30:49 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.28 1999/03/27 21:04:19 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -43,6 +43,7 @@
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <netinet/in.h>
#include <sys/md5k.h>
#include <netinet/ip_sha1.h>
@@ -283,10 +284,21 @@ struct tdb /* tunnel descriptor block */
u_int16_t tdb_dstid_type;
struct flow *tdb_flow; /* Which flows use this SA */
+
+ struct tdb *tdb_bind_out; /* Outgoing SA to use */
+ TAILQ_HEAD(tdb_bind_head, tdb) tdb_bind_in;
+ TAILQ_ENTRY(tdb) tdb_bind_in_next; /* Refering Incoming SAs */
+ TAILQ_HEAD(tdb_inp_head, inpcb) tdb_inp;
};
#define TDB_HASHMOD 257
+struct tdb_ident {
+ u_int32_t spi;
+ union sockaddr_union dst;
+ u_int8_t proto;
+};
+
struct auth_hash {
int type;
char *name;
@@ -418,6 +430,7 @@ extern char *inet_ntoa4(struct in_addr);
extern char *ipsp_address(union sockaddr_union);
/* TDB management routines */
+extern void tdb_add_inp(struct tdb *tdb, struct inpcb *inp);
extern u_int32_t reserve_spi(u_int32_t, u_int32_t, union sockaddr_union *,
union sockaddr_union *, u_int8_t, int *);
extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t);
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 311806ea3d8..0c0400c0c1a 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.43 1999/03/24 17:00:47 niklas Exp $ */
+/* $OpenBSD: ip_output.c,v 1.44 1999/03/27 21:04:20 provos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -167,8 +167,7 @@ ip_output(m0, va_alist)
/*
* Check if the packet needs encapsulation
*/
- if ((ipsec_in_use != 0) &&
- !(flags & IP_ENCAPSULATED) &&
+ if (!(flags & IP_ENCAPSULATED) &&
(inp == NULL ||
(inp->inp_seclevel[SL_AUTH] != IPSEC_LEVEL_BYPASS ||
inp->inp_seclevel[SL_ESP_TRANS] != IPSEC_LEVEL_BYPASS ||
@@ -184,6 +183,20 @@ ip_output(m0, va_alist)
sa_require = inp->inp_secrequire;
bzero((caddr_t) re, sizeof(*re));
+
+ /* Check if there was a bound outgoing SA */
+ if (inp && inp->inp_tdb &&
+ (inp->inp_tdb->tdb_dst.sin.sin_addr.s_addr ==
+ INADDR_ANY ||
+ !bcmp(&inp->inp_tdb->tdb_dst.sin.sin_addr,
+ &ip->ip_dst, sizeof(ip->ip_dst)))) {
+ tdb = inp->inp_tdb;
+ goto have_tdb;
+ }
+
+ if (!ipsec_in_use)
+ goto no_encap;
+
ddst = (struct sockaddr_encap *) &re->re_dst;
ddst->sen_family = PF_KEY;
ddst->sen_len = SENT_IP4_LEN;
@@ -266,10 +279,6 @@ ip_output(m0, va_alist)
goto no_encap;
}
- ip->ip_len = htons((u_short)ip->ip_len);
- ip->ip_off = htons((u_short)ip->ip_off);
- ip->ip_sum = 0;
-
/*
* At this point we have an IPSP "gateway" (tunnel) spec.
* Use the destination of the tunnel and the SPI to
@@ -284,6 +293,12 @@ ip_output(m0, va_alist)
tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, &sunion,
gw->sen_ipsp_sproto);
+ have_tdb:
+
+ ip->ip_len = htons((u_short)ip->ip_len);
+ ip->ip_off = htons((u_short)ip->ip_off);
+ ip->ip_sum = 0;
+
/*
* Now we check if this tdb has all the transforms which
* are requried by the socket or our default policy.
@@ -354,7 +369,8 @@ ip_output(m0, va_alist)
if (tdb->tdb_flags & TDBF_INVALID) {
DPRINTF(("ip_output(): attempt to use invalid SA %s/%08x/%u\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), tdb->tdb_sproto));
m_freem(m);
- RTFREE(re->re_rt);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
return ENXIO;
}
@@ -389,6 +405,8 @@ ip_output(m0, va_alist)
/* Check for tunneling */
if (((tdb->tdb_dst.sin.sin_addr.s_addr !=
+ INADDR_ANY &&
+ tdb->tdb_dst.sin.sin_addr.s_addr !=
ip->ip_dst.s_addr) ||
(tdb->tdb_flags & TDBF_TUNNELING)) &&
(tdb->tdb_xform->xf_type != XF_IP4))
@@ -404,7 +422,8 @@ ip_output(m0, va_alist)
if (mp == NULL)
error = EFAULT;
if (error) {
- RTFREE(re->re_rt);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
return error;
}
m = mp;
@@ -427,7 +446,8 @@ ip_output(m0, va_alist)
if (error) {
if (mp != NULL)
m_freem(mp);
- RTFREE(re->re_rt);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
return error;
}
@@ -444,7 +464,8 @@ ip_output(m0, va_alist)
* processed packet. Call ourselves recursively, but
* bypass the encap code.
*/
- RTFREE(re->re_rt);
+ if (re->re_rt)
+ RTFREE(re->re_rt);
ip = mtod(m, struct ip *);
NTOHS(ip->ip_len);
NTOHS(ip->ip_off);
@@ -953,6 +974,28 @@ ip_ctloutput(op, so, level, optname, mp)
}
}
break;
+ case IPSEC_OUTSA:
+#ifndef IPSEC
+ error = EINVAL;
+#else
+ if (m == 0 || m->m_len != sizeof(struct tdb_ident)) {
+ error = EINVAL;
+ break;
+ } else {
+ struct tdb *tdb;
+ struct tdb_ident *tdbi;
+
+ tdbi = mtod(m, struct tdb_ident *);
+ tdb = gettdb(tdbi->spi, &tdbi->dst,
+ tdbi->proto);
+ if (tdb == NULL) {
+ error = ESRCH;
+ break;
+ }
+ tdb_add_inp(tdb, inp);
+ }
+#endif /* IPSEC */
+ break;
case IP_AUTH_LEVEL:
case IP_ESP_TRANS_LEVEL:
@@ -1082,6 +1125,26 @@ ip_ctloutput(op, so, level, optname, mp)
*mtod(m, int *) = optval;
break;
+ case IPSEC_OUTSA:
+#ifndef IPSEC
+ error = EINVAL;
+#else
+ if (inp->inp_tdb == NULL) {
+ error = ENOENT;
+ break;
+ } else {
+ struct tdb_ident tdbi;
+ tdbi.spi = inp->inp_tdb->tdb_spi;
+ tdbi.dst = inp->inp_tdb->tdb_dst;
+ tdbi.proto = inp->inp_tdb->tdb_sproto;
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(tdbi);
+ bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
+ (unsigned)m->m_len);
+ }
+#endif /* IPSEC */
+ break;
+
case IP_AUTH_LEVEL:
case IP_ESP_TRANS_LEVEL:
case IP_ESP_NETWORK_LEVEL:
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 1bb0da1d16e..59086ee521b 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.32 1999/02/15 02:39:02 provos Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.33 1999/03/27 21:04:20 provos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -77,6 +77,10 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#include <machine/stdarg.h>
#include <sys/md5k.h>
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+#endif /* IPSEC */
+
#ifdef INET6
#include <sys/domain.h>
#include <netinet6/in6_var.h>
@@ -437,6 +441,9 @@ tcp_input(m, va_alist)
int iphlen;
va_list ap;
register struct tcphdr *th;
+#ifdef IPSEC
+ struct tdb *tdb = NULL;
+#endif /* IPSEC */
#ifdef INET6
struct in6_addr laddr6;
unsigned short is_ipv6; /* Type of incoming datagram. */
@@ -449,6 +456,15 @@ tcp_input(m, va_alist)
tcpstat.tcps_rcvtotal++;
+#ifdef IPSEC
+ /* Save the last SA which was used to process the mbuf */
+ if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
+ struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
+#endif /* IPSEC */
#ifdef INET6
/*
* Before we do ANYTHING, we have to figure out if it's TCP/IPv6 or
@@ -683,6 +699,18 @@ findpcb:
* we're committed to it below in TCPS_LISTEN.
*/
dropsocket++;
+#ifdef IPSEC
+ /*
+ * We need to copy the required security levels
+ * from the old pcb.
+ */
+ {
+ struct inpcb *newinp = (struct inpcb *)so->so_pcb;
+ bcopy(inp->inp_seclevel, newinp->inp_seclevel,
+ sizeof(inp->inp_seclevel));
+ newinp->inp_secrequire = inp->inp_secrequire;
+ }
+#endif /* IPSEC */
#ifdef INET6
/*
* inp still has the OLD in_pcb stuff, set the
@@ -748,6 +776,28 @@ findpcb:
}
}
+#ifdef IPSEC
+ /* Check if this socket requires security for incoming packets */
+ if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_AUTH)) ||
+ (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_CONF))) {
+#ifdef notyet
+#ifdef INET6
+ if (is_ipv6)
+ ipv6_icmp_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
+ else
+#endif /* INET6 */
+ icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
+#endif /* notyet */
+ tcpstat.tcps_rcvnosec++;
+ goto drop;
+ }
+ /* Use tdb_bind_out for this inp's outbound communication */
+ if (tdb)
+ tdb_add_inp(tdb, inp);
+#endif /*IPSEC */
+
/*
* Segment received on connection.
* Reset idle time and keep-alive timer.
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index c4c1b2213ec..f7ac9a841b3 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.18 1999/02/04 16:12:13 deraadt Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.19 1999/03/27 21:04:21 provos Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -244,6 +244,7 @@ struct tcpstat {
u_int32_t tcps_rcvbadsum; /* packets received with ccksum errs */
u_int32_t tcps_rcvbadoff; /* packets received with bad offset */
u_int32_t tcps_rcvmemdrop; /* packets dropped for lack of memory */
+ u_int32_t tcps_rcvnosec; /* packets dropped for lack of ipsec */
u_int32_t tcps_rcvshort; /* packets received too short */
u_int32_t tcps_rcvduppack; /* duplicate-only packets received */
u_int64_t tcps_rcvdupbyte; /* duplicate-only bytes received */
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 48805a76134..ce04a080ad8 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.24 1999/03/24 02:59:06 cmetz Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.25 1999/03/27 21:04:20 provos Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -76,6 +76,8 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#include <netinet/udp_var.h>
#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+
extern int check_ipsec_policy __P((struct inpcb *, u_int32_t));
#endif
@@ -147,6 +149,9 @@ udp_input(m, va_alist)
struct ipv6 *ipv6;
struct sockaddr_in6 src_v4mapped;
#endif /* INET6 */
+#ifdef IPSEC
+ struct tdb *tdb = NULL;
+#endif /* IPSEC */
va_start(ap, m);
iphlen = va_arg(ap, int);
@@ -154,6 +159,16 @@ udp_input(m, va_alist)
udpstat.udps_ipackets++;
+#ifdef IPSEC
+ /* Save the last SA which was used to process the mbuf */
+ if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
+ struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
+#endif /* IPSEC */
+
switch (mtod(m, struct ip *)->ip_v) {
case 4:
ip = mtod(m, struct ip *);
@@ -485,6 +500,28 @@ udp_input(m, va_alist)
}
}
+#ifdef IPSEC
+ /* Check if this socket requires security for incoming packets */
+ if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_AUTH)) ||
+ (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
+ !(m->m_flags & M_CONF))) {
+#ifdef notyet
+#ifdef INET6
+ if (ipv6)
+ ipv6_icmp_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
+ else
+#endif /* INET6 */
+ icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
+#endif /* notyet */
+ udpstat.udps_nosec++;
+ goto bad;
+ }
+ /* Use tdb_bind_out for this inp's outbound communication */
+ if (tdb)
+ tdb_add_inp(tdb, inp);
+#endif /*IPSEC */
+
if (inp->inp_flags & INP_CONTROLOPTS) {
struct mbuf **mp = &opts;
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index f41b8aa10b5..afc23036d32 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_var.h,v 1.7 1999/02/04 16:05:02 deraadt Exp $ */
+/* $OpenBSD: udp_var.h,v 1.8 1999/03/27 21:04:21 provos Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
@@ -62,6 +62,7 @@ struct udpstat {
u_long udps_badlen; /* data length larger than packet */
u_long udps_noport; /* no socket on port */
u_long udps_noportbcast; /* of above, arrived as broadcast */
+ u_long udps_nosec; /* dropped for lack of ipsec */
u_long udps_fullsock; /* not delivered, input socket full */
u_long udps_pcbhashmiss; /* input packets missing pcb hash */
/* output statistics: */
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index e02ebf70f95..62ba4bdc873 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbuf.h,v 1.9 1999/01/07 22:33:31 deraadt Exp $ */
+/* $OpenBSD: mbuf.h,v 1.10 1999/03/27 21:04:21 provos Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@@ -80,6 +80,8 @@ struct m_hdr {
struct pkthdr {
struct ifnet *rcvif; /* rcv interface */
int len; /* total packet length */
+ void *tdbi; /* pointer to struct tdb_ident */
+ /* XXX - pull in ip_ipsp.h */
};
/* description of external storage mapped into mbuf, valid if M_EXT set */
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 2ce10641a2d..9f56f9f41c0 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inet.c,v 1.30 1999/02/24 22:57:34 angelos Exp $ */
+/* $OpenBSD: inet.c,v 1.31 1999/03/27 21:04:21 provos Exp $ */
/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
#else
-static char *rcsid = "$OpenBSD: inet.c,v 1.30 1999/02/24 22:57:34 angelos Exp $";
+static char *rcsid = "$OpenBSD: inet.c,v 1.31 1999/03/27 21:04:21 provos Exp $";
#endif
#endif /* not lint */
@@ -226,6 +226,7 @@ tcp_stats(off, name)
p(tcps_rcvbadsum, "\t\t%ld discarded for bad checksum%s\n");
p(tcps_rcvbadoff, "\t\t%ld discarded for bad header offset field%s\n");
p(tcps_rcvshort, "\t\t%ld discarded because packet too short\n");
+ p(tcps_rcvnosec, "\t\t%ld discarded for missing IPSec protection\n");
p(tcps_connattempt, "\t%ld connection request%s\n");
p(tcps_accepts, "\t%ld connection accept%s\n");
p(tcps_connects, "\t%ld connection%s established (including accepts)\n");
@@ -273,6 +274,7 @@ udp_stats(off, name)
p(udps_nosum, "\t%lu with no checksum\n");
p(udps_noport, "\t%lu dropped due to no socket\n");
p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
+ p(udps_nosec, "\t%lu dropped due to missing IPSec protection\n");
p(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
delivered = udpstat.udps_ipackets -
udpstat.udps_hdrops -