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 | |
parent | 4baf2e1d61b5570ff1ad12415e822ea0a3d4f9f2 (diff) |
major restructuring
Diffstat (limited to 'sys')
-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 | ||||
-rw-r--r-- | sys/netinet/ip_ah.c | 4 | ||||
-rw-r--r-- | sys/netinet/ip_ahhmacmd5.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_ahhmacsha1.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_ahmd5.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_ahsha1.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 4 | ||||
-rw-r--r-- | sys/netinet/ip_esp3des.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_esp3desmd5.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_espdes.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_espdesmd5.c | 5 | ||||
-rw-r--r-- | sys/netinet/ip_ip4.c | 59 | ||||
-rw-r--r-- | sys/netinet/ip_ip4.h | 16 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 70 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 19 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 93 |
18 files changed, 526 insertions, 636 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; } diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index d012fbdeba8..1e5cdddc26b 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.6 1997/06/25 07:53:21 provos Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.7 1997/07/01 22:12:41 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -145,7 +145,7 @@ ah_input(register struct mbuf *m, int iphlen) return; } - m->m_pkthdr.rcvif = tdbp->tdb_rcvif; + m->m_pkthdr.rcvif = &enc_softc; /* Register first use */ if (tdbp->tdb_first_use == 0) diff --git a/sys/netinet/ip_ahhmacmd5.c b/sys/netinet/ip_ahhmacmd5.c index 3a3bd949caf..55284cd715e 100644 --- a/sys/netinet/ip_ahhmacmd5.c +++ b/sys/netinet/ip_ahhmacmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahhmacmd5.c,v 1.12 1997/06/25 07:53:22 provos Exp $ */ +/* $OpenBSD: ip_ahhmacmd5.c,v 1.13 1997/07/01 22:12:42 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -374,7 +374,8 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) #define AHXPORT int -ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct ahhmacmd5_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_ahhmacsha1.c b/sys/netinet/ip_ahhmacsha1.c index ac9b056a010..9e3fa61bdb9 100644 --- a/sys/netinet/ip_ahhmacsha1.c +++ b/sys/netinet/ip_ahhmacsha1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahhmacsha1.c,v 1.10 1997/06/25 07:53:22 provos Exp $ */ +/* $OpenBSD: ip_ahhmacsha1.c,v 1.11 1997/07/01 22:12:43 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -377,7 +377,8 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) #define AHXPORT int -ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct ahhmacsha1_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_ahmd5.c b/sys/netinet/ip_ahmd5.c index e19b596f172..f3d406dcd8f 100644 --- a/sys/netinet/ip_ahmd5.c +++ b/sys/netinet/ip_ahmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahmd5.c,v 1.9 1997/06/25 07:53:23 provos Exp $ */ +/* $OpenBSD: ip_ahmd5.c,v 1.10 1997/07/01 22:12:44 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -99,6 +99,7 @@ ahmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) } m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, (caddr_t)xd); + bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ return 0; } @@ -294,7 +295,8 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb) #define AHXPORT int -ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct ahmd5_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_ahsha1.c b/sys/netinet/ip_ahsha1.c index 61bece49bc2..6aa40c07612 100644 --- a/sys/netinet/ip_ahsha1.c +++ b/sys/netinet/ip_ahsha1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ahsha1.c,v 1.5 1997/06/25 07:53:23 provos Exp $ */ +/* $OpenBSD: ip_ahsha1.c,v 1.6 1997/07/01 22:12:45 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -293,7 +293,8 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb) #define AHXPORT int -ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct ahsha1_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index dad0caaaa96..fc3f12bd412 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.6 1997/06/25 07:53:24 provos Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.7 1997/07/01 22:12:45 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -142,7 +142,7 @@ esp_input(register struct mbuf *m, int iphlen) return; } - m->m_pkthdr.rcvif = tdbp->tdb_rcvif; + m->m_pkthdr.rcvif = &enc_softc; /* Register first use */ if (tdbp->tdb_first_use == 0) diff --git a/sys/netinet/ip_esp3des.c b/sys/netinet/ip_esp3des.c index 175a2594c8a..9489f6c9f51 100644 --- a/sys/netinet/ip_esp3des.c +++ b/sys/netinet/ip_esp3des.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp3des.c,v 1.6 1997/06/25 07:53:25 provos Exp $ */ +/* $OpenBSD: ip_esp3des.c,v 1.7 1997/07/01 22:12:46 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -307,7 +307,8 @@ esp3des_input(struct mbuf *m, struct tdb *tdb) } int -esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct esp3des_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_esp3desmd5.c b/sys/netinet/ip_esp3desmd5.c index d52969c457b..3bfe161f2f2 100644 --- a/sys/netinet/ip_esp3desmd5.c +++ b/sys/netinet/ip_esp3desmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp3desmd5.c,v 1.10 1997/06/25 07:53:25 provos Exp $ */ +/* $OpenBSD: ip_esp3desmd5.c,v 1.11 1997/07/01 22:12:47 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -517,7 +517,8 @@ esp3desmd5_input(struct mbuf *m, struct tdb *tdb) } int -esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct esp3desmd5_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_espdes.c b/sys/netinet/ip_espdes.c index d0b925c4aa0..cfbd603b514 100644 --- a/sys/netinet/ip_espdes.c +++ b/sys/netinet/ip_espdes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_espdes.c,v 1.8 1997/06/25 07:53:26 provos Exp $ */ +/* $OpenBSD: ip_espdes.c,v 1.9 1997/07/01 22:12:48 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -294,7 +294,8 @@ espdes_input(struct mbuf *m, struct tdb *tdb) } int -espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct espdes_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_espdesmd5.c b/sys/netinet/ip_espdesmd5.c index 2700e34b888..4e50b1d6501 100644 --- a/sys/netinet/ip_espdesmd5.c +++ b/sys/netinet/ip_espdesmd5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_espdesmd5.c,v 1.10 1997/06/25 07:53:26 provos Exp $ */ +/* $OpenBSD: ip_espdesmd5.c,v 1.11 1997/07/01 22:12:49 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -501,7 +501,8 @@ espdesmd5_input(struct mbuf *m, struct tdb *tdb) } int -espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct espdesmd5_xdata *xd; struct ip *ip, ipo; diff --git a/sys/netinet/ip_ip4.c b/sys/netinet/ip_ip4.c index ff113083e91..ee878138a39 100644 --- a/sys/netinet/ip_ip4.c +++ b/sys/netinet/ip_ip4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ip4.c,v 1.9 1997/06/25 07:53:27 provos Exp $ */ +/* $OpenBSD: ip_ip4.c,v 1.10 1997/07/01 22:12:49 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -155,10 +155,10 @@ ip4_input(register struct mbuf *m, int iphlen) } int -ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) +ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, + struct mbuf **mp) { struct ip *ipo, *ipi; - struct ip4_xdata *xd; ushort ilen; ip4stat.ip4s_opackets++; @@ -178,23 +178,19 @@ ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct m /* ipo->ip_id = htons(ip_id++); */ get_random_bytes((void *)&(ipo->ip_id), sizeof(ipo->ip_id)); ipo->ip_off = ipi->ip_off & ~(IP_MF | IP_OFFMASK); /* keep C and DF */ - xd = (struct ip4_xdata *)tdb->tdb_xdata; - switch (xd->ip4_ttl) - { - case IP4_SAME_TTL: - ipo->ip_ttl = ipi->ip_ttl; - break; - case IP4_DEFAULT_TTL: - ipo->ip_ttl = ip_defttl; - break; - default: - ipo->ip_ttl = xd->ip4_ttl; - } + + if (tdb->tdb_flags & TDBF_SAME_TTL) + ipo->ip_ttl = ipi->ip_ttl; + else + if (tdb->tdb_ttl == 0) + ipo->ip_ttl = ip_defttl; + else + ipi->ip_ttl = tdb->tdb_ttl; ipo->ip_p = IPPROTO_IPIP; ipo->ip_sum = 0; - ipo->ip_src = gw->sen_ipsp_src; - ipo->ip_dst = gw->sen_ipsp_dst; + ipo->ip_src = tdb->tdb_osrc; + ipo->ip_dst = tdb->tdb_odst; /* * printf("ip4_output: [%x->%x](l=%d, p=%d)", @@ -208,8 +204,11 @@ ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct m *mp = m; /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ipo->ip_len) - (ipo->ip_hl << 2); + if (tdb->tdb_xform->xf_type == XF_IP4) + { + tdb->tdb_cur_packets++; + tdb->tdb_cur_bytes += ntohs(ipo->ip_len) - (ipo->ip_hl << 2); + } return 0; @@ -225,39 +224,17 @@ ipe4_attach() int ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) { - struct ip4_xdata *xd; - struct ip4_xencap txd; - struct encap_msghdr *em; - #ifdef ENCDEBUG if (encdebug) printf("ipe4_init: setting up\n"); #endif tdbp->tdb_xform = xsp; - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ip4_xdata), M_XDATA, - M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct ip4_xdata)); - xd = (struct ip4_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ip4_xencap)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)&txd); - xd->ip4_ttl = txd.ip4_ttl; return 0; } int ipe4_zeroize(struct tdb *tdbp) { - FREE(tdbp->tdb_xdata, M_XDATA); return 0; } diff --git a/sys/netinet/ip_ip4.h b/sys/netinet/ip_ip4.h index d489d3c1dc3..fd9d3d40070 100644 --- a/sys/netinet/ip_ip4.h +++ b/sys/netinet/ip_ip4.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ip4.h,v 1.6 1997/06/25 07:53:27 provos Exp $ */ +/* $OpenBSD: ip_ip4.h,v 1.7 1997/07/01 22:12:50 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -28,16 +28,6 @@ * Not quite all the functionality of RFC-1853, but the main idea is there. */ -struct ip4_xdata -{ - int32_t ip4_ttl; -}; - -struct ip4_xencap -{ - int32_t ip4_ttl; -}; - struct ip4stat { u_int32_t ip4s_ipackets; /* total input packets */ @@ -48,8 +38,8 @@ struct ip4stat u_int32_t ip4s_qfull; }; -#define IP4_SAME_TTL 0 -#define IP4_DEFAULT_TTL -1 +#define IP4_DEFAULT_TTL 0 +#define IP4_SAME_TTL -1 #ifdef _KERNEL struct ip4stat ip4stat; diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 99bbddb5ebe..f49eef36ff3 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.10 1997/06/25 07:53:28 provos Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.11 1997/07/01 22:12:51 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -71,34 +71,36 @@ int encdebug = 1; */ struct xformsw xformsw[] = { - { XF_IP4, 0, "IPv4 Simple Encapsulation", - ipe4_attach, ipe4_init, ipe4_zeroize, + { XF_IP4, 0, "IPv4 Simple Encapsulation", + ipe4_attach, ipe4_init, ipe4_zeroize, (struct mbuf * (*)(struct mbuf *, struct tdb *))ipe4_input, ipe4_output, }, - { XF_AHMD5, XFT_AUTH, "Keyed MD5 Authentication", - ahmd5_attach, ahmd5_init, ahmd5_zeroize, - ahmd5_input, ahmd5_output, }, - { XF_AHSHA1, XFT_AUTH, "Keyed SHA1 Authentication", - ahsha1_attach, ahsha1_init, ahsha1_zeroize, - ahsha1_input, ahsha1_output, }, - { XF_ESPDES, XFT_CONF, "DES-CBC Encryption", - espdes_attach, espdes_init, espdes_zeroize, - espdes_input, espdes_output, }, - { XF_ESP3DES, XFT_CONF, "3DES-CBC Encryption", - esp3des_attach, esp3des_init, esp3des_zeroize, - esp3des_input, esp3des_output, }, - { XF_AHHMACMD5, XFT_AUTH, "HMAC MD5 Authentication", - ahhmacmd5_attach, ahhmacmd5_init, ahhmacmd5_zeroize, - ahhmacmd5_input, ahhmacmd5_output, }, - { XF_AHHMACSHA1, XFT_AUTH, "HMAC SHA1 Authentication", - ahhmacsha1_attach, ahhmacsha1_init, ahhmacsha1_zeroize, - ahhmacsha1_input, ahhmacsha1_output, }, - { XF_ESPDESMD5, XFT_CONF|XFT_AUTH, "DES-CBC Encryption + MD5 Authentication", - espdesmd5_attach, espdesmd5_init, espdesmd5_zeroize, - espdesmd5_input, espdesmd5_output, }, - { XF_ESP3DESMD5, XFT_CONF|XFT_AUTH, "3DES-CBC Encryption + MD5 Authentication", - esp3desmd5_attach, esp3desmd5_init, esp3desmd5_zeroize, - esp3desmd5_input, esp3desmd5_output, }, + { XF_AHMD5, XFT_AUTH, "Keyed MD5 Authentication", + ahmd5_attach, ahmd5_init, ahmd5_zeroize, + ahmd5_input, ahmd5_output, }, + { XF_AHSHA1, XFT_AUTH, "Keyed SHA1 Authentication", + ahsha1_attach, ahsha1_init, ahsha1_zeroize, + ahsha1_input, ahsha1_output, }, + { XF_ESPDES, XFT_CONF, "DES-CBC Encryption", + espdes_attach, espdes_init, espdes_zeroize, + espdes_input, espdes_output, }, + { XF_ESP3DES, XFT_CONF, "3DES-CBC Encryption", + esp3des_attach, esp3des_init, esp3des_zeroize, + esp3des_input, esp3des_output, }, + { XF_AHHMACMD5, XFT_AUTH, "HMAC MD5 Authentication", + ahhmacmd5_attach, ahhmacmd5_init, ahhmacmd5_zeroize, + ahhmacmd5_input, ahhmacmd5_output, }, + { XF_AHHMACSHA1, XFT_AUTH, "HMAC SHA1 Authentication", + ahhmacsha1_attach, ahhmacsha1_init, ahhmacsha1_zeroize, + ahhmacsha1_input, ahhmacsha1_output, }, + { XF_ESPDESMD5, XFT_CONF|XFT_AUTH, + "DES-CBC Encryption + MD5 Authentication", + espdesmd5_attach, espdesmd5_init, espdesmd5_zeroize, + espdesmd5_input, espdesmd5_output, }, + { XF_ESP3DESMD5, XFT_CONF|XFT_AUTH, + "3DES-CBC Encryption + MD5 Authentication", + esp3desmd5_attach, esp3desmd5_init, esp3desmd5_zeroize, + esp3desmd5_input, esp3desmd5_output, }, }; struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])]; @@ -111,7 +113,7 @@ int ipspkernfs_dirty = 1; /* * 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. + * SPI. SPIs less than 255 are reserved, so we check for those too. */ u_int32_t @@ -122,7 +124,7 @@ reserve_spi(u_int32_t tspi, struct in_addr src) while (1) { - while (spi == 0) /* Get a new SPI */ + while (spi <= 255) /* Get a new SPI */ get_random_bytes((void *)&spi, sizeof(spi)); /* Check whether we're using this SPI already */ @@ -247,6 +249,9 @@ tdb_init(struct tdb *tdbp, struct mbuf *m) return EINVAL; } +/* + * XXX This should change to something cleaner. + */ int ipsp_kern(int off, char **bufp, int len) { @@ -277,10 +282,6 @@ ipsp_kern(int off, char **bufp, int len) /* Being paranoid to avoid buffer overflows */ k += 126 + strlen(tdbp->tdb_xform->xf_name); - if (tdbp->tdb_rcvif) - k += strlen(tdbp->tdb_rcvif->if_xname); - else - k += 4; } if (k == 0) @@ -295,10 +296,9 @@ ipsp_kern(int off, char **bufp, int len) { b = (char *)&(tdbp->tdb_dst.s_addr); k += sprintf(ipspkernfs + k, - "SPI=%x, destination=%d.%d.%d.%d, interface=%s\n algorithm=%d (%s)\n next SPI=%x, previous SPI=%x\n", + "SPI=%x, destination=%d.%d.%d.%d\n algorithm=%d (%s)\n next SPI=%x, previous SPI=%x\n", ntohl(tdbp->tdb_spi), ((int)b[0] & 0xff), ((int)b[1] & 0xff), ((int)b[2] & 0xff), ((int)b[3] & 0xff), - (tdbp->tdb_rcvif ? tdbp->tdb_rcvif->if_xname : "none"), tdbp->tdb_xform->xf_type, tdbp->tdb_xform->xf_name, (tdbp->tdb_onext ? ntohl(tdbp->tdb_onext->tdb_spi) : 0), (tdbp->tdb_inext ? ntohl(tdbp->tdb_inext->tdb_spi) : 0)); diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 2bf82d5b554..8d7c65e7ae3 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.8 1997/06/25 07:53:28 provos Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.9 1997/07/01 22:12:52 provos Exp $ */ /* * The author of this code is John Ioannidis, ji@tla.org, @@ -32,6 +32,7 @@ struct tdb /* tunnel descriptor block */ struct tdb *tdb_hnext; /* next in hash chain */ struct tdb *tdb_onext; /* next in output */ struct tdb *tdb_inext; /* next in input (prev!) */ + struct xformsw *tdb_xform; /* transformation to use */ u_int32_t tdb_spi; /* SPI to use */ u_int32_t tdb_flags; /* Flags related to this TDB */ #define TDBF_UNIQUE 0x00001 /* This should not be used by others */ @@ -46,6 +47,8 @@ struct tdb /* tunnel descriptor block */ #define TDBF_SOFT_PACKETS 0x00200 /* Soft expiration */ #define TDBF_SOFT_FIRSTUSE 0x00400 /* Soft expiration */ #define TDBF_SOFT_RELATIVE 0x00800 /* Soft expiration */ +#define TDBF_TUNNELING 0x01000 /* Do IP-in-IP encapsulation */ +#define TDBF_SAME_TTL 0x02000 /* Keep the packet TTL, in tunneling */ u_int64_t tdb_exp_packets; /* Expire after so many packets s|r */ u_int64_t tdb_soft_packets; /* Expiration warning */ u_int64_t tdb_cur_packets; /* Current number of packets s|r'ed */ @@ -63,9 +66,19 @@ struct tdb /* tunnel descriptor block */ u_int64_t tdb_exp_first_use; /* Expire if tdb_first_use + tdb_exp_first_use <= curtime */ struct in_addr tdb_dst; /* dest address for this SPI */ - struct ifnet *tdb_rcvif; /* related rcv encap interface */ - struct xformsw *tdb_xform; /* transformation to use */ + struct in_addr tdb_src; /* source address for this SPI, + * used when tunneling */ + struct in_addr tdb_osrc; + struct in_addr tdb_odst; /* Source and destination addresses + * of outter IP header if we're doing + * tunneling */ caddr_t tdb_xdata; /* transformation data (opaque) */ + u_int16_t tdb_sport; /* Source port, if applicable */ + u_int16_t tdb_dport; /* Destination port, if applicable */ + + u_int8_t tdb_ttl; /* TTL used in tunneling */ + u_int8_t tdb_proto; /* Protocol carried */ + u_int16_t tdb_foo; /* alignment */ }; #define TDB_HASHMOD 257 diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index d420438f7dc..a282dd5eedb 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.14 1997/06/25 07:53:29 provos Exp $ */ +/* $OpenBSD: ip_output.c,v 1.15 1997/07/01 22:12:53 provos Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -198,57 +198,6 @@ ip_output(m0, va_alist) return EHOSTUNREACH; } - ifp = re->re_rt->rt_ifp; - - if (ip->ip_src.s_addr == INADDR_ANY) { - struct sockaddr_encap *sen; - struct sockaddr_in *sinp; - - if (ifp->if_addrlist.tqh_first) - sen = (struct sockaddr_encap *) - ifp->if_addrlist.tqh_first->ifa_addr; - else { -#ifdef ENCDEBUG - if (encdebug) - printf("ip_output: interface %s has no default address\n", - ifp->if_xname); -#endif /* ENCDEBUG */ - m_freem(m); - RTFREE(re->re_rt); - return ENXIO; - } - - if (sen->sen_family != AF_ENCAP) { -#ifdef ENCDEBUG - if (encdebug) - printf("ip_output: %s does not have AF_ENCAP address\n", - ifp->if_xname); -#endif /* ENCDEBUG */ - m_freem(m); - RTFREE(re->re_rt); - return EHOSTDOWN; - } - - if (sen->sen_type != SENT_DEFIF) { -#ifdef ENCDEBUG - if (encdebug) - printf("ip_output: %s does not have SENT_DEFIF address\n", - ifp->if_xname); -#endif /* ENCDEBUG */ - m_freem(m); - RTFREE(re->re_rt); - return EHOSTDOWN; - } - sinp = (struct sockaddr_in *)&(sen->sen_dfl); - ip->ip_src = sinp->sin_addr; - } - -#ifdef ENCDEBUG - if (encdebug) - printf("ip_output: encapsulating %x->%x through %x->%x\n", - ip->ip_src.s_addr, ip->ip_dst.s_addr, - gw->sen_ipsp_src, gw->sen_ipsp_dst); -#endif ip->ip_len = htons((u_short)ip->ip_len); ip->ip_off = htons((u_short)ip->ip_off); ip->ip_sum = 0; @@ -263,6 +212,10 @@ ip_output(m0, va_alist) tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, gw->sen_ipsp_dst); + /* Fix the ip_src field if necessary */ + if ((ip->ip_src.s_addr == INADDR_ANY) && tdb) + ip->ip_src = tdb->tdb_src; + /* * If we're doing IP-in-IP first, let the options be. * Otherwise, get rid of them. @@ -271,11 +224,12 @@ ip_output(m0, va_alist) * XXX subsequently authenticated). */ if (tdb && tdb->tdb_xform) - if (tdb->tdb_xform->xf_type != XF_IP4) - if (hlen > sizeof (struct ip)) { /* XXX IPOPT */ - ip_stripoptions(m, (struct mbuf *)0); - hlen = sizeof (struct ip); - } + if ((tdb->tdb_xform->xf_type != XF_IP4) || + (tdb->tdb_flags & TDBF_TUNNELING)) + if (hlen > sizeof (struct ip)) { /* XXX IPOPT */ + ip_stripoptions(m, (struct mbuf *)0); + hlen = sizeof (struct ip); + } /* Now fix the checksum */ ip->ip_sum = in_cksum(m, hlen); @@ -300,6 +254,27 @@ ip_output(m0, va_alist) return ENXIO; } + /* Check for tunneling */ + if (tdb->tdb_flags & TDBF_TUNNELING) { +#ifdef ENCDEBUG + if (encdebug) + printf("ip_output: doing tunneling\n"); +#endif /* ENCDEBUG */ + + /* Register first use */ + if (tdb->tdb_first_use == 0) + tdb->tdb_first_use = time.tv_sec; + + error = ipe4_output(m, gw, tdb, &mp); + if (mp == NULL) + error = EFAULT; + if (error) { + RTFREE(re->re_rt); + return error; + } + m = mp; + } + #ifdef ENCDEBUG if (encdebug) printf("ip_output: calling %s\n", @@ -308,7 +283,7 @@ ip_output(m0, va_alist) /* Register first use */ if (tdb->tdb_first_use == 0) - tdb->tdb_first_use = time.tv_sec; + tdb->tdb_first_use = time.tv_sec; error = (*(tdb->tdb_xform->xf_output))(m, gw, tdb, &mp); if (mp == NULL) @@ -322,7 +297,7 @@ ip_output(m0, va_alist) } /* - * At this point, mp is pointing to an mbuf chain with the + * At this point, m is pointing to an mbuf chain with the * processed packet. Call ourselves recursively, but * bypass the encap code. */ |