diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1997-07-01 22:12:54 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1997-07-01 22:12:54 +0000 |
commit | 170afa951af5e94eeb4a824da6b926603c094be2 (patch) | |
tree | b872ba634c7124715b485e7217b675eb6ffb4455 /sys/net | |
parent | 4baf2e1d61b5570ff1ad12415e822ea0a3d4f9f2 (diff) |
major restructuring
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/encap.c | 326 | ||||
-rw-r--r-- | sys/net/encap.h | 276 | ||||
-rw-r--r-- | sys/net/if_enc.c | 254 |
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 *)⁡ - - 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 *)⁡ + + 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; } |