diff options
-rw-r--r-- | sbin/ipsecadm/ipsecadm.c | 75 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 47 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 3 | ||||
-rw-r--r-- | sys/net/pfkeyv2_parsemessage.c | 8 | ||||
-rw-r--r-- | sys/netinet/in.h | 4 | ||||
-rw-r--r-- | sys/netinet/in_pcb.c | 4 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 5 | ||||
-rw-r--r-- | sys/netinet/ip_ah.c | 30 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 30 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 149 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 15 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 85 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 52 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 3 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 39 | ||||
-rw-r--r-- | sys/netinet/udp_var.h | 3 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 4 | ||||
-rw-r--r-- | usr.bin/netstat/inet.c | 6 |
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 - |