summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/encap.c326
-rw-r--r--sys/net/encap.h276
-rw-r--r--sys/net/if_enc.c254
3 files changed, 391 insertions, 465 deletions
diff --git a/sys/net/encap.c b/sys/net/encap.c
index 898ff599dcf..ae2de47222a 100644
--- a/sys/net/encap.c
+++ b/sys/net/encap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.c,v 1.5 1997/06/25 07:53:19 provos Exp $ */
+/* $OpenBSD: encap.c,v 1.6 1997/07/01 22:12:40 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -44,6 +44,7 @@
#include <net/encap.h>
#include <netinet/ip_ipsp.h>
+#include <netinet/ip_ip4.h>
extern struct ifnet loif;
@@ -51,7 +52,8 @@ extern int ipspkernfs_dirty;
void encap_init(void);
int encap_output __P((struct mbuf *, ...));
-int encap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *);
+int encap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *);
extern int tdb_init(struct tdb *, struct mbuf *);
@@ -89,10 +91,11 @@ encap_init()
/*ARGSUSED*/
int
-encap_usrreq(register struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control)
+encap_usrreq(register struct socket *so, int req, struct mbuf *m,
+ struct mbuf *nam, struct mbuf *control)
{
- register int error = 0;
register struct rawcb *rp = sotorawcb(so);
+ register int error = 0;
int s;
if (req == PRU_ATTACH)
@@ -133,16 +136,13 @@ va_dcl
#endif
{
#define SENDERR(e) do { error = e; goto flush;} while (0)
- struct socket *so;
- int len, emlen, error = 0, nspis, i;
+ int len, emlen, error = 0;
struct encap_msghdr *emp;
- struct ifnet *ifp;
- struct ifaddr *ifa;
- struct sockaddr_encap *sen, *sen2;
- struct sockaddr_in *sin;
- struct tdb *tdbp, *tprev;
- va_list ap;
+ struct tdb *tdbp, *tdbp2;
+ caddr_t buffer = 0;
+ struct socket *so;
u_int32_t spi;
+ va_list ap;
va_start(ap, m);
so = va_arg(ap, struct socket *);
@@ -156,75 +156,44 @@ va_dcl
panic("encap_output");
len = m->m_pkthdr.len;
+
emp = mtod(m, struct encap_msghdr *);
+
emlen = emp->em_msglen;
if ((len < emlen))
SENDERR(EINVAL);
if (m->m_len < emlen)
{
- m = m_pullup(m, emlen);
- if (m == NULL)
+ MALLOC(buffer, caddr_t, emlen, M_TEMP, M_WAITOK);
+ if (buffer == 0)
SENDERR(ENOBUFS);
-
- emp = mtod(m, struct encap_msghdr *);
+
+ m_copydata(m, 0, emlen, buffer);
+
+ emp = (struct encap_msghdr *) buffer;
}
+ if (emp->em_version != PFENCAP_VERSION_1)
+ SENDERR(EINVAL);
+
switch (emp->em_type)
{
- case EMT_IFADDR:
- if (emp->em_ifn >= nencap)
- SENDERR(ENODEV);
-
- /*
- * Set the default source address for an encap interface
- */
-
- ifp = &(enc_softc[emp->em_ifn].enc_if);
-
- if ((ifp->if_addrlist.tqh_first == NULL) ||
- (ifp->if_addrlist.tqh_first->ifa_addr == NULL) ||
- (ifp->if_addrlist.tqh_first->ifa_addr->sa_family != AF_ENCAP))
- {
- MALLOC(ifa, struct ifaddr *, sizeof (struct ifaddr) +
- 2 * SENT_DEFIF_LEN, M_IFADDR, M_WAITOK);
- if (ifa == NULL)
- SENDERR(ENOBUFS);
-
- bzero((caddr_t)ifa, sizeof (struct ifaddr) +
- 2 * SENT_DEFIF_LEN);
- sen = (struct sockaddr_encap *)(ifa + 1);
- sen2 = (struct sockaddr_encap *)((caddr_t)sen +
- SENT_DEFIF_LEN);
- ifa->ifa_addr = (struct sockaddr *)sen;
- ifa->ifa_dstaddr = (struct sockaddr *)sen2;
- ifa->ifa_ifp = ifp;
- TAILQ_INSERT_HEAD(&(ifp->if_addrlist), ifa, ifa_list);
- }
- else
- {
- sen = (struct sockaddr_encap *)((&(ifp->if_addrlist))->tqh_first->ifa_addr);
- sen2 = (struct sockaddr_encap *)((&(ifp->if_addrlist))->tqh_first->ifa_dstaddr);
- }
-
- sen->sen_family = AF_ENCAP;
- sen->sen_len = SENT_DEFIF_LEN;
- sen->sen_type = SENT_DEFIF;
- sin = (struct sockaddr_in *) &(sen->sen_dfl);
- sin->sin_len = sizeof(*sin);
- sin->sin_family = AF_INET;
- sin->sin_addr = emp->em_ifa;
-
- *sen2 = *sen;
-
- break;
-
case EMT_SETSPI:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
+ if (emlen <= EMT_SETSPI_FLEN)
+ SENDERR(EINVAL);
+
tdbp = gettdb(emp->em_spi, emp->em_dst);
if (tdbp == NULL)
{
+ /*
+ * If only one of the two outter addresses is set, return
+ * error.
+ */
+ if ((emp->em_osrc.s_addr != 0) ^
+ (emp->em_odst.s_addr != 0))
+ SENDERR(EINVAL);
+
MALLOC(tdbp, struct tdb *, sizeof (*tdbp), M_TDB, M_WAITOK);
if (tdbp == NULL)
SENDERR(ENOBUFS);
@@ -233,8 +202,38 @@ va_dcl
tdbp->tdb_spi = emp->em_spi;
tdbp->tdb_dst = emp->em_dst;
- tdbp->tdb_rcvif = &(enc_softc[emp->em_if].enc_if);
+ tdbp->tdb_proto = emp->em_proto;
+ tdbp->tdb_sport = emp->em_sport;
+ tdbp->tdb_dport = emp->em_dport;
+
+ tdbp->tdb_src = emp->em_src;
+
+ /* Check if this is an encapsulating SPI */
+ if (emp->em_osrc.s_addr != 0)
+ {
+ tdbp->tdb_flags |= TDBF_TUNNELING;
+ tdbp->tdb_osrc = emp->em_osrc;
+ tdbp->tdb_odst = emp->em_odst;
+
+ /* TTL */
+ switch (emp->em_ttl)
+ {
+ case IP4_DEFAULT_TTL:
+ tdbp->tdb_ttl = 0;
+ break;
+
+ case IP4_SAME_TTL:
+ tdbp->tdb_flags |= TDBF_SAME_TTL;
+ break;
+
+ default:
+ /* Get just the least significant bits */
+ tdbp->tdb_ttl = emp->em_ttl % 256;
+ break;
+ }
+ }
+
puttdb(tdbp);
}
else
@@ -302,82 +301,77 @@ va_dcl
}
error = tdb_init(tdbp, m);
+ if (error)
+ SENDERR(EINVAL);
+
ipspkernfs_dirty = 1;
+
break;
case EMT_DELSPI:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_DELSPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
- {
- error = EINVAL;
- break;
- }
-
- if (emp->em_alg != tdbp->tdb_xform->xf_type)
- {
- error = EINVAL;
- break;
- }
-
+ SENDERR(ENOENT);
+
error = tdb_delete(tdbp, 0);
+ if (error)
+ SENDERR(EINVAL);
+
break;
case EMT_DELSPICHAIN:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
- tdbp = gettdb(emp->em_spi, emp->em_dst);
- if (tdbp == NULL)
- {
- error = EINVAL;
- break;
- }
-
- if (emp->em_alg != tdbp->tdb_xform->xf_type)
- {
- error = EINVAL;
- break;
- }
+ if (emlen != EMT_DELSPICHAIN_FLEN)
+ SENDERR(EINVAL);
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
+ if (tdbp == NULL)
+ SENDERR(ENOENT);
+
error = tdb_delete(tdbp, 1);
+ if (error)
+ SENDERR(EINVAL);
+
break;
case EMT_GRPSPIS:
- nspis = (emlen - 4) / 12;
- if (nspis * 12 + 4 != emlen)
+ if (emlen != EMT_GRPSPIS_FLEN)
SENDERR(EINVAL);
- for (i = 0; i < nspis; i++)
- if ((tdbp = gettdb(emp->em_rel[i].emr_spi, emp->em_rel[i].emr_dst)) == NULL)
- SENDERR(ENOENT);
- else
- emp->em_rel[i].emr_tdb = tdbp;
+ tdbp = gettdb(emp->em_rel_spi, emp->em_rel_dst);
+ if (tdbp == NULL)
+ SENDERR(ENOENT);
- tprev = emp->em_rel[0].emr_tdb;
- tprev->tdb_inext = NULL;
- for (i = 1; i < nspis; i++)
- {
- tdbp = emp->em_rel[i].emr_tdb;
- tprev->tdb_onext = tdbp;
- tdbp->tdb_inext = tprev;
- tprev = tdbp;
- }
- tprev->tdb_onext = NULL;
+ tdbp2 = gettdb(emp->em_rel_spi2, emp->em_rel_dst2);
+ if (tdbp2 == NULL)
+ SENDERR(ENOENT);
+
+ tdbp->tdb_onext = tdbp2;
+ tdbp2->tdb_inext = tdbp;
+
ipspkernfs_dirty = 1;
error = 0;
break;
case EMT_RESERVESPI:
- spi = reserve_spi(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_RESERVESPI_FLEN)
+ SENDERR(EINVAL);
+
+ spi = reserve_spi(emp->em_gen_spi, emp->em_gen_dst);
if (spi == 0)
- if (emp->em_spi == 0)
+ if (emp->em_gen_spi == 0)
SENDERR(ENOBUFS);
else
SENDERR(EINVAL);
- emp->em_spi = spi;
+ emp->em_gen_spi = spi;
+ /* If we're using a buffer, copy the data back to the mbuf */
+ if (buffer)
+ m_copyback(m, 0, emlen, buffer);
+
/* Send it back to us */
if (sbappendaddr(&so->so_rcv, &encap_src, m,
(struct mbuf *)0) == 0)
@@ -390,114 +384,66 @@ va_dcl
break;
case EMT_ENABLESPI:
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_ENABLESPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
SENDERR(ENOENT);
/* Clear the INVALID flag */
tdbp->tdb_flags &= (~TDBF_INVALID);
+
error = 0;
break;
case EMT_DISABLESPI:
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_DISABLESPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
SENDERR(ENOENT);
/* Set the INVALID flag */
tdbp->tdb_flags |= TDBF_INVALID;
+
error = 0;
break;
+
+ case EMT_NOTIFY:
+ if (emlen <= EMT_NOTIFY_FLEN)
+ SENDERR(EINVAL);
+
+ /* XXX Not yet finished */
+
+ SENDERR(EINVAL);
+
+ break;
default:
SENDERR(EINVAL);
}
+ if (buffer)
+ free(buffer, M_TEMP);
+
return error;
flush:
if (m)
m_freem(m);
+
+ if (buffer)
+ free(buffer, M_TEMP);
+
return error;
}
struct ifaddr *
encap_findgwifa(struct sockaddr *gw)
{
- struct sockaddr_encap *egw = (struct sockaddr_encap *)gw;
- u_char *op = (u_char *)gw;
- int i, j;
- struct ifaddr *retval = loif.if_addrlist.tqh_first;
- union
- {
- struct in_addr ia;
- u_char io[4];
- } iao;
-
- switch (egw->sen_type)
- {
- case SENT_IPSP:
- return enc_softc[egw->sen_ipsp_ifn].enc_if.if_addrlist.tqh_first;
- break;
-
- case SENT_IP4:
- /*
- * Pretty-much standard options walking code.
- * Repeated elsewhere as necessary
- */
-
- for (i = SENT_IP4_LEN; i < egw->sen_len;)
- switch (op[i])
- {
- case SENO_EOL:
- goto opt_done;
-
- case SENO_NOP:
- i++;
- continue;
-
- case SENO_IFN:
- if (op[i+1] != 3)
- {
- return NULL;
- }
- retval = enc_softc[op[i+2]].enc_if.if_addrlist.tqh_first;
- goto opt_done;
-
- case SENO_IFIP4A:
- if (op[i+1] != 6) /* XXX -- IPv4 address */
- {
- return NULL;
- }
- iao.io[0] = op[i+2];
- iao.io[1] = op[i+3];
- iao.io[2] = op[i+4];
- iao.io[3] = op[i+5];
-
- for (j = 0; j < nencap; j++)
- {
- struct ifaddr *ia = (struct ifaddr *)enc_softc[j].enc_if.if_addrlist.tqh_first;
-
- struct sockaddr_in *si = (struct sockaddr_in *)ia->ifa_addr;
-
- if ((si->sin_family == AF_INET) && (si->sin_addr.s_addr == iao.ia.s_addr))
- {
- retval = ia;
- goto opt_done;
- }
- }
- i += 6;
- break;
-
- default:
- if (op[i+1] == 0)
- return NULL;
- i += op[i+i];
- }
- opt_done:
- break;
- }
- return retval;
+ return enc_softc.if_addrlist.tqh_first;
}
diff --git a/sys/net/encap.h b/sys/net/encap.h
index d5b28c8a942..7305abd2a33 100644
--- a/sys/net/encap.h
+++ b/sys/net/encap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.h,v 1.4 1997/06/25 07:53:20 provos Exp $ */
+/* $OpenBSD: encap.h,v 1.5 1997/07/01 22:12:40 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -46,7 +46,6 @@
* as far as the routing code is concerned.
*/
-
struct sockaddr_encap
{
u_int8_t sen_len; /* length */
@@ -55,19 +54,8 @@ struct sockaddr_encap
union
{
u_int8_t Data[16]; /* other stuff mapped here */
- struct sockaddr Dfl; /* SENT_DEFIF */
- struct /* SENT_SA */
- {
- struct sockaddr Src;
- struct sockaddr Dst;
- } Sa;
-#ifdef INET
- struct /* SENT_SAIN */
- {
- struct sockaddr_in Src;
- struct sockaddr_in Dst;
- } Sin;
- struct /* SENT_IP4 */
+
+ struct /* SENT_IP4 */
{
struct in_addr Src;
struct in_addr Dst;
@@ -76,36 +64,27 @@ struct sockaddr_encap
u_int8_t Proto;
u_int8_t Filler[3];
} Sip4;
- struct /* SENT_IPSP */
+
+ struct /* SENT_IPSP */
{
- struct in_addr Src;
struct in_addr Dst;
u_int32_t Spi;
- u_int8_t Ifn;
- u_int8_t Filler[3];
+ u_int8_t Filler[8];
} Sipsp;
-
-#endif
} Sen;
};
+#define PFENCAP_VERSION_0 0
+#define PFENCAP_VERSION_1 1
+
#define sen_data Sen.Data
-#define sen_dfl Sen.Dfl
-#define sen_sa_src Sen.Sa.Src
-#define sen_sa_dst Sen.Sa.Dst
-#ifdef INET
-#define sen_sin_src Sen.Sin.Src
-#define sen_sin_dst Sen.Sin.Dst
#define sen_ip_src Sen.Sip4.Src
#define sen_ip_dst Sen.Sip4.Dst
-#define sen_ipsp_src Sen.Sipsp.Src
-#define sen_ipsp_dst Sen.Sipsp.Dst
-#define sen_ipsp_spi Sen.Sipsp.Spi
-#define sen_ipsp_ifn Sen.Sipsp.Ifn
#define sen_proto Sen.Sip4.Proto
#define sen_sport Sen.Sip4.Sport
#define sen_dport Sen.Sip4.Dport
-#endif
+#define sen_ipsp_dst Sen.Sipsp.Dst
+#define sen_ipsp_spi Sen.Sipsp.Spi
/*
* The "type" is really part of the address as far as the routing
@@ -115,11 +94,8 @@ struct sockaddr_encap
*
*/
-#define SENT_DEFIF 0x0001 /* data is a default sockaddr for if */
-#define SENT_SA 0x0002 /* data is two struct sockaddr */
-#define SENT_SAIN 0x0004 /* data is two struct sockaddr_in */
-#define SENT_IP4 0x0008 /* data is two struct in_addr */
-#define SENT_IPSP 0x0010 /* data as in IP4 plus SPI and if# */
+#define SENT_IP4 0x0001 /* data is two struct in_addr */
+#define SENT_IPSP 0x0002 /* data as in IP4 plus SPI */
/*
* SENT_HDRLEN is the length of the "header"
@@ -127,79 +103,67 @@ struct sockaddr_encap
* SENT_*_OFF are the offsets in the sen_data array of various fields
*/
-#define SENT_HDRLEN (2*sizeof(u_int8_t)+sizeof(u_int16_t))
-
-#define SENT_DEFIF_LEN (SENT_HDRLEN + sizeof (struct sockaddr_in))
+#define SENT_HDRLEN (2 * sizeof(u_int8_t) + sizeof(u_int16_t))
#define SENT_IP4_SRCOFF (0)
#define SENT_IP4_DSTOFF (sizeof (struct in_addr))
-#define SENT_IP4_OPTOFF (2*sizeof(struct in_addr)+2*sizeof(u_int16_t)+sizeof(u_int8_t)+3*sizeof(u_int8_t))
-
-#define SENT_IP4_LEN (SENT_HDRLEN + SENT_IP4_OPTOFF)
-
-#define SENT_IPSP_LEN (SENT_HDRLEN + 2 * sizeof (struct in_addr) + sizeof (u_int32_t) + 4)
-
-/*
- * Options 0x00 and 01 are 1-byte options (no arguments).
- * The rest of the options are T-L-V fields, where the L includes
- * the T and L bytes; thus, the minimum length for an option with
- * no arguments is 2. An option of length less than 2 causes en EINVAL
- */
-
-#define SENO_EOL 0x00 /* End of Options, or placeholder */
-#define SENO_NOP 0x01 /* No Operation. Skip */
-#define SENO_NAME 0x02 /* tunnel name, NUL-terminated */
-#define SENO_SPI 0x03 /* Security Parameters Index */
-#define SENO_IFN 0x04 /* Encap interface number */
-#define SENO_IFIP4A 0x05 /* Encap interface IPv4 address */
-#define SENO_IPSA 0x06 /* Encap interface generic sockaddr */
-
-struct enc_softc
-{
- struct ifnet enc_if;
-};
+#define SENT_IP4_LEN 20
+#define SENT_IPSP_LEN 20
/*
* Tunnel descriptors are setup and torn down using a socket of the
* AF_ENCAP domain. The following defines the messages that can
* be sent down that socket.
*/
-
-#define EM_MAXRELSPIS 4 /* at most five chained xforms */
-
-
struct encap_msghdr
{
u_int16_t em_msglen; /* message length */
u_int8_t em_version; /* for future expansion */
u_int8_t em_type; /* message type */
+ u_int32_t foo; /* Alignment to 64 bit */
union
{
+ /*
+ * This is used to set/change the attributes of an SPI. If oSrc and
+ * oDst are set to non-zero values, the SPI will also do IP-in-IP
+ * encapsulation (tunneling). If only one of them is set, an error
+ * is returned. Both zero implies transport mode.
+ */
struct
{
- struct in_addr Ia;
- u_int8_t Ifn;
- u_int8_t xxx[3]; /* makes life a lot easier */
- } Ifa;
-
- struct
- {
- u_int32_t Spi; /* SPI */
+ u_int32_t Spi; /* SPI */
+ int32_t Alg; /* Algorithm to use */
struct in_addr Dst; /* Destination address */
- u_int64_t Relative_Hard; /* Expire relative to creation */
- u_int64_t Relative_Soft;
- u_int64_t First_Use_Hard; /* Expire relative to first use */
- u_int64_t First_Use_Soft;
- u_int64_t Expire_Hard; /* Expire at fixed point in time */
- u_int64_t Expire_Soft;
- u_int64_t Bytes_Hard; /* Expire after bytes recved/sent */
- u_int64_t Bytes_Soft;
- u_int64_t Packets_Hard; /* Expire after packets recved/sent */
- u_int64_t Packets_Soft;
- u_int32_t If; /* enc i/f for input */
- int32_t Alg; /* Algorithm to use */
- u_int8_t Dat[1]; /* Data */
+ struct in_addr Src; /* This is used to set our source
+ * address when doing tunneling and
+ * the outgoing packet does not
+ * have a source address (is zero) */
+ struct in_addr oSrc; /* Source... */
+ struct in_addr oDst; /* ...and destination in outter IP
+ * header, if we're doing IP-in-IP */
+ u_int64_t Relative_Hard; /* Expire relative to creation */
+ u_int64_t Relative_Soft;
+ u_int64_t First_Use_Hard; /* Expire relative to first use */
+ u_int64_t First_Use_Soft;
+ u_int64_t Expire_Hard; /* Expire at fixed point in time */
+ u_int64_t Expire_Soft;
+ u_int64_t Bytes_Hard; /* Expire after bytes recved/sent */
+ u_int64_t Bytes_Soft;
+ u_int64_t Packets_Hard; /* Expire after packets recved/sent */
+ u_int64_t Packets_Soft;
+ int32_t TTL; /* When tunneling, what TTL to use.
+ * If set to IP4_SAME_TTL, the ttl
+ * from the encapsulated packet will
+ * be copied. If set to IP4_DEFAULT_TTL,
+ * the system default TTL will be used.
+ * If set to anything else, then the
+ * ttl used will be TTL % 256 */
+ u_int16_t Sport; /* Source port, if applicable */
+ u_int16_t Dport; /* Destination port, if applicable */
+ u_int8_t Proto; /* Protocol, if applicable */
+ u_int8_t foo[3]; /* Alignment */
+ u_int8_t Dat[1]; /* Data */
} Xfm;
/*
@@ -217,54 +181,65 @@ struct encap_msghdr
*/
struct /* kernel->userland notifications */
{
- u_int32_t Notification_Type;
-#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
-#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
-#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
- u_int32_t MsgID; /* Request ID */
- u_int32_t Spi;
- u_int32_t Spi2;
- u_int32_t Spi3;
- u_int8_t Seclevel[3]; /* see netinet/in_pcb.h */
- u_int8_t Protocol; /* Transport mode for which protocol */
+ u_int32_t Notification_Type;
+ u_int32_t MsgID; /* Request ID */
+ u_int32_t Spi;
+ u_int32_t Spi2;
+ u_int32_t Spi3;
+ u_int8_t Seclevel[3]; /* see netinet/in_pcb.h */
+ u_int8_t Protocol; /* Transport mode for which protocol */
struct in_addr Dst; /* Peer */
struct in_addr Src; /* Might have our local address */
- u_int16_t Sport; /* Source port */
- u_int16_t Dport; /* Destination port */
- u_int8_t UserID[1]; /* Might be used to indicate user */
+ u_int16_t Sport; /* Source port */
+ u_int16_t Dport; /* Destination port */
+ u_int8_t UserID[1]; /* Might be used to indicate user */
} Notify;
-
+
+ /* Link two SPIs */
struct
{
- u_int32_t emr_spi; /* SPI */
- struct in_addr emr_dst; /* Dest */
- struct tdb *emr_tdb; /* used internally! */
-
- } Rel[EM_MAXRELSPIS];
+ u_int32_t emr_spi; /* SPI */
+ u_int32_t emr_spi2;
+ struct in_addr emr_dst; /* Dest */
+ struct in_addr emr_dst2;
+ } Rel;
+
+ /* For general use */
+ struct
+ {
+ u_int32_t emg_spi;
+ struct in_addr emg_dst;
+ } Gen;
} Eu;
};
-#define em_not_type Eu.Notify.Notification_Type
-#define em_not_spi Eu.Notify.Spi
-#define em_not_spi2 Eu.Notify.Spi2
-#define em_not_spi3 Eu.Notify.Spi3
-#define em_not_src Eu.Notify.Src
-#define em_not_dst Eu.Notify.Dst
-#define em_not_seclevel Eu.Notify.Seclevel
-#define em_not_userid Eu.Notify.UserID
-#define em_not_msgid Eu.Notify.MsgID
-#define em_not_sport Eu.Notify.Sport
-#define em_not_dport Eu.Notify.Dport
-#define em_not_protocol Eu.Notify.Protocol
+#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
+#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
+#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
+
+#define em_gen_spi Eu.Gen.emg_spi
+#define em_gen_dst Eu.Gen.emg_dst
-#define em_ifa Eu.Ifa.Ia
-#define em_ifn Eu.Ifa.Ifn
+#define em_not_type Eu.Notify.Notification_Type
+#define em_not_spi Eu.Notify.Spi
+#define em_not_spi2 Eu.Notify.Spi2
+#define em_not_spi3 Eu.Notify.Spi3
+#define em_not_dst Eu.Notify.Dst
+#define em_not_seclevel Eu.Notify.Seclevel
+#define em_not_userid Eu.Notify.UserID
+#define em_not_msgid Eu.Notify.MsgID
+#define em_not_sport Eu.Notify.Sport
+#define em_not_dport Eu.Notify.Dport
+#define em_not_protocol Eu.Notify.Protocol
-#define em_spi Eu.Xfm.Spi
-#define em_dst Eu.Xfm.Dst
-#define em_if Eu.Xfm.If
-#define em_alg Eu.Xfm.Alg
-#define em_dat Eu.Xfm.Dat
+#define em_spi Eu.Xfm.Spi
+#define em_dst Eu.Xfm.Dst
+#define em_src Eu.Xfm.Src
+#define em_osrc Eu.Xfm.oSrc
+#define em_odst Eu.Xfm.oDst
+#define em_if Eu.Xfm.If
+#define em_alg Eu.Xfm.Alg
+#define em_dat Eu.Xfm.Dat
#define em_relative_hard Eu.Xfm.Relative_Hard
#define em_relative_soft Eu.Xfm.Relative_Soft
#define em_first_use_hard Eu.Xfm.First_Use_Hard
@@ -275,28 +250,37 @@ struct encap_msghdr
#define em_bytes_soft Eu.Xfm.Bytes_Soft
#define em_packets_hard Eu.Xfm.Packets_Hard
#define em_packets_soft Eu.Xfm.Packets_Soft
+#define em_ttl Eu.Xfm.TTL
+#define em_proto Eu.Xfm.Proto
+#define em_sport Eu.Xfm.Sport
+#define em_dport Eu.Xfm.Dport
-#define em_rel Eu.Rel
+#define em_rel_spi Eu.Rel.emr_spi
+#define em_rel_spi2 Eu.Rel.emr_spi2
+#define em_rel_dst Eu.Rel.emr_dst
+#define em_rel_dst2 Eu.Rel.emr_dst2
-#define EMT_IFADDR 1 /* set enc if addr */
-#define EMT_SETSPI 2 /* Set SPI properties */
-#define EMT_GRPSPIS 3 /* Group SPIs (output order) */
-#define EMT_DELSPI 4 /* delete an SPI */
-#define EMT_DELSPICHAIN 5 /* delete an SPI chain starting from */
-#define EMT_RESERVESPI 6 /* Give us an SPI */
-#define EMT_ENABLESPI 7 /* Enable an SA */
-#define EMT_DISABLESPI 8 /* Disable an SA */
-#define EMT_NOTIFY 9 /* kernel->userland key mgmt not. */
+#define EMT_SETSPI 1 /* Set SPI properties */
+#define EMT_GRPSPIS 2 /* Group SPIs (output order) */
+#define EMT_DELSPI 3 /* delete an SPI */
+#define EMT_DELSPICHAIN 4 /* delete an SPI chain starting from */
+#define EMT_RESERVESPI 5 /* Give us an SPI */
+#define EMT_ENABLESPI 6 /* Enable an SA */
+#define EMT_DISABLESPI 7 /* Disable an SA */
+#define EMT_NOTIFY 8 /* kernel->userland key mgmt not. */
-#define EM_MINLEN 8 /* count!!! */
-#define EMT_IFADDR_LEN 12
-#define EMT_SETSPI_FLEN 20
-#define EMT_GRPSPIS_FLEN 4
-#define EMT_DELSPI_FLEN 20
-#define EMT_DELSPICHAIN_FLEN 20
+/* Total packet lengths */
+#define EMT_SETSPI_FLEN 124
+#define EMT_GRPSPIS_FLEN 20
+#define EMT_GENLEN 12
+#define EMT_DELSPI_FLEN EMT_GENLEN
+#define EMT_DELSPICHAIN_FLEN EMT_GENLEN
+#define EMT_ENABLESPI_FLEN EMT_GENLEN
+#define EMT_DISABLESPI_FLEN EMT_GENLEN
+#define EMT_RESERVESPI_FLEN EMT_GENLEN
+#define EMT_NOTIFY_FLEN 40
#ifdef _KERNEL
extern struct ifaddr *encap_findgwifa(struct sockaddr *);
-extern struct enc_softc *enc_softc;
-extern int32_t nencap;
+extern struct ifnet enc_softc;
#endif
diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c
index 1f6d8e8509f..0f0cff17d8c 100644
--- a/sys/net/if_enc.c
+++ b/sys/net/if_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_enc.c,v 1.3 1997/02/27 04:05:45 angelos Exp $ */
+/* $OpenBSD: if_enc.c,v 1.4 1997/07/01 22:12:39 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -62,18 +62,7 @@ extern struct ifqueue nsintrq;
#define ENCMTU (1024+512)
-/*
- * Called from boot code to establish enc interfaces.
- */
-
-struct enc_softc
-{
- struct ifnet enc_if;
-} ;
-
-struct enc_softc *enc_softc;
-
-int nencap;
+struct ifnet enc_softc;
void encattach __P((int));
int encoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
@@ -84,30 +73,37 @@ void encrtrequest __P((int, struct rtentry *, struct sockaddr *));
void
encattach(int nenc)
{
- register struct enc_softc *enc;
- register int i = 0;
+ struct ifaddr *ifa;
+
+ bzero(&enc_softc, sizeof(struct ifnet));
+
+ /* We only need one interface anyway under the new mode of operation */
+ enc_softc.if_index = 0;
+
+ sprintf(enc_softc.if_xname, "enc0");
+
+ enc_softc.if_list.tqe_next = NULL;
+ enc_softc.if_mtu = ENCMTU;
+ enc_softc.if_flags = IFF_LOOPBACK;
+ enc_softc.if_type = IFT_ENC;
+ enc_softc.if_ioctl = encioctl;
+ enc_softc.if_output = encoutput;
+ enc_softc.if_hdrlen = 0;
+ enc_softc.if_addrlen = 0;
+
+ if_attach(&enc_softc);
- nencap = nenc;
-
- enc_softc = malloc(nenc * sizeof (*enc_softc), M_DEVBUF, M_WAIT);
- bzero(enc_softc, nenc * sizeof (*enc_softc));
- for (enc = enc_softc; i < nenc; enc++)
- {
- enc->enc_if.if_index = i;
- sprintf(enc->enc_if.if_xname, "enc%d", i++);
- enc->enc_if.if_list.tqe_next = NULL;
- enc->enc_if.if_mtu = ENCMTU;
- enc->enc_if.if_flags = IFF_LOOPBACK;
- enc->enc_if.if_type = IFT_ENC;
- enc->enc_if.if_ioctl = encioctl;
- enc->enc_if.if_output = encoutput;
- enc->enc_if.if_hdrlen = 0;
- enc->enc_if.if_addrlen = 0;
- if_attach(&enc->enc_if);
#if NBPFILTER > 0
- bpfattach(&enc->enc_if.if_bpf, &enc->enc_if, DLT_NULL, sizeof(u_int));
+ bpfattach(&(enc_softc.if_bpf), &enc_softc, DLT_NULL, sizeof(u_int32_t));
#endif
- }
+
+ /* Just a bogus entry */
+ ifa = (struct ifaddr *)malloc(sizeof(struct ifaddr) +
+ sizeof(struct sockaddr), M_IFADDR, M_WAITOK);
+ bzero(ifa, sizeof(struct ifaddr) + sizeof(struct sockaddr));
+ ifa->ifa_addr = ifa->ifa_dstaddr = (struct sockaddr *)(ifa + 1);
+ ifa->ifa_ifp = &enc_softc;
+ TAILQ_INSERT_HEAD(&(enc_softc.if_addrlist), ifa, ifa_list);
}
/*
@@ -120,93 +116,106 @@ register struct mbuf *m;
struct sockaddr *dst;
register struct rtentry *rt;
{
- int s, isr;
- register struct ifqueue *ifq = 0;
+ register struct ifqueue *ifq = 0;
+ int s, isr;
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("encoutput no HDR");
+
+ ifp->if_lastchange = time;
- /* register struct enc_softc *ec = &enc_softc[ifp->if_index]; */
-
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("encoutput no HDR");
- ifp->if_lastchange = time;
#if NBPFILTER > 0
- if (ifp->if_bpf) {
- /*
- * We need to prepend the address family as
- * a four byte field. Cons up a dummy header
- * to pacify bpf. This is safe because bpf
- * will only read from the mbuf (i.e., it won't
- * try to free it or keep a pointer a to it).
- */
- struct mbuf m0;
- u_int af = dst->sa_family;
-
- m0.m_next = m;
- m0.m_len = 4;
- m0.m_data = (char *)&af;
-
- bpf_mtap(ifp->if_bpf, &m0);
- }
+ if (ifp->if_bpf)
+ {
+ /*
+ * We need to prepend the address family as
+ * a four byte field. Cons up a dummy header
+ * to pacify bpf. This is safe because bpf
+ * will only read from the mbuf (i.e., it won't
+ * try to free it or keep a pointer a to it).
+ */
+ struct mbuf m0;
+ u_int af = dst->sa_family;
+
+ m0.m_next = m;
+ m0.m_len = 4;
+ m0.m_data = (char *)&af;
+
+ bpf_mtap(ifp->if_bpf, &m0);
+ }
#endif
- m->m_pkthdr.rcvif = ifp;
- if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
- m_freem(m);
- return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
- rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
- }
- ifp->if_opackets++;
- ifp->if_obytes += m->m_pkthdr.len;
- switch (dst->sa_family) {
+ m->m_pkthdr.rcvif = ifp;
+
+ if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE))
+ {
+ m_freem(m);
+ return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+ rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ }
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+
+ switch (dst->sa_family)
+ {
#ifdef INET
case AF_INET:
- ifq = &ipintrq;
- isr = NETISR_IP;
- break;
+ ifq = &ipintrq;
+ isr = NETISR_IP;
+ break;
#endif
#ifdef NS
case AF_NS:
- ifq = &nsintrq;
- isr = NETISR_NS;
- break;
+ ifq = &nsintrq;
+ isr = NETISR_NS;
+ break;
#endif
#ifdef ISO
case AF_ISO:
- ifq = &clnlintrq;
- isr = NETISR_ISO;
+ ifq = &clnlintrq;
+ isr = NETISR_ISO;
break;
#endif
default:
- m_freem(m);
- return (EAFNOSUPPORT);
- }
- s = splimp();
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- m_freem(m);
- splx(s);
- return (ENOBUFS);
- }
- IF_ENQUEUE(ifq, m);
- schednetisr(isr);
- ifp->if_ipackets++;
- ifp->if_ibytes += m->m_pkthdr.len;
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+
+ s = splimp();
+
+ if (IF_QFULL(ifq))
+ {
+ IF_DROP(ifq);
+ m_freem(m);
splx(s);
- return (0);
+ return (ENOBUFS);
+ }
+
+ IF_ENQUEUE(ifq, m);
+ schednetisr(isr);
+
+ /* Statistics */
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+
+ splx(s);
+
+ return (0);
}
/* ARGSUSED */
void
encrtrequest(cmd, rt, sa)
- int cmd;
- struct rtentry *rt;
- struct sockaddr *sa;
+int cmd;
+struct rtentry *rt;
+struct sockaddr *sa;
{
-
- if (rt)
- rt->rt_rmx.rmx_mtu = ENCMTU;
+ if (rt)
+ rt->rt_rmx.rmx_mtu = ENCMTU;
}
+
/*
* Process an ioctl request.
* Also shamelessly stolen from loioctl()
@@ -215,41 +224,28 @@ encrtrequest(cmd, rt, sa)
/* ARGSUSED */
int
encioctl(ifp, cmd, data)
- register struct ifnet *ifp;
- u_long cmd;
- caddr_t data;
+register struct ifnet *ifp;
+u_long cmd;
+caddr_t data;
{
- register struct ifaddr *ifa;
- register struct ifreq *ifr;
- register int error = 0;
-
- switch (cmd)
- {
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- ifa = (struct ifaddr *)data;
- /*
- * Everything else is done at a higher level.
- */
- break;
+ register struct ifaddr *ifa;
+ register int error = 0;
- switch (ifr->ifr_addr.sa_family) {
+ switch (cmd)
+ {
+ case SIOCSIFADDR:
+ /*
+ * Everything else is done at a higher level.
+ */
-#ifdef INET
- case AF_INET:
- break;
-#endif
- case AF_ENCAP:
- break;
-
- default:
- error = EAFNOSUPPORT;
- break;
- }
- break;
+ ifp->if_flags |= IFF_UP;
+ ifa = (struct ifaddr *)data;
+
+ break;
+
+ default:
+ error = EINVAL;
+ }
- default:
- error = EINVAL;
- }
- return error;
+ return error;
}