diff options
35 files changed, 1377 insertions, 208 deletions
diff --git a/usr.sbin/ppp/ppp/Makefile b/usr.sbin/ppp/ppp/Makefile index 0c3a81833d7..cfc993c0f62 100644 --- a/usr.sbin/ppp/ppp/Makefile +++ b/usr.sbin/ppp/ppp/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.23 2001/09/08 20:22:37 ho Exp $ +# $OpenBSD: Makefile,v 1.24 2002/03/31 02:38:49 brian Exp $ PROG= ppp SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ @@ -10,7 +10,7 @@ SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ pred.c probe.c prompt.c proto.c radius.c radlib.c route.c server.c \ sig.c slcompress.c systems.c sync.c tcp.c tcpmss.c throughput.c \ timer.c tty.c tun.c udp.c vjcomp.c -CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH +CFLAGS+=-Wall -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH CFLAGS+=-DLOCALNAT -DLOCALRAD M4FLAGS=-DLOCALNAT -DLOCALRAD LDADD+= -lcrypto -ldes -lutil -lz diff --git a/usr.sbin/ppp/ppp/alias.c b/usr.sbin/ppp/ppp/alias.c index 2a2ef3730bf..5412f6ff786 100644 --- a/usr.sbin/ppp/ppp/alias.c +++ b/usr.sbin/ppp/ppp/alias.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: alias.c,v 1.17 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: alias.c,v 1.18 2002/03/31 02:38:49 brian Exp $ */ /* @@ -1057,12 +1057,14 @@ TcpAliasOut(struct ip *pip, int maxpacketsize) u_short *sptr; /* Save original destination address, if this is a proxy packet. - Also modify packet to include destination encoding. */ + Also modify packet to include destination encoding. This may + change the size of IP header. */ if (proxy_type != 0) { SetProxyPort(link, dest_port); SetProxyAddress(link, dest_address); ProxyModify(link, pip, maxpacketsize, proxy_type); + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); } /* Get alias address and port */ diff --git a/usr.sbin/ppp/ppp/alias_ftp.c b/usr.sbin/ppp/ppp/alias_ftp.c index ffd06d9967f..29fcf017ac0 100644 --- a/usr.sbin/ppp/ppp/alias_ftp.c +++ b/usr.sbin/ppp/ppp/alias_ftp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: alias_ftp.c,v 1.13 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: alias_ftp.c,v 1.14 2002/03/31 02:38:49 brian Exp $ */ /* @@ -482,11 +482,8 @@ NewFtpMessage(struct ip *pip, struct tcphdr *tc; #ifndef NO_FW_PUNCH - if (ftp_message_type == FTP_PORT_COMMAND || - ftp_message_type == FTP_EPRT_COMMAND) { - /* Punch hole in firewall */ - PunchFWHole(ftp_link); - } + /* Punch hole in firewall */ + PunchFWHole(ftp_link); #endif /* Calculate data length of TCP packet */ diff --git a/usr.sbin/ppp/ppp/async.c b/usr.sbin/ppp/ppp/async.c index 1d6f2cd1ec8..685bb4096e7 100644 --- a/usr.sbin/ppp/ppp/async.c +++ b/usr.sbin/ppp/ppp/async.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: async.c,v 1.10 2002/03/04 10:17:40 brian Exp $ + * $OpenBSD: async.c,v 1.11 2002/03/31 02:38:49 brian Exp $ */ #include <sys/types.h> @@ -69,10 +69,10 @@ async_Setup(struct async *async) } void -async_SetLinkParams(struct async *async, struct lcp *lcp) +async_SetLinkParams(struct async *async, u_int32_t mymap, u_int32_t hismap) { - async->my_accmap = lcp->want_accmap; - async->his_accmap = lcp->his_accmap | lcp->want_accmap; + async->my_accmap = mymap; + async->his_accmap = hismap | mymap; } /* diff --git a/usr.sbin/ppp/ppp/async.h b/usr.sbin/ppp/ppp/async.h index 752d3cee1bb..bbc132d6776 100644 --- a/usr.sbin/ppp/ppp/async.h +++ b/usr.sbin/ppp/ppp/async.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: async.h,v 1.5 2002/03/04 10:17:40 brian Exp $ + * $OpenBSD: async.h,v 1.6 2002/03/31 02:38:49 brian Exp $ */ #define HDLCSIZE (MAX_MRU*2+6) @@ -48,6 +48,6 @@ struct bundle; extern void async_Init(struct async *); extern void async_Setup(struct async *); -extern void async_SetLinkParams(struct async *, struct lcp *); +extern void async_SetLinkParams(struct async *, u_int32_t, u_int32_t); extern struct layer asynclayer; diff --git a/usr.sbin/ppp/ppp/atm.c b/usr.sbin/ppp/ppp/atm.c index 575c4c39299..01a3ded13aa 100644 --- a/usr.sbin/ppp/ppp/atm.c +++ b/usr.sbin/ppp/ppp/atm.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: atm.c,v 1.6 2002/01/16 14:13:06 brian Exp $ + * $OpenBSD: atm.c,v 1.7 2002/03/31 02:38:49 brian Exp $ */ #include <sys/types.h> @@ -130,6 +130,7 @@ static const struct device baseatmdevice = { NULL, NULL, NULL, + NULL, atm_Free, atm_Recvfrom, atm_Sendto, diff --git a/usr.sbin/ppp/ppp/auth.c b/usr.sbin/ppp/ppp/auth.c index 339ffa7d6a3..ce8337dd983 100644 --- a/usr.sbin/ppp/ppp/auth.c +++ b/usr.sbin/ppp/ppp/auth.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: auth.c,v 1.16 2001/08/19 23:22:17 brian Exp $ + * $OpenBSD: auth.c,v 1.17 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -116,12 +116,13 @@ auth_SetPhoneList(const char *name, char *phone, int phonelen) { FILE *fp; int n, lineno; - char *vector[6]; - char buff[LINE_LEN]; + char *vector[6], buff[LINE_LEN]; + const char *slash; fp = OpenSecret(SECRETFILE); - lineno = 0; if (fp != NULL) { +again: + lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') @@ -141,6 +142,14 @@ auth_SetPhoneList(const char *name, char *phone, int phonelen) return 1; /* Valid */ } } + + if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { + /* Look for the name without the leading domain */ + name = slash + 1; + rewind(fp); + goto again; + } + CloseSecret(fp); } *phone = '\0'; @@ -152,8 +161,8 @@ auth_Select(struct bundle *bundle, const char *name) { FILE *fp; int n, lineno; - char *vector[5]; - char buff[LINE_LEN]; + char *vector[5], buff[LINE_LEN]; + const char *slash; if (*name == '\0') { ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); @@ -171,8 +180,9 @@ auth_Select(struct bundle *bundle, const char *name) #endif fp = OpenSecret(SECRETFILE); - lineno = 0; if (fp != NULL) { +again: + lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') @@ -200,6 +210,14 @@ auth_Select(struct bundle *bundle, const char *name) return 1; /* Valid */ } } + + if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { + /* Look for the name without the leading domain */ + name = slash + 1; + rewind(fp); + goto again; + } + CloseSecret(fp); } @@ -226,10 +244,11 @@ auth_Validate(struct bundle *bundle, const char *name, FILE *fp; int n, lineno; - char *vector[5]; - char buff[LINE_LEN]; + char *vector[5], buff[LINE_LEN]; + const char *slash; fp = OpenSecret(SECRETFILE); +again: lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { @@ -247,9 +266,20 @@ auth_Validate(struct bundle *bundle, const char *name, return auth_CheckPasswd(name, vector[1], key); } } - CloseSecret(fp); } + if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { + /* Look for the name without the leading domain */ + name = slash + 1; + if (fp != NULL) { + rewind(fp); + goto again; + } + } + + if (fp != NULL) + CloseSecret(fp); + #ifndef NOPASSWDAUTH if (Enabled(bundle, OPT_PASSWDAUTH)) return auth_CheckPasswd(name, "*", key); @@ -267,12 +297,14 @@ auth_GetSecret(struct bundle *bundle, const char *name, int len, FILE *fp; int n, lineno; char *vector[5]; + const char *slash; static char buff[LINE_LEN]; /* vector[] will point here when returned */ fp = OpenSecret(SECRETFILE); if (fp == NULL) return (NULL); +again: lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; @@ -291,6 +323,15 @@ auth_GetSecret(struct bundle *bundle, const char *name, int len, return vector[1]; } } + + if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { + /* Go back and look for the name without the leading domain */ + len -= slash - name + 1; + name = slash + 1; + rewind(fp); + goto again; + } + CloseSecret(fp); return (NULL); /* Invalid */ } diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index 82517444018..8349ede415c 100644 --- a/usr.sbin/ppp/ppp/bundle.c +++ b/usr.sbin/ppp/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.c,v 1.62 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: bundle.c,v 1.63 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -49,12 +49,6 @@ #include <string.h> #include <sys/uio.h> #include <sys/wait.h> -#if defined(__FreeBSD__) && !defined(NOKLDLOAD) -#ifdef NOSUID -#include <sys/linker.h> -#endif -#include <sys/module.h> -#endif #include <termios.h> #include <unistd.h> @@ -100,7 +94,7 @@ #include "iface.h" #include "server.h" #include "probe.h" -#ifdef HAVE_DES +#ifndef NODES #include "mppe.h" #endif @@ -135,7 +129,7 @@ bundle_NewPhase(struct bundle *bundle, u_int new) switch (new) { case PHASE_DEAD: bundle->phase = new; -#ifdef HAVE_DES +#ifndef NODES MPPE_MasterKeyValid = 0; #endif log_DisplayPrompts(); @@ -336,9 +330,11 @@ bundle_LayerDown(void *v, struct fsm *fp) fp->link->name); } - if (!others_active) + if (!others_active) { /* Down the NCPs. We don't expect to get fsm_Close()d ourself ! */ ncp2initial(&bundle->ncp); + mp_Down(&bundle->ncp.mp); + } } } @@ -348,6 +344,7 @@ bundle_LayerFinish(void *v, struct fsm *fp) /* The given fsm is now down (fp cannot be NULL) * * If it's the last NCP, fsm_Close all LCPs + * If it's the last NCP, bring any MP layer down */ struct bundle *bundle = (struct bundle *)v; @@ -360,6 +357,7 @@ bundle_LayerFinish(void *v, struct fsm *fp) if (dl->state == DATALINK_OPEN) datalink_Close(dl, CLOSE_STAYDOWN); fsm2initial(fp); + mp_Down(&bundle->ncp.mp); } } @@ -406,6 +404,7 @@ bundle_Close(struct bundle *bundle, const char *name, int how) ncp_Close(&bundle->ncp); else { ncp2initial(&bundle->ncp); + mp_Down(&bundle->ncp.mp); for (dl = bundle->links; dl; dl = dl->next) datalink_Close(dl, how); } @@ -625,11 +624,18 @@ bundle_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle, /* This is not actually necessary as struct mpserver doesn't Write() */ if (descriptor_IsSet(&bundle->ncp.mp.server.desc, fdset)) - descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset); + if (descriptor_Write(&bundle->ncp.mp.server.desc, bundle, fdset) == 1) + result++; for (dl = bundle->links; dl; dl = dl->next) if (descriptor_IsSet(&dl->desc, fdset)) - result += descriptor_Write(&dl->desc, bundle, fdset); + switch (descriptor_Write(&dl->desc, bundle, fdset)) { + case -1: + datalink_ComeDown(dl, CLOSE_NORMAL); + break; + case 1: + result++; + } return result; } @@ -705,13 +711,8 @@ bundle_Create(const char *prefix, int type, int unit) * Attempt to load the tunnel interface KLD if it isn't loaded * already. */ - if (modfind("if_tun") == -1) { - if (ID0kldload("if_tun") != -1) { - bundle.unit--; - continue; - } - log_Printf(LogWARN, "kldload: if_tun: %s\n", strerror(errno)); - } + loadmodules(LOAD_VERBOSLY, "if_tun", NULL); + continue; } #endif if (errno != ENOENT || ++enoentcount > 2) { @@ -938,6 +939,7 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl) if (dl->physical->type != PHYS_AUTO) /* Not in -auto mode */ bundle_DownInterface(bundle); ncp2initial(&bundle->ncp); + mp_Down(&bundle->ncp.mp); bundle_NewPhase(bundle, PHASE_DEAD); bundle_StopIdleTimer(bundle); } diff --git a/usr.sbin/ppp/ppp/ccp.c b/usr.sbin/ppp/ppp/ccp.c index a8331ed427d..033f1d83882 100644 --- a/usr.sbin/ppp/ppp/ccp.c +++ b/usr.sbin/ppp/ppp/ccp.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ccp.c,v 1.25 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: ccp.c,v 1.26 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -70,7 +70,7 @@ #ifndef NORADIUS #include "radius.h" #endif -#ifdef HAVE_DES +#ifndef NODES #include "mppe.h" #endif #include "ipv6cp.h" @@ -148,7 +148,7 @@ static const struct ccp_algorithm * const algorithm[] = { &DeflateAlgorithm, &Pred1Algorithm, &PppdDeflateAlgorithm -#ifdef HAVE_DES +#ifndef NODES , &MPPEAlgorithm #endif }; @@ -197,7 +197,7 @@ ccp_ReportStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, " deflate windows: "); prompt_Printf(arg->prompt, "incoming = %d, ", ccp->cfg.deflate.in.winsize); prompt_Printf(arg->prompt, "outgoing = %d\n", ccp->cfg.deflate.out.winsize); -#ifdef HAVE_DES +#ifndef NODES prompt_Printf(arg->prompt, " MPPE: "); if (ccp->cfg.mppe.keybits) prompt_Printf(arg->prompt, "%d bits, ", ccp->cfg.mppe.keybits); @@ -224,7 +224,7 @@ ccp_ReportStatus(struct cmdargs const *arg) command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1])); prompt_Printf(arg->prompt, " DEFLATE24: %s\n", command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24])); -#ifdef HAVE_DES +#ifndef NODES prompt_Printf(arg->prompt, " MPPE: %s\n", command_ShowNegval(ccp->cfg.neg[CCP_NEG_MPPE])); #endif @@ -257,7 +257,7 @@ ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l, ccp->cfg.neg[CCP_NEG_DEFLATE] = NEG_ENABLED|NEG_ACCEPTED; ccp->cfg.neg[CCP_NEG_PRED1] = NEG_ENABLED|NEG_ACCEPTED; ccp->cfg.neg[CCP_NEG_DEFLATE24] = 0; -#ifdef HAVE_DES +#ifndef NODES ccp->cfg.mppe.keybits = 0; ccp->cfg.mppe.state = MPPE_ANYSTATE; ccp->cfg.mppe.required = 0; diff --git a/usr.sbin/ppp/ppp/ccp.h b/usr.sbin/ppp/ppp/ccp.h index 9de531fa4a6..d6d83655191 100644 --- a/usr.sbin/ppp/ppp/ccp.h +++ b/usr.sbin/ppp/ppp/ccp.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ccp.h,v 1.11 2001/07/03 22:23:56 brian Exp $ + * $OpenBSD: ccp.h,v 1.12 2002/03/31 02:38:49 brian Exp $ */ #define CCP_MAXCODE CODE_RESETACK @@ -47,14 +47,14 @@ #define CCP_NEG_DEFLATE 0 #define CCP_NEG_PRED1 1 #define CCP_NEG_DEFLATE24 2 -#ifdef HAVE_DES +#ifndef NODES #define CCP_NEG_MPPE 3 #define CCP_NEG_TOTAL 4 #else #define CCP_NEG_TOTAL 3 #endif -#ifdef HAVE_DES +#ifndef NODES enum mppe_negstate { MPPE_ANYSTATE, MPPE_STATELESS, @@ -71,7 +71,7 @@ struct ccp_config { int winsize; } in, out; } deflate; -#ifdef HAVE_DES +#ifndef NODES struct { int keybits; enum mppe_negstate state; diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c index 08565bf53cf..473e66267db 100644 --- a/usr.sbin/ppp/ppp/chap.c +++ b/usr.sbin/ppp/ppp/chap.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: chap.c,v 1.30 2001/08/19 23:22:17 brian Exp $ + * $OpenBSD: chap.c,v 1.31 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -37,7 +37,7 @@ #include <errno.h> #include <fcntl.h> -#ifdef HAVE_DES +#ifndef NODES #include <md4.h> #endif #include <md5.h> @@ -85,7 +85,7 @@ #include "cbcp.h" #include "command.h" #include "datalink.h" -#ifdef HAVE_DES +#ifndef NODES #include "chap_ms.h" #include "mppe.h" #endif @@ -123,7 +123,7 @@ ChapOutput(struct physical *physical, u_int code, u_int id, static char * chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, u_char type -#ifdef HAVE_DES +#ifndef NODES , char *peerchallenge, char *authresponse, int lanman #endif ) @@ -134,7 +134,7 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, u_char type nlen = strlen(name); klen = strlen(key); -#ifdef HAVE_DES +#ifndef NODES if (type == 0x80) { char expkey[AUTHLEN << 2]; MD4_CTX MD4context; @@ -358,14 +358,14 @@ chap_Cleanup(struct chap *chap, int sig) log_Printf(LogERROR, "Chap: Child exited %d\n", WEXITSTATUS(status)); } *chap->challenge.local = *chap->challenge.peer = '\0'; -#ifdef HAVE_DES +#ifndef NODES chap->peertries = 0; #endif } static void chap_Respond(struct chap *chap, char *name, char *key, u_char type -#ifdef HAVE_DES +#ifndef NODES , int lm #endif ) @@ -373,7 +373,7 @@ chap_Respond(struct chap *chap, char *name, char *key, u_char type u_char *ans; ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.peer, type -#ifdef HAVE_DES +#ifndef NODES , chap->challenge.local, chap->authresponse, lm #endif ); @@ -381,7 +381,7 @@ chap_Respond(struct chap *chap, char *name, char *key, u_char type if (ans) { ChapOutput(chap->auth.physical, CHAP_RESPONSE, chap->auth.id, ans, *ans + 1 + strlen(name), name); -#ifdef HAVE_DES +#ifndef NODES chap->NTRespSent = !lm; MPPE_IsServer = 0; /* XXX Global ! */ #endif @@ -447,7 +447,7 @@ chap_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) chap_Cleanup(chap, SIGTERM); } } else { -#ifdef HAVE_DES +#ifndef NODES int lanman = chap->auth.physical->link.lcp.his_authtype == 0x80 && ((chap->NTRespSent && IsAccepted(chap->auth.physical->link.lcp.cfg.chap80lm)) || @@ -462,7 +462,7 @@ chap_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) key += strspn(key, " \t"); chap_Respond(chap, name, key, chap->auth.physical->link.lcp.his_authtype -#ifdef HAVE_DES +#ifndef NODES , lanman #endif ); @@ -501,7 +501,7 @@ chap_ChallengeInit(struct authinfo *authp) } else #endif { -#ifdef HAVE_DES +#ifndef NODES if (authp->physical->link.lcp.want_authtype == 0x80) *cp++ = 8; /* MS does 8 byte callenges :-/ */ else if (authp->physical->link.lcp.want_authtype == 0x81) @@ -531,7 +531,7 @@ chap_Challenge(struct authinfo *authp) if (!*chap->challenge.local) chap_ChallengeInit(authp); -#ifdef HAVE_DES +#ifndef NODES if (authp->physical->link.lcp.want_authtype == 0x81) ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id, chap->challenge.local, 1 + *chap->challenge.local, NULL); @@ -546,7 +546,7 @@ chap_Success(struct authinfo *authp) { const char *msg; datalink_GotAuthname(authp->physical->dl, authp->in.name); -#ifdef HAVE_DES +#ifndef NODES if (authp->physical->link.lcp.want_authtype == 0x81) { msg = auth2chap(authp)->authresponse; MPPE_MasterKeyValid = 1; /* XXX Global ! */ @@ -572,12 +572,12 @@ chap_Success(struct authinfo *authp) static void chap_Failure(struct authinfo *authp) { -#ifdef HAVE_DES +#ifndef NODES char buf[1024]; #endif const char *msg; -#ifdef HAVE_DES +#ifndef NODES if (authp->physical->link.lcp.want_authtype == 0x81) { char *ptr; int i; @@ -600,14 +600,14 @@ chap_Failure(struct authinfo *authp) static int chap_Cmp(u_char type, char *myans, int mylen, char *hisans, int hislen -#ifdef HAVE_DES +#ifndef NODES , int lm #endif ) { if (mylen != hislen) return 0; -#ifdef HAVE_DES +#ifndef NODES else if (type == 0x80) { int off = lm ? 0 : 24; @@ -621,7 +621,7 @@ chap_Cmp(u_char type, char *myans, int mylen, char *hisans, int hislen return 1; } -#ifdef HAVE_DES +#ifndef NODES static int chap_HaveAnotherGo(struct chap *chap) { @@ -648,7 +648,7 @@ chap_Init(struct chap *chap, struct physical *p) chap->child.fd = -1; auth_Init(&chap->auth, p, chap_Challenge, chap_Success, chap_Failure); *chap->challenge.local = *chap->challenge.peer = '\0'; -#ifdef HAVE_DES +#ifndef NODES chap->NTRespSent = 0; chap->peertries = 0; #endif @@ -668,7 +668,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) char *name, *key, *ans; int len, nlen; u_char alen; -#ifdef HAVE_DES +#ifndef NODES int lanman; #endif @@ -708,7 +708,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) } chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */ -#ifdef HAVE_DES +#ifndef NODES lanman = 0; #endif switch (chap->auth.in.hdr.code) { @@ -723,7 +723,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) *chap->challenge.peer = alen; bp = mbuf_Read(bp, chap->challenge.peer + 1, alen); bp = auth_ReadName(&chap->auth, bp, len); -#ifdef HAVE_DES +#ifndef NODES lanman = p->link.lcp.his_authtype == 0x80 && ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) || !IsAccepted(p->link.lcp.cfg.chap80nt)); @@ -756,7 +756,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) } ans[alen+1] = '\0'; bp = auth_ReadName(&chap->auth, bp, len); -#ifdef HAVE_DES +#ifndef NODES lanman = p->link.lcp.want_authtype == 0x80 && alen == 49 && ans[alen] == 0; #endif @@ -782,7 +782,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n", chapcodes[chap->auth.in.hdr.code], alen, chap->auth.in.name, -#ifdef HAVE_DES +#ifndef NODES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif @@ -790,7 +790,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) else log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n", chapcodes[chap->auth.in.hdr.code], alen, -#ifdef HAVE_DES +#ifndef NODES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif @@ -817,7 +817,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key + (*bundle->cfg.auth.key == '!' ? 1 : 0), p->link.lcp.his_authtype -#ifdef HAVE_DES +#ifndef NODES , lanman #endif ); @@ -838,7 +838,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) key = auth_GetSecret(bundle, name, nlen, p); if (key) { char *myans; -#ifdef HAVE_DES +#ifndef NODES if (p->link.lcp.want_authtype == 0x80 && lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) { log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n"); @@ -858,7 +858,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) } else #endif { -#ifdef HAVE_DES +#ifndef NODES /* Get peer's challenge */ if (p->link.lcp.want_authtype == 0x81) { chap->challenge.peer[0] = CHAP81_CHALLENGE_LEN; @@ -869,7 +869,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) myans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.local, p->link.lcp.want_authtype -#ifdef HAVE_DES +#ifndef NODES , chap->challenge.peer, chap->authresponse, lanman); MPPE_IsServer = 1; /* XXX Global ! */ @@ -881,7 +881,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) else { if (!chap_Cmp(p->link.lcp.want_authtype, myans + 1, *myans, ans + 1, alen -#ifdef HAVE_DES +#ifndef NODES , lanman #endif )) @@ -903,7 +903,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p->link.lcp.auth_iwait == PROTO_CHAP) { p->link.lcp.auth_iwait = 0; if (p->link.lcp.auth_ineed == 0) { -#ifdef HAVE_DES +#ifndef NODES if (p->link.lcp.his_authtype == 0x81) { if (strncmp(ans, chap->authresponse, 42)) { datalink_AuthNotOk(p->dl); diff --git a/usr.sbin/ppp/ppp/chap.h b/usr.sbin/ppp/ppp/chap.h index b48fa9439ba..35abb29b81b 100644 --- a/usr.sbin/ppp/ppp/chap.h +++ b/usr.sbin/ppp/ppp/chap.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: chap.h,v 1.11 2001/06/13 21:33:40 brian Exp $ + * $OpenBSD: chap.h,v 1.12 2002/03/31 02:38:49 brian Exp $ */ struct mbuf; @@ -51,7 +51,7 @@ struct chap { u_char local[CHAPCHALLENGELEN + AUTHLEN]; /* I invented this one */ u_char peer[CHAPCHALLENGELEN + AUTHLEN]; /* Peer gave us this one */ } challenge; -#ifdef HAVE_DES +#ifndef NODES unsigned NTRespSent : 1; /* Our last response */ int peertries; u_char authresponse[CHAPAUTHRESPONSELEN]; /* CHAP 81 response */ diff --git a/usr.sbin/ppp/ppp/chat.c b/usr.sbin/ppp/ppp/chat.c index de50d212a7f..f260636cd2d 100644 --- a/usr.sbin/ppp/ppp/chat.c +++ b/usr.sbin/ppp/ppp/chat.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: chat.c,v 1.17 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: chat.c,v 1.18 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -516,10 +516,12 @@ chat_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) } wrote = physical_Write(c->physical, c->argptr, c->arglen); - result = wrote ? 1 : 0; + result = wrote > 0 ? 1 : 0; if (wrote == -1) { - if (errno != EINTR) - log_Printf(LogERROR, "chat_Write: %s\n", strerror(errno)); + if (errno != EINTR) { + log_Printf(LogWARN, "chat_Write: %s\n", strerror(errno)); + result = -1; + } if (physical_IsSync(c->physical)) { c->argptr += 2; c->arglen -= 2; diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 36929e07469..c87cc579848 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: command.c,v 1.71 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: command.c,v 1.72 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -1673,7 +1673,7 @@ SetVariable(struct cmdargs const *arg) } break; -#ifdef HAVE_DES +#ifndef NODES case VAR_MPPE: if (arg->argc > arg->argn + 2) { res = -1; @@ -2210,7 +2210,7 @@ static struct cmdtab const SetCommands[] = { {"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT, "deflate window sizes", "set deflate out-winsize in-winsize", (const void *) VAR_WINSIZE}, -#ifdef HAVE_DES +#ifndef NODES {"mppe", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT, "MPPE key size and state", "set mppe [40|56|128|* [stateful|stateless|*]]", (const void *) VAR_MPPE}, @@ -2674,7 +2674,7 @@ NegotiateSet(struct cmdargs const *arg) cx->physical->link.lcp.cfg.chap05 &= keep; cx->physical->link.lcp.cfg.chap05 |= add; break; -#ifdef HAVE_DES +#ifndef NODES case NEG_CHAP80: cx->physical->link.lcp.cfg.chap80nt &= keep; cx->physical->link.lcp.cfg.chap80nt |= add; @@ -2799,7 +2799,7 @@ static struct cmdtab const NegotiateCommands[] = { {"chap", "chap05", NegotiateSet, LOCAL_AUTH | LOCAL_CX, "Challenge Handshake Authentication Protocol", "accept|deny|disable|enable", (const void *)NEG_CHAP05}, -#ifdef HAVE_DES +#ifndef NODES {"mschap", "chap80nt", NegotiateSet, LOCAL_AUTH | LOCAL_CX, "Microsoft (NT) CHAP", "accept|deny|disable|enable", (const void *)NEG_CHAP80}, diff --git a/usr.sbin/ppp/ppp/datalink.c b/usr.sbin/ppp/ppp/datalink.c index a2763236c28..74734922941 100644 --- a/usr.sbin/ppp/ppp/datalink.c +++ b/usr.sbin/ppp/ppp/datalink.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: datalink.c,v 1.39 2002/03/04 10:17:40 brian Exp $ + * $OpenBSD: datalink.c,v 1.40 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -489,7 +489,10 @@ datalink_Write(struct fdescriptor *d, struct bundle *bundle, case DATALINK_DIAL: case DATALINK_LOGOUT: case DATALINK_LOGIN: - result = descriptor_Write(&dl->chat.desc, bundle, fdset); + if ((result = descriptor_Write(&dl->chat.desc, bundle, fdset)) == -1) { + datalink_ComeDown(dl, CLOSE_NORMAL); + result = 0; + } break; case DATALINK_READY: @@ -498,16 +501,28 @@ datalink_Write(struct fdescriptor *d, struct bundle *bundle, case DATALINK_CBCP: case DATALINK_OPEN: if (descriptor_IsSet(&dl->chap.desc, fdset)) - result += descriptor_Write(&dl->chap.desc, bundle, fdset); + switch (descriptor_Write(&dl->chap.desc, bundle, fdset)) { + case -1: + datalink_ComeDown(dl, CLOSE_NORMAL); + break; + case 1: + result++; + } if (descriptor_IsSet(&dl->physical->desc, fdset)) - result += descriptor_Write(&dl->physical->desc, bundle, fdset); + switch (descriptor_Write(&dl->physical->desc, bundle, fdset)) { + case -1: + datalink_ComeDown(dl, CLOSE_NORMAL); + break; + case 1: + result++; + } break; } return result; } -static void +void datalink_ComeDown(struct datalink *dl, int how) { int stayonline; diff --git a/usr.sbin/ppp/ppp/datalink.h b/usr.sbin/ppp/ppp/datalink.h index 8d842253297..4761c05c5af 100644 --- a/usr.sbin/ppp/ppp/datalink.h +++ b/usr.sbin/ppp/ppp/datalink.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: datalink.h,v 1.8 2000/02/27 01:38:25 brian Exp $ + * $OpenBSD: datalink.h,v 1.9 2002/03/31 02:38:49 brian Exp $ */ #define DATALINK_CLOSED (0) @@ -52,7 +52,7 @@ struct physical; struct bundle; struct datalink { - struct fdescriptor desc; /* We play either a physical or a chat */ + struct fdescriptor desc; /* We play either a physical or a chat */ int state; /* Our DATALINK_* state */ struct physical *physical; /* Our link */ @@ -154,3 +154,4 @@ extern int datalink_RemoveFromSet(struct datalink *, fd_set *, fd_set *, extern int datalink_SetMode(struct datalink *, int); extern int datalink_GetDialTimeout(struct datalink *); extern const char *datalink_ChoosePhoneNumber(struct datalink *); +extern void datalink_ComeDown(struct datalink *, int); diff --git a/usr.sbin/ppp/ppp/defs.c b/usr.sbin/ppp/ppp/defs.c index 6dd7763f74c..cbbeeca6e6c 100644 --- a/usr.sbin/ppp/ppp/defs.c +++ b/usr.sbin/ppp/ppp/defs.c @@ -23,11 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: defs.c,v 1.22 2002/03/12 16:14:22 brian Exp $ + * $OpenBSD: defs.c,v 1.23 2002/03/31 02:38:49 brian Exp $ */ -#include <sys/types.h> +#include <sys/param.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -35,15 +35,24 @@ #include <ctype.h> #include <errno.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include <sys/linker.h> +#include <sys/module.h> +#endif #include <termios.h> #if !defined(__FreeBSD__) || __FreeBSD__ < 3 #include <time.h> #endif #include <unistd.h> +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include "id.h" +#include "log.h" +#endif #include "defs.h" #define issep(c) ((c) == '\t' || (c) == ' ') @@ -410,3 +419,20 @@ Concatinate(char *buf, size_t sz, int argc, const char *const *argv) break; } } + +void +loadmodules(int how, const char *module, ...) +{ +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) + va_list ap; + + va_start(ap, module); + while (module != NULL) { + if (modfind(module) == -1 && ID0kldload(module) == -1 && + how == LOAD_VERBOSLY) + log_Printf(LogWARN, "%s: Cannot load module\n", module); + module = va_arg(ap, const char *); + } + va_end(ap); +#endif +} diff --git a/usr.sbin/ppp/ppp/defs.h b/usr.sbin/ppp/ppp/defs.h index f209e2de761..1313891cf14 100644 --- a/usr.sbin/ppp/ppp/defs.h +++ b/usr.sbin/ppp/ppp/defs.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: defs.h,v 1.22 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: defs.h,v 1.23 2002/03/31 02:38:49 brian Exp $ */ /* Check the following definitions for your machine environment */ @@ -111,6 +111,10 @@ #define PARSE_REDUCE 1 #define PARSE_NOHASH 2 +/* flags passed to loadmodules */ +#define LOAD_QUIETLY 1 +#define LOAD_VERBOSLY 2 + #define ROUNDUP(x) ((x) ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long)) #if defined(__NetBSD__) || __FreeBSD__ < 3 @@ -135,3 +139,4 @@ extern void SetTitle(const char *); extern fd_set *mkfdset(void); extern void zerofdset(fd_set *); extern void Concatinate(char *, size_t, int, const char *const *); +extern void loadmodules(int, const char *, ...); diff --git a/usr.sbin/ppp/ppp/ether.c b/usr.sbin/ppp/ppp/ether.c index 00106c6676a..93cc1a6f468 100644 --- a/usr.sbin/ppp/ppp/ether.c +++ b/usr.sbin/ppp/ppp/ether.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ether.c,v 1.14 2001/09/13 10:32:57 brian Exp $ + * $OpenBSD: ether.c,v 1.15 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -49,10 +49,6 @@ #include <string.h> #include <sysexits.h> #include <sys/fcntl.h> -#if defined(__FreeBSD__) && !defined(NOKLDLOAD) -#include <sys/linker.h> -#include <sys/module.h> -#endif #include <sys/stat.h> #include <sys/uio.h> #include <termios.h> @@ -254,6 +250,11 @@ ether_MessageIn(struct etherdevice *dev) case NGM_PPPOE_FAIL: msg = "FAIL"; break; case NGM_PPPOE_CLOSE: msg = "CLOSE"; break; case NGM_PPPOE_GET_STATUS: msg = "GET_STATUS"; break; + case NGM_PPPOE_ACNAME: + msg = "ACNAME"; + if (setenv("ACNAME", sts->hook, 1) != 0) + log_Printf(LogWARN, "setenv: cannot set ACNAME=%s: %m", sts->hook); + break; default: snprintf(unknown, sizeof unknown, "<%d>", (int)rep->header.cmd); msg = unknown; @@ -297,6 +298,7 @@ static const struct device baseetherdevice = { NULL, NULL, NULL, + NULL, ether_Free, ether_Read, ether_Write, @@ -427,29 +429,8 @@ ether_Create(struct physical *p) p->fd--; /* We own the device - change fd */ -#if defined(__FreeBSD__) && !defined(NOKLDLOAD) - if (modfind("netgraph") == -1 && ID0kldload("netgraph") == -1) { - log_Printf(LogWARN, "kldload: netgraph: %s\n", strerror(errno)); - return NULL; - } - - if (modfind("ng_ether") == -1 && ID0kldload("ng_ether") == -1) - /* - * Don't treat this as an error as older kernels have this stuff - * built in as part of the netgraph node itself. - */ - log_Printf(LogWARN, "kldload: ng_ether: %s\n", strerror(errno)); - - if (modfind("ng_pppoe") == -1 && ID0kldload("ng_pppoe") == -1) { - log_Printf(LogWARN, "kldload: ng_pppoe: %s\n", strerror(errno)); - return NULL; - } - - if (modfind("ng_socket") == -1 && ID0kldload("ng_socket") == -1) { - log_Printf(LogWARN, "kldload: ng_socket: %s\n", strerror(errno)); - return NULL; - } -#endif + loadmodules(LOAD_VERBOSLY, "netgraph", "ng_ether", "ng_pppoe", "ng_socket", + NULL); if ((dev = malloc(sizeof *dev)) == NULL) return NULL; @@ -493,6 +474,7 @@ ether_Create(struct physical *p) log_Printf(LogWARN, "Cannot create netgraph socket node: %s\n", strerror(errno)); free(dev); + p->fd = -2; return NULL; } @@ -560,7 +542,7 @@ ether_Create(struct physical *p) if (f == ninfo->hooks) { /* * Create a new ``PPPoE'' node connected to the ``ether'' node using - * the magic ``orphan'' and ``ethernet'' hooks + * the ``orphan'' and ``ethernet'' hooks */ snprintf(mkp.type, sizeof mkp.type, "%s", NG_PPPOE_NODE_TYPE); snprintf(mkp.ourhook, sizeof mkp.ourhook, "%s", NG_ETHER_HOOK_ORPHAN); diff --git a/usr.sbin/ppp/ppp/exec.c b/usr.sbin/ppp/ppp/exec.c index ff681b4ce40..9a57104a76f 100644 --- a/usr.sbin/ppp/ppp/exec.c +++ b/usr.sbin/ppp/ppp/exec.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: exec.c,v 1.16 2001/06/19 10:24:52 brian Exp $ + * $OpenBSD: exec.c,v 1.17 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -81,6 +81,7 @@ static struct device execdevice = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/usr.sbin/ppp/ppp/fsm.c b/usr.sbin/ppp/ppp/fsm.c index 1b0666c4e72..822fa604a76 100644 --- a/usr.sbin/ppp/ppp/fsm.c +++ b/usr.sbin/ppp/ppp/fsm.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: fsm.c,v 1.19 2001/08/19 23:22:17 brian Exp $ + * $OpenBSD: fsm.c,v 1.20 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -879,6 +879,7 @@ FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) case ST_CLOSED: case ST_CLOSING: NewState(fp, ST_CLOSED); + break; default: NewState(fp, ST_STOPPED); break; diff --git a/usr.sbin/ppp/ppp/i4b.c b/usr.sbin/ppp/ppp/i4b.c index bb3b02328c3..71342ff6094 100644 --- a/usr.sbin/ppp/ppp/i4b.c +++ b/usr.sbin/ppp/ppp/i4b.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: i4b.c,v 1.6 2001/10/24 10:01:13 brian Exp $ + * $OpenBSD: i4b.c,v 1.7 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -305,6 +305,7 @@ static struct device basei4bdevice = { i4b_Raw, i4b_Offline, i4b_Cooked, + NULL, i4b_StopTimer, i4b_Free, NULL, diff --git a/usr.sbin/ppp/ppp/iface.c b/usr.sbin/ppp/ppp/iface.c index 50c4cc1f7f2..c40d487a583 100644 --- a/usr.sbin/ppp/ppp/iface.c +++ b/usr.sbin/ppp/ppp/iface.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: iface.c,v 1.22 2002/01/16 14:13:06 brian Exp $ + * $OpenBSD: iface.c,v 1.23 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -231,6 +231,13 @@ iface_addr_Zap(const char *name, struct iface_addr *addr, int s) memcpy(peer4, &sspeer, sizeof *peer4); res = ID0ioctl(s, SIOCDIFADDR, &ifra); + if (log_IsKept(LogDEBUG)) { + char buf[100]; + + snprintf(buf, sizeof buf, "%s", ncprange_ntoa(&addr->ifa)); + log_Printf(LogWARN, "%s: DIFADDR %s -> %s returns %d\n", + ifra.ifra_name, buf, ncpaddr_ntoa(&addr->peer), res); + } break; #ifndef NOINET6 @@ -274,7 +281,7 @@ iface_addr_Zap(const char *name, struct iface_addr *addr, int s) return res != -1; } -static void +static int iface_addr_Add(const char *name, struct iface_addr *addr, int s) { struct ifaliasreq ifra; @@ -309,6 +316,13 @@ iface_addr_Add(const char *name, struct iface_addr *addr, int s) memcpy(peer4, &sspeer, sizeof *peer4); res = ID0ioctl(s, SIOCAIFADDR, &ifra); + if (log_IsKept(LogDEBUG)) { + char buf[100]; + + snprintf(buf, sizeof buf, "%s", ncprange_ntoa(&addr->ifa)); + log_Printf(LogWARN, "%s: AIFADDR %s -> %s returns %d\n", + ifra.ifra_name, buf, ncpaddr_ntoa(&addr->peer), res); + } break; #ifndef NOINET6 @@ -347,6 +361,8 @@ iface_addr_Add(const char *name, struct iface_addr *addr, int s) end, ncprange_ntoa(&addr->ifa), dst, strerror(errno)); } } + + return res != -1; } @@ -411,9 +427,9 @@ int iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa, const struct ncpaddr *peer, int how) { - int af, n, s, width; - struct ncpaddr ifaddr, ncplocal; - struct iface_addr *addr; + int af, n, removed, s, width; + struct ncpaddr ncplocal; + struct iface_addr *addr, newaddr; af = ncprange_family(ifa); if ((s = ID0socket(af, SOCK_DGRAM, 0)) == -1) { @@ -425,6 +441,7 @@ iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa, for (n = 0; n < iface->addrs; n++) { if (ncprange_contains(&iface->addr[n].ifa, &ncplocal) || ncpaddr_equal(&iface->addr[n].peer, peer)) { + /* Replace this sockaddr */ if (!(how & IFACE_FORCE_ADD)) { close(s); return 0; /* errno = EEXIST; */ @@ -441,19 +458,24 @@ iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa, (af == AF_INET6) ? 128 : #endif 32; - iface_addr_Zap(iface->name, iface->addr + n, s); - ncprange_setwidth(&iface->addr[n].ifa, width); - ncprange_getaddr(&iface->addr[n].ifa, &ifaddr); - if (ncpaddr_equal(&ifaddr, &ncplocal)) - ncpaddr_copy(&iface->addr[n].peer, peer); - else - ncpaddr_init(&iface->addr[n].peer); - iface_addr_Add(iface->name, iface->addr + n, s); - if (ncpaddr_equal(&ifaddr, &ncplocal)) { + removed = iface_addr_Zap(iface->name, iface->addr + n, s); + if (removed) + ncp_IfaceAddrDeleted(ncp, iface->addr + n); + ncprange_copy(&iface->addr[n].ifa, ifa); + ncpaddr_copy(&iface->addr[n].peer, peer); + if (!iface_addr_Add(iface->name, iface->addr + n, s)) { + if (removed) { + bcopy(iface->addr + n + 1, iface->addr + n, + (iface->addrs - n - 1) * sizeof *iface->addr); + iface->addrs--; + n--; + } close(s); - ncp_IfaceAddrAdded(ncp, iface->addr + n); - return 1; + return 0; } + close(s); + ncp_IfaceAddrAdded(ncp, iface->addr + n); + return 1; } } @@ -466,6 +488,14 @@ iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa, } iface->addr = addr; + ncprange_copy(&newaddr.ifa, ifa); + ncpaddr_copy(&newaddr.peer, peer); + newaddr.system = !!(how & IFACE_SYSTEM); + if (!iface_addr_Add(iface->name, &newaddr, s)) { + close(s); + return 0; + } + if (how & IFACE_ADD_FIRST) { /* Stuff it at the start of our list */ n = 0; @@ -474,10 +504,7 @@ iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa, n = iface->addrs; iface->addrs++; - ncprange_copy(&iface->addr[n].ifa, ifa); - ncpaddr_copy(&iface->addr[n].peer, peer); - iface->addr[n].system = !!(how & IFACE_SYSTEM); - iface_addr_Add(iface->name, iface->addr + n, s); + memcpy(iface->addr + n, &newaddr, sizeof(*iface->addr)); close(s); ncp_IfaceAddrAdded(ncp, iface->addr + n); @@ -499,12 +526,13 @@ iface_Delete(struct iface *iface, struct ncp *ncp, const struct ncpaddr *del) for (n = res = 0; n < iface->addrs; n++) { ncprange_getaddr(&iface->addr[n].ifa, &found); if (ncpaddr_equal(&found, del)) { - iface_addr_Zap(iface->name, iface->addr + n, s); - ncp_IfaceAddrDeleted(ncp, iface->addr + n); - bcopy(iface->addr + n + 1, iface->addr + n, - (iface->addrs - n - 1) * sizeof *iface->addr); - iface->addrs--; - res = 1; + if (iface_addr_Zap(iface->name, iface->addr + n, s)) { + ncp_IfaceAddrDeleted(ncp, iface->addr + n); + bcopy(iface->addr + n + 1, iface->addr + n, + (iface->addrs - n - 1) * sizeof *iface->addr); + iface->addrs--; + res = 1; + } break; } } diff --git a/usr.sbin/ppp/ppp/lcp.c b/usr.sbin/ppp/ppp/lcp.c index 5ebe750d552..57ded851603 100644 --- a/usr.sbin/ppp/ppp/lcp.c +++ b/usr.sbin/ppp/ppp/lcp.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: lcp.c,v 1.34 2001/11/23 11:17:03 brian Exp $ + * $OpenBSD: lcp.c,v 1.35 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -210,7 +210,7 @@ lcp_ReportStatus(struct cmdargs const *arg) command_ShowNegval(lcp->cfg.acfcomp)); prompt_Printf(arg->prompt, " CHAP = %s\n", command_ShowNegval(lcp->cfg.chap05)); -#ifdef HAVE_DES +#ifndef NODES prompt_Printf(arg->prompt, " CHAP80 = %s\n", command_ShowNegval(lcp->cfg.chap80nt)); prompt_Printf(arg->prompt, " LANMan = %s\n", @@ -268,7 +268,7 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l, lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED; lcp->cfg.chap05 = NEG_ACCEPTED; -#ifdef HAVE_DES +#ifndef NODES lcp->cfg.chap80nt = NEG_ACCEPTED; lcp->cfg.chap80lm = 0; lcp->cfg.chap81 = NEG_ACCEPTED; @@ -315,7 +315,7 @@ lcp_Setup(struct lcp *lcp, int openmode) if (IsEnabled(lcp->cfg.chap05)) { lcp->want_auth = PROTO_CHAP; lcp->want_authtype = 0x05; -#ifdef HAVE_DES +#ifndef NODES } else if (IsEnabled(lcp->cfg.chap80nt) || IsEnabled(lcp->cfg.chap80lm)) { lcp->want_auth = PROTO_CHAP; @@ -573,7 +573,7 @@ LcpLayerUp(struct fsm *fp) struct lcp *lcp = fsm2lcp(fp); log_Printf(LogLCP, "%s: LayerUp\n", fp->link->name); - async_SetLinkParams(&p->async, lcp); + physical_SetAsyncParams(p, lcp->want_accmap, lcp->his_accmap); lqr_Start(lcp); hdlc_StartTimer(&p->hdlc); fp->more.reqs = fp->more.naks = fp->more.rejs = lcp->cfg.fsm.maxreq * 3; @@ -795,7 +795,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); *dec->nakend++ = (unsigned char) PROTO_CHAP; *dec->nakend++ = 0x05; -#ifdef HAVE_DES +#ifndef NODES } else if (IsAccepted(lcp->cfg.chap80nt) || IsAccepted(lcp->cfg.chap80lm)) { *dec->nakend++ = *cp; @@ -820,7 +820,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, goto reqreject; } if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05)) -#ifdef HAVE_DES +#ifndef NODES || (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) || (IsAccepted(lcp->cfg.chap80lm)))) || (cp[4] == 0x81 && IsAccepted(lcp->cfg.chap81)) @@ -848,7 +848,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8); *dec->nakend++ = (unsigned char) PROTO_CHAP; *dec->nakend++ = 0x05; -#ifdef HAVE_DES +#ifndef NODES } else if (IsAccepted(lcp->cfg.chap80nt) || IsAccepted(lcp->cfg.chap80lm)) { *dec->nakend++ = *cp; @@ -896,7 +896,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, if (cp[4] == 0x05 && IsEnabled(lcp->cfg.chap05)) { lcp->want_auth = PROTO_CHAP; lcp->want_authtype = 0x05; -#ifdef HAVE_DES +#ifndef NODES } else if (cp[4] == 0x80 && (IsEnabled(lcp->cfg.chap80nt) || IsEnabled(lcp->cfg.chap80lm))) { lcp->want_auth = PROTO_CHAP; @@ -917,7 +917,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, #endif log_Printf(LogLCP, "Peer will only send %s (not %s)\n", Auth2Nam(PROTO_CHAP, cp[4]), -#ifdef HAVE_DES +#ifndef NODES (cp[4] == 0x80 || cp[4] == 0x81) ? "configured" : #endif "supported"); diff --git a/usr.sbin/ppp/ppp/lcp.h b/usr.sbin/ppp/ppp/lcp.h index b5bbd2de9c3..66ba19b1f43 100644 --- a/usr.sbin/ppp/ppp/lcp.h +++ b/usr.sbin/ppp/ppp/lcp.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: lcp.h,v 1.11 2001/10/24 10:01:15 brian Exp $ + * $OpenBSD: lcp.h,v 1.12 2002/03/31 02:38:49 brian Exp $ */ /* callback::opmask values */ @@ -92,7 +92,7 @@ struct lcp { struct fsm_retry fsm; /* How often/frequently to resend requests */ unsigned acfcomp : 2; /* Address & Control Field Compression neg */ unsigned chap05 : 2; /* Challenge Handshake Authentication proto */ -#ifdef HAVE_DES +#ifndef NODES unsigned chap80nt : 2; /* Microsoft (NT) CHAP */ unsigned chap80lm : 2; /* Microsoft (LANMan) CHAP */ unsigned chap81 : 2; /* Microsoft CHAP v2 */ diff --git a/usr.sbin/ppp/ppp/main.c b/usr.sbin/ppp/ppp/main.c index 39fa0ba1acb..5ade23042ce 100644 --- a/usr.sbin/ppp/ppp/main.c +++ b/usr.sbin/ppp/ppp/main.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: main.c,v 1.30 2001/08/19 23:22:18 brian Exp $ + * $OpenBSD: main.c,v 1.31 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -653,9 +653,9 @@ DoLoop(struct bundle *bundle) } if (descriptor_IsSet(&bundle->desc, wfds)) - if (!descriptor_Write(&bundle->desc, bundle, wfds) && nothing_done) { + if (descriptor_Write(&bundle->desc, bundle, wfds) <= 0 && nothing_done) { /* - * This is disasterous. The OS has told us that something is + * This is disastrous. The OS has told us that something is * writable, and all our write()s have failed. Rather than * going back immediately to do our UpdateSet()s and select(), * we sleep for a bit to avoid gobbling up all cpu time. diff --git a/usr.sbin/ppp/ppp/netgraph.c b/usr.sbin/ppp/ppp/netgraph.c new file mode 100644 index 00000000000..e048054f365 --- /dev/null +++ b/usr.sbin/ppp/ppp/netgraph.c @@ -0,0 +1,739 @@ +/*- + * Copyright (c) 2000 Brian Somers <brian@Awfulhak.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <netgraph.h> +#include <net/ethernet.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netgraph/ng_ether.h> +#include <netgraph/ng_message.h> +#include <netgraph/ng_socket.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <sys/fcntl.h> +#include <sys/uio.h> +#include <termios.h> +#include <sys/time.h> +#include <unistd.h> + +#include "layer.h" +#include "defs.h" +#include "mbuf.h" +#include "log.h" +#include "timer.h" +#include "lqr.h" +#include "hdlc.h" +#include "throughput.h" +#include "fsm.h" +#include "lcp.h" +#include "ccp.h" +#include "link.h" +#include "async.h" +#include "descriptor.h" +#include "physical.h" +#include "main.h" +#include "mp.h" +#include "chat.h" +#include "auth.h" +#include "chap.h" +#include "cbcp.h" +#include "datalink.h" +#include "slcompress.h" +#include "iplist.h" +#include "ncpaddr.h" +#include "ipcp.h" +#include "ipv6cp.h" +#include "ncp.h" +#include "filter.h" +#ifndef NORADIUS +#include "radius.h" +#endif +#include "bundle.h" +#include "id.h" +#include "netgraph.h" + + +struct ngdevice { + struct device dev; /* What struct physical knows about */ + int cs; /* Control socket */ + char hook[NG_HOOKLEN + 1]; /* Our socket node hook */ +}; + +#define device2ng(d) ((d)->type == NG_DEVICE ? (struct ngdevice *)d : NULL) +#define NG_MSGBUFSZ 4096 +#define NETGRAPH_PREFIX "netgraph:" + +int +ng_DeviceSize(void) +{ + return sizeof(struct ngdevice); +} + +static int +ng_MessageOut(struct ngdevice *dev, struct physical *p, const char *data) +{ + char path[NG_PATHLEN + 1]; + int len, pos, dpos; + char *fmt; + + /* + * We expect a node path, one or more spaces, a command, one or more + * spaces and an ascii netgraph structure. + */ + data += strspn(data, " \t"); + len = strcspn(data, " \t"); + if (len >= sizeof path) { + log_Printf(LogWARN, "%s: %.*s: Node path too long\n", + dev->dev.name, len, data); + return 0; + } + memcpy(path, data, len); + path[len] = '\0'; + data += len; + + data += strspn(data, " \t"); + len = strcspn(data, " \t"); + for (pos = len; pos >= 0; pos--) + if (data[pos] == '%') + len++; + if ((fmt = alloca(len + 4)) == NULL) { + log_Printf(LogWARN, "%s: alloca(%d) failure... %s\n", + dev->dev.name, len + 4, strerror(errno)); + return 0; + } + + /* + * This is probably a waste of time, but we really don't want to end + * up stuffing unexpected % escapes into the kernel.... + */ + for (pos = dpos = 0; pos < len;) { + if (data[dpos] == '%') + fmt[pos++] = '%'; + fmt[pos++] = data[dpos++]; + } + strcpy(fmt + pos, " %s"); + data += dpos; + + data += strspn(data, " \t"); + if (NgSendAsciiMsg(dev->cs, path, fmt, data) < 0) { + log_Printf(LogDEBUG, "%s: NgSendAsciiMsg (to %s): \"%s\", \"%s\": %s\n", + dev->dev.name, path, fmt, data, strerror(errno)); + return 0; + } + + return 1; +} + +/* + * Get a netgraph message + */ +static ssize_t +ng_MessageIn(struct physical *p, char *buf, size_t sz) +{ + char msgbuf[sizeof(struct ng_mesg) * 2 + NG_MSGBUFSZ]; + struct ngdevice *dev = device2ng(p->handler); + struct ng_mesg *rep = (struct ng_mesg *)msgbuf; + char path[NG_PATHLEN + 1]; + int len; + +#ifdef BROKEN_SELECT + struct timeval t; + fd_set *r; + int ret; + + if (dev->cs < 0) + return 0; + + if ((r = mkfdset()) == NULL) { + log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n"); + return -1; + } + zerofdset(r); + FD_SET(dev->cs, r); + t.tv_sec = t.tv_usec = 0; + ret = select(dev->cs + 1, r, NULL, NULL, &t); + free(r); + + if (ret <= 0) + return 0; +#endif + + if (NgRecvAsciiMsg(dev->cs, rep, sizeof msgbuf, path)) { + log_Printf(LogWARN, "%s: NgRecvAsciiMsg: %s\n", + dev->dev.name, strerror(errno)); + return -1; + } + + /* XXX: Should we check rep->header.version ? */ + + if (sz == 0) + log_Printf(LogWARN, "%s: Unexpected message: %s\n", dev->dev.name, + rep->header.cmdstr); + else { + log_Printf(LogDEBUG, "%s: Received message: %s\n", dev->dev.name, + rep->header.cmdstr); + len = strlen(rep->header.cmdstr); + if (sz > len) + sz = len; + memcpy(buf, rep->header.cmdstr, sz); + } + + return sz; +} + +static ssize_t +ng_Write(struct physical *p, const void *v, size_t n) +{ + struct ngdevice *dev = device2ng(p->handler); + + switch (p->dl->state) { + case DATALINK_DIAL: + case DATALINK_LOGIN: + return ng_MessageOut(dev, p, v) ? n : -1; + } + return NgSendData(p->fd, dev->hook, v, n) == -1 ? -1 : n; +} + +static ssize_t +ng_Read(struct physical *p, void *v, size_t n) +{ + char hook[NG_HOOKLEN + 1]; + +log_Printf(LogDEBUG, "ng_Read\n"); + switch (p->dl->state) { + case DATALINK_DIAL: + case DATALINK_LOGIN: + return ng_MessageIn(p, v, n); + } + + return NgRecvData(p->fd, v, n, hook); +} + +static int +ng_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) +{ + struct ngdevice *dev = device2ng(p->handler); + int result; + + if (r && dev->cs >= 0 && FD_ISSET(dev->cs, r)) { + FD_CLR(dev->cs, r); + log_Printf(LogTIMER, "%s: fdunset(ctrl) %d\n", p->link.name, dev->cs); + result = 1; + } else + result = 0; + + /* Careful... physical_RemoveFromSet() called us ! */ + + p->handler->removefromset = NULL; + result += physical_RemoveFromSet(p, r, w, e); + p->handler->removefromset = ng_RemoveFromSet; + + return result; +} + +static void +ng_Free(struct physical *p) +{ + struct ngdevice *dev = device2ng(p->handler); + + physical_SetDescriptor(p); + if (dev->cs != -1) + close(dev->cs); + free(dev); +} + +static void +ng_device2iov(struct device *d, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + struct ngdevice *dev = device2ng(d); + int sz = physical_MaxDeviceSize(); + + iov[*niov].iov_base = realloc(d, sz); + if (iov[*niov].iov_base == NULL) { + log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); + AbortProgram(EX_OSERR); + } + iov[*niov].iov_len = sz; + (*niov)++; + + *auxfd = dev->cs; + (*nauxfd)++; +} + +static const struct device basengdevice = { + NG_DEVICE, + "netgraph", + 0, + { CD_REQUIRED, DEF_NGCDDELAY }, + NULL, + ng_RemoveFromSet, + NULL, + NULL, + NULL, + NULL, + NULL, + ng_Free, + ng_Read, + ng_Write, + ng_device2iov, + NULL, + NULL +}; + +struct device * +ng_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + if (type == NG_DEVICE) { + struct ngdevice *dev = (struct ngdevice *)iov[(*niov)++].iov_base; + + dev = realloc(dev, sizeof *dev); /* Reduce to the correct size */ + if (dev == NULL) { + log_Printf(LogALERT, "Failed to allocate memory: %d\n", + (int)(sizeof *dev)); + AbortProgram(EX_OSERR); + } + + if (*nauxfd) { + dev->cs = *auxfd; + (*nauxfd)--; + } else + dev->cs = -1; + + /* Refresh function pointers etc */ + memcpy(&dev->dev, &basengdevice, sizeof dev->dev); + + /* XXX: Are netgraph always synchronous ? */ + physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF); + return &dev->dev; + } + + return NULL; +} + +static int +ng_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +{ + struct physical *p = descriptor2physical(d); + struct ngdevice *dev = device2ng(p->handler); + int result; + + switch (p->dl->state) { + case DATALINK_DIAL: + case DATALINK_LOGIN: + if (r) { + FD_SET(dev->cs, r); + log_Printf(LogTIMER, "%s(ctrl): fdset(r) %d\n", p->link.name, dev->cs); + result = 1; + } else + result = 0; + break; + + default: + result = physical_doUpdateSet(d, r, w, e, n, 0); + break; + } + + return result; +} + +static int +ng_IsSet(struct fdescriptor *d, const fd_set *fdset) +{ + struct physical *p = descriptor2physical(d); + struct ngdevice *dev = device2ng(p->handler); + int result; + + result = dev->cs >= 0 && FD_ISSET(dev->cs, fdset); + result += physical_IsSet(d, fdset); + + return result; +} + +static void +ng_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, + const fd_set *fdset) +{ + struct physical *p = descriptor2physical(d); + struct ngdevice *dev = device2ng(p->handler); + + if (dev->cs >= 0 && FD_ISSET(dev->cs, fdset)) + ng_MessageIn(p, NULL, 0); + + if (physical_IsSet(d, fdset)) + physical_DescriptorRead(d, bundle, fdset); +} + +static struct device * +ng_Abandon(struct ngdevice *dev, struct physical *p) +{ + /* Abandon our node construction */ + close(dev->cs); + close(p->fd); + p->fd = -2; /* Nobody else need try.. */ + free(dev); + + return NULL; +} + + +/* + * Populate the ``word'' (of size ``sz'') named ``what'' from ``from'' + * ending with any character from ``sep''. Point ``endp'' at the next + * word. + */ + +#define GETSEGMENT(what, from, sep, endp) \ + getsegment(#what, (what), sizeof(what), from, sep, endp) + +static int +getsegment(const char *what, char *word, size_t sz, const char *from, + const char *sep, const char **endp) +{ + int len; + + if ((len = strcspn(from, sep)) == 0) { + log_Printf(LogWARN, "%s name should not be empty !\n", what); + return 0; + } + + if (len >= sz) { + log_Printf(LogWARN, "%s name too long, max %d !\n", what, sz - 1); + return 0; + } + + strncpy(word, from, len); + word[len] = '\0'; + + *endp = from + len; + *endp += strspn(*endp, sep); + + return 1; +} + +struct device * +ng_Create(struct physical *p) +{ + struct sockaddr_ng ngsock; + u_char rbuf[2048]; + struct sockaddr *sock = (struct sockaddr *)&ngsock; + const struct hooklist *hlist; + const struct nodeinfo *ninfo; + const struct linkinfo *nlink; + struct ngdevice *dev; + struct ng_mesg *resp; + struct ngm_mkpeer mkp; + struct ngm_connect ngc; + const char *devp, *endp; + char lasthook[NG_HOOKLEN + 1]; + char hook[NG_HOOKLEN + 1]; + char nodetype[NG_TYPELEN + NG_NODELEN + 2]; + char modname[NG_TYPELEN + 4]; + char path[NG_PATHLEN + 1]; + char *nodename; + int len, sz, done, f; + + dev = NULL; + if (p->fd < 0 && !strncasecmp(p->name.full, NETGRAPH_PREFIX, + sizeof NETGRAPH_PREFIX - 1)) { + p->fd--; /* We own the device - change fd */ + + if ((dev = malloc(sizeof *dev)) == NULL) + return NULL; + + loadmodules(LOAD_VERBOSLY, "netgraph", "ng_socket", NULL); + + /* Create a socket node */ + if (ID0NgMkSockNode(NULL, &dev->cs, &p->fd) == -1) { + log_Printf(LogWARN, "Cannot create netgraph socket node: %s\n", + strerror(errno)); + free(dev); + p->fd = -2; + return NULL; + } + + devp = p->name.full + sizeof NETGRAPH_PREFIX - 1; + *lasthook = *path = '\0'; + log_Printf(LogDEBUG, "%s: Opening netgraph device \"%s\"\n", + p->link.name, devp); + done = 0; + + while (*devp != '\0' && !done) { + if (*devp != '[') { + if (*lasthook == '\0') { + log_Printf(LogWARN, "%s: Netgraph devices must start with" + " [nodetype:nodename]\n", p->link.name); + return ng_Abandon(dev, p); + } + + /* Get the hook name of the new node */ + if (!GETSEGMENT(hook, devp, ".[", &endp)) + return ng_Abandon(dev, p); + log_Printf(LogDEBUG, "%s: Got hook \"%s\"\n", p->link.name, hook); + devp = endp; + if (*devp == '\0') { + log_Printf(LogWARN, "%s: Netgraph device must not end with a second" + " hook\n", p->link.name); + return ng_Abandon(dev, p); + } + if (devp[-1] != '[') { + log_Printf(LogWARN, "%s: Expected a [nodetype:nodename] at device" + " pos %d\n", p->link.name, devp - p->link.name - 1); + return ng_Abandon(dev, p); + } + } else { + /* Use lasthook as the hook name */ + strcpy(hook, lasthook); + devp++; + } + + /* We've got ``lasthook'' and ``hook'', get the node type */ + if (!GETSEGMENT(nodetype, devp, "]", &endp)) + return ng_Abandon(dev, p); + log_Printf(LogDEBUG, "%s: Got node \"%s\"\n", p->link.name, nodetype); + + if ((nodename = strchr(nodetype, ':')) != NULL) { + *nodename++ = '\0'; + if (*nodename == '\0' && *nodetype == '\0') { + log_Printf(LogWARN, "%s: Empty [nodetype:nodename] at device" + " pos %d\n", p->link.name, devp - p->link.name - 1); + return ng_Abandon(dev, p); + } + } + + /* Ignore optional colons after nodes */ + devp = *endp == ':' ? endp + 1 : endp; + if (*devp == '.') + devp++; + + if (*lasthook == '\0') { + /* This is the first node in the chain */ + if (nodename == NULL || *nodename == '\0') { + log_Printf(LogWARN, "%s: %s: No initial device nodename\n", + p->link.name, devp); + return ng_Abandon(dev, p); + } + + if (*nodetype != '\0') { + /* Attempt to load the module */ + snprintf(modname, sizeof modname, "ng_%s", nodetype); + log_Printf(LogDEBUG, "%s: Attempting to load %s.ko\n", + p->link.name, modname); + loadmodules(LOAD_QUIETLY, modname, NULL); + } + + snprintf(path, sizeof path, "%s:", nodename); + /* XXX: If we have a node type, ensure it's correct */ + } else { + /* + * Ask for a list of hooks attached to the previous node. If we + * find the one we're interested in, and if it's connected to a + * node of the right type using the correct hook, use that. + * If we find the hook connected to something else, fail. + * If we find no match, mkpeer the new node. + */ + if (*nodetype == '\0') { + log_Printf(LogWARN, "%s: Nodetype missing at device offset %d\n", + p->link.name, + devp - p->name.full + sizeof NETGRAPH_PREFIX - 1); + return ng_Abandon(dev, p); + } + + /* Get a list of node hooks */ + if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, NGM_LISTHOOKS, + NULL, 0) < 0) { + log_Printf(LogWARN, "%s: %s Cannot send a LISTHOOOKS message: %s\n", + p->link.name, path, strerror(errno)); + return ng_Abandon(dev, p); + } + + /* Get our list back */ + resp = (struct ng_mesg *)rbuf; + if (NgRecvMsg(dev->cs, resp, sizeof rbuf, NULL) <= 0) { + log_Printf(LogWARN, "%s: Cannot get netgraph response: %s\n", + p->link.name, strerror(errno)); + return ng_Abandon(dev, p); + } + + hlist = (const struct hooklist *)resp->data; + ninfo = &hlist->nodeinfo; + + log_Printf(LogDEBUG, "List of netgraph node ``%s'' (id %x) hooks:\n", + path, ninfo->id); + + /* look for a hook already attached. */ + for (f = 0; f < ninfo->hooks; f++) { + nlink = &hlist->link[f]; + + log_Printf(LogDEBUG, " Found %s -> %s (type %s)\n", nlink->ourhook, + nlink->peerhook, nlink->nodeinfo.type); + + if (!strcmp(nlink->ourhook, lasthook)) { + if (strcmp(nlink->peerhook, hook) || + strcmp(nlink->nodeinfo.type, nodetype)) { + log_Printf(LogWARN, "%s: hook %s:%s is already in use\n", + p->link.name, nlink->ourhook, path); + return ng_Abandon(dev, p); + } + /* The node is already hooked up nicely.... reuse it */ + break; + } + } + + if (f == ninfo->hooks) { + /* Attempt to load the module */ + snprintf(modname, sizeof modname, "ng_%s", nodetype); + log_Printf(LogDEBUG, "%s: Attempting to load %s.ko\n", + p->link.name, modname); + loadmodules(LOAD_QUIETLY, modname, NULL); + + /* Create (mkpeer) the new node */ + + snprintf(mkp.type, sizeof mkp.type, "%s", nodetype); + snprintf(mkp.ourhook, sizeof mkp.ourhook, "%s", lasthook); + snprintf(mkp.peerhook, sizeof mkp.peerhook, "%s", hook); + + log_Printf(LogDEBUG, "%s: Doing MKPEER %s%s -> %s (type %s)\n", + p->link.name, path, mkp.ourhook, mkp.peerhook, nodetype); + + if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, + NGM_MKPEER, &mkp, sizeof mkp) < 0) { + log_Printf(LogWARN, "%s Cannot create %s netgraph node: %s\n", + path, nodetype, strerror(errno)); + return ng_Abandon(dev, p); + } + } + len = strlen(path); + snprintf(path + len, sizeof path - len, "%s%s", + path[len - 1] == ':' ? "" : ".", lasthook); + } + + /* Get a list of node hooks */ + if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, NGM_LISTHOOKS, + NULL, 0) < 0) { + log_Printf(LogWARN, "%s: %s Cannot send a LISTHOOOKS message: %s\n", + p->link.name, path, strerror(errno)); + return ng_Abandon(dev, p); + } + + /* Get our list back */ + resp = (struct ng_mesg *)rbuf; + if (NgRecvMsg(dev->cs, resp, sizeof rbuf, NULL) <= 0) { + log_Printf(LogWARN, "%s: Cannot get netgraph response: %s\n", + p->link.name, strerror(errno)); + return ng_Abandon(dev, p); + } + + hlist = (const struct hooklist *)resp->data; + ninfo = &hlist->nodeinfo; + + if (*lasthook != '\0' && nodename != NULL && *nodename != '\0' && + strcmp(ninfo->name, nodename) && + NgNameNode(dev->cs, path, "%s", nodename) < 0) { + log_Printf(LogWARN, "%s: %s: Cannot name netgraph node: %s\n", + p->link.name, path, strerror(errno)); + return ng_Abandon(dev, p); + } + + if (!GETSEGMENT(lasthook, devp, " \t.[", &endp)) + return ng_Abandon(dev, p); + log_Printf(LogDEBUG, "%s: Got hook \"%s\"\n", p->link.name, lasthook); + + len = strlen(lasthook); + done = strchr(" \t", devp[len]) ? 1 : 0; + devp = endp; + + if (*devp != '\0') { + if (devp[-1] == '[') + devp--; + } /* else should moan about devp[-1] being '[' ? */ + } + + snprintf(dev->hook, sizeof dev->hook, "%s", lasthook); + + /* Connect the node to our socket node */ + snprintf(ngc.path, sizeof ngc.path, "%s", path); + snprintf(ngc.ourhook, sizeof ngc.ourhook, "%s", dev->hook); + memcpy(ngc.peerhook, ngc.ourhook, sizeof ngc.peerhook); + + log_Printf(LogDEBUG, "Connecting netgraph socket .:%s -> %s.%s\n", + ngc.ourhook, ngc.path, ngc.peerhook); + if (NgSendMsg(dev->cs, ".:", NGM_GENERIC_COOKIE, + NGM_CONNECT, &ngc, sizeof ngc) < 0) { + log_Printf(LogWARN, "Cannot connect %s and socket netgraph " + "nodes: %s\n", path, strerror(errno)); + return ng_Abandon(dev, p); + } + + /* Hook things up so that we monitor dev->cs */ + p->desc.UpdateSet = ng_UpdateSet; + p->desc.IsSet = ng_IsSet; + p->desc.Read = ng_DescriptorRead; + + memcpy(&dev->dev, &basengdevice, sizeof dev->dev); + + } else { + /* See if we're a netgraph socket */ + + sz = sizeof ngsock; + if (getsockname(p->fd, sock, &sz) != -1 && sock->sa_family == AF_NETGRAPH) { + /* + * It's a netgraph node... We can't determine hook names etc, so we + * stay pretty impartial.... + */ + log_Printf(LogPHASE, "%s: Link is a netgraph node\n", p->link.name); + + if ((dev = malloc(sizeof *dev)) == NULL) { + log_Printf(LogWARN, "%s: Cannot allocate an ether device: %s\n", + p->link.name, strerror(errno)); + return NULL; + } + + memcpy(&dev->dev, &basengdevice, sizeof dev->dev); + dev->cs = -1; + *dev->hook = '\0'; + } + } + + if (dev) { + physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF); + return &dev->dev; + } + + return NULL; +} diff --git a/usr.sbin/ppp/ppp/netgraph.h b/usr.sbin/ppp/ppp/netgraph.h new file mode 100644 index 00000000000..8bcf835bd25 --- /dev/null +++ b/usr.sbin/ppp/ppp/netgraph.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2000 Brian Somers <brian@Awfulhak.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +struct physical; +struct device; + +#define DEF_NGCDDELAY 5 /* Default ``set cd'' value */ + +extern struct device *ng_Create(struct physical *); +extern struct device *ng_iov2device(int, struct physical *, struct iovec *, + int *, int, int *, int *); +extern int ng_DeviceSize(void); diff --git a/usr.sbin/ppp/ppp/physical.c b/usr.sbin/ppp/ppp/physical.c index 1b7794c5766..641bf8ee81b 100644 --- a/usr.sbin/ppp/ppp/physical.c +++ b/usr.sbin/ppp/ppp/physical.c @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: physical.c,v 1.32 2002/02/21 07:32:55 fgsch Exp $ + * $OpenBSD: physical.c,v 1.33 2002/03/31 02:38:49 brian Exp $ * */ @@ -100,6 +100,7 @@ #endif #ifndef NONETGRAPH #include "ether.h" +#include "netgraph.h" #endif #ifndef NOATM #include "atm.h" @@ -137,6 +138,9 @@ struct { * able to identify it as a more specific type of SOCK_DGRAM. */ { ether_Create, ether_iov2device, ether_DeviceSize }, +#ifdef EXPERIMENTAL_NETGRAPH + { ng_Create, ng_iov2device, ng_DeviceSize }, +#endif #endif #ifndef NOATM /* Ditto for ATM devices */ @@ -593,7 +597,7 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, p->desc.Write = physical_DescriptorWrite; p->type = PHYS_DIRECT; p->dl = dl; - len = sizeof(_PATH_DEV) - 1; + len = strlen(_PATH_DEV); p->out = NULL; p->connect_count = 1; @@ -953,7 +957,7 @@ physical_DeleteQueue(struct physical *p) void physical_SetDevice(struct physical *p, const char *name) { - int len = sizeof(_PATH_DEV) - 1; + int len = strlen(_PATH_DEV); if (name != p->name.full) { strncpy(p->name.full, name, sizeof p->name.full - 1); @@ -1100,3 +1104,13 @@ physical_AwaitCarrier(struct physical *p) return CARRIER_OK; } + + +void +physical_SetAsyncParams(struct physical *p, u_int32_t mymap, u_int32_t hismap) +{ + if (p->handler && p->handler->setasyncparams) + return (*p->handler->setasyncparams)(p, mymap, hismap); + + async_SetLinkParams(&p->async, mymap, hismap); +} diff --git a/usr.sbin/ppp/ppp/physical.h b/usr.sbin/ppp/ppp/physical.h index 34025a577b2..633e62ac583 100644 --- a/usr.sbin/ppp/ppp/physical.h +++ b/usr.sbin/ppp/ppp/physical.h @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: physical.h,v 1.18 2001/06/19 10:24:56 brian Exp $ + * $OpenBSD: physical.h,v 1.19 2002/03/31 02:38:49 brian Exp $ * */ @@ -36,6 +36,7 @@ struct cmdargs; #define ETHER_DEVICE 5 #define EXEC_DEVICE 6 #define ATM_DEVICE 7 +#define NG_DEVICE 8 /* Returns from awaitcarrier() */ #define CARRIER_PENDING 1 @@ -64,6 +65,7 @@ struct device { int (*raw)(struct physical *); void (*offline)(struct physical *); void (*cooked)(struct physical *); + void (*setasyncparams)(struct physical *, u_int32_t, u_int32_t); void (*stoptimer)(struct physical *); void (*destroy)(struct physical *); ssize_t (*read)(struct physical *, void *, size_t); @@ -166,3 +168,4 @@ extern void physical_StopDeviceTimer(struct physical *); extern int physical_MaxDeviceSize(void); extern int physical_AwaitCarrier(struct physical *); extern void physical_SetDescriptor(struct physical *); +extern void physical_SetAsyncParams(struct physical *, u_int32_t, u_int32_t); diff --git a/usr.sbin/ppp/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp/ppp.8.m4 index 1452dfc4b50..fff5c168cb6 100644 --- a/usr.sbin/ppp/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp/ppp.8.m4 @@ -25,7 +25,7 @@ changecom(,)dnl .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: ppp.8.m4,v 1.5 2002/03/25 14:22:39 brian Exp $ +.\" $OpenBSD: ppp.8.m4,v 1.6 2002/03/31 02:38:49 brian Exp $ .\" .Dd September 20, 1995 .Dt PPP 8 @@ -67,8 +67,12 @@ to act as a NAT or masquerading engine for all machines on an internal LAN. ifdef({LOCALNAT},{},{Refer to .Xr libalias 3 -for details. +for details on the technical side of the NAT engine. })dnl +Refer to the +.Sx NETWORK ADDRESS TRANSLATION (PACKET ALIASING) +section of this manual page for details on how to configure NAT in +.Nm ppp . .Pp The .Fl quiet @@ -4491,6 +4495,12 @@ The given is passed as the service name in the PPPoE Discovery Initiation (PADI) packet. If no provider is given, an empty value will be used. +.Pp +When a PPPoE connection is established, +.Nm +will place the name of the Access Concentrator in the environment variable +.Ev ACNAME . +.Pp Refer to .Xr netgraph 4 and diff --git a/usr.sbin/ppp/ppp/route.c b/usr.sbin/ppp/ppp/route.c index 0a2a2afe87c..252b6d88b7a 100644 --- a/usr.sbin/ppp/ppp/route.c +++ b/usr.sbin/ppp/ppp/route.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: route.c,v 1.24 2002/01/16 14:13:06 brian Exp $ + * $OpenBSD: route.c,v 1.25 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -847,7 +847,7 @@ rt_Update(struct bundle *bundle, const struct sockaddr *dst, rtmes.m_rtm.rtm_addrs = 0; rtmes.m_rtm.rtm_seq = ++bundle->routing_seq; rtmes.m_rtm.rtm_pid = getpid(); - rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; + rtmes.m_rtm.rtm_flags = RTF_UP | RTF_STATIC; if (bundle->ncp.cfg.sendpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe; @@ -867,6 +867,7 @@ rt_Update(struct bundle *bundle, const struct sockaddr *dst, rtmes.m_rtm.rtm_addrs |= RTA_DST; p += memcpy_roundup(p, dst, dst->sa_len); } + rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; p += memcpy_roundup(p, gw, gw->sa_len); if (mask) { diff --git a/usr.sbin/ppp/ppp/tcp.c b/usr.sbin/ppp/ppp/tcp.c index 3d9a5159e54..1af56e94bc9 100644 --- a/usr.sbin/ppp/ppp/tcp.c +++ b/usr.sbin/ppp/ppp/tcp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: tcp.c,v 1.13 2002/01/16 14:13:06 brian Exp $ + * $OpenBSD: tcp.c,v 1.14 2002/03/31 02:38:49 brian Exp $ */ #include <sys/types.h> @@ -113,6 +113,7 @@ static struct device tcpdevice = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/usr.sbin/ppp/ppp/tty.c b/usr.sbin/ppp/ppp/tty.c index 951a1a6248c..51db0fec40f 100644 --- a/usr.sbin/ppp/ppp/tty.c +++ b/usr.sbin/ppp/ppp/tty.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: tty.c,v 1.16 2001/06/19 10:25:00 brian Exp $ + * $OpenBSD: tty.c,v 1.17 2002/03/31 02:38:49 brian Exp $ */ #include <sys/param.h> @@ -34,12 +34,20 @@ #include <errno.h> #include <fcntl.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <sys/uio.h> #include <termios.h> #include <unistd.h> +#ifndef NONETGRAPH +#include <netgraph.h> +#include <netgraph/ng_async.h> +#include <netgraph/ng_message.h> +#include <netgraph/ng_ppp.h> +#include <netgraph/ng_tty.h> +#endif #include "layer.h" #include "defs.h" @@ -63,6 +71,7 @@ #include "cbcp.h" #include "datalink.h" #include "main.h" +#include "id.h" #include "tty.h" #if defined(__mac68k__) || defined(__macppc__) @@ -79,6 +88,15 @@ struct ttydevice { struct pppTimer Timer; /* CD checks */ int mbits; /* Current DCD status */ int carrier_seconds; /* seconds before CD is *required* */ +#ifndef NONETGRAPH + struct { + int speed; /* Pre-line-discipline speed */ + int fd; /* Pre-line-discipline fd */ + int disc; /* Old line-discipline */ + } real; + char hook[sizeof NG_ASYNC_HOOK_SYNC]; /* our ng_socket hook */ + int cs; /* A netgraph control socket (maybe) */ +#endif struct termios ios; /* To be able to reset from raw mode */ }; @@ -192,6 +210,216 @@ tty_AwaitCarrier(struct physical *p) return Online(dev) ? CARRIER_OK : CARRIER_LOST; } +#ifdef NONETGRAPH +#define tty_SetAsyncParams NULL +#define tty_Write NULL +#define tty_Read NULL +#else + +static int +isngtty(struct ttydevice *dev) +{ + return dev->real.fd != -1; +} + +static void +tty_SetAsyncParams(struct physical *p, u_int32_t mymap, u_int32_t hismap) +{ + struct ttydevice *dev = device2tty(p->handler); + char asyncpath[NG_PATHLEN + 1]; + struct ng_async_cfg cfg; + + if (isngtty(dev)) { + /* Configure the async converter node */ + + snprintf(asyncpath, sizeof asyncpath, ".:%s", dev->hook); + memset(&cfg, 0, sizeof cfg); + cfg.enabled = 1; + cfg.accm = mymap | hismap; + cfg.amru = MAX_MTU; + cfg.smru = MAX_MRU; + log_Printf(LogDEBUG, "Configure async node at %s\n", asyncpath); + if (NgSendMsg(dev->cs, asyncpath, NGM_ASYNC_COOKIE, + NGM_ASYNC_CMD_SET_CONFIG, &cfg, sizeof cfg) < 0) + log_Printf(LogWARN, "%s: Can't configure async node at %s\n", + p->link.name, asyncpath); + } else + /* No netgraph node, just config the async layer */ + async_SetLinkParams(&p->async, mymap, hismap); +} + +static int +LoadLineDiscipline(struct physical *p) +{ + struct ttydevice *dev = device2tty(p->handler); + u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; + struct ng_mesg *reply; + struct nodeinfo *info; + char ttypath[NG_NODELEN + 1]; + struct ngm_mkpeer ngm; + struct ngm_connect ngc; + int ldisc, cs, ds, hot, speed; + + reply = (struct ng_mesg *)rbuf; + info = (struct nodeinfo *)reply->data; + + loadmodules(LOAD_VERBOSLY, "netgraph", "ng_tty", "ng_async", "ng_socket", + NULL); + + /* Get the speed before loading the line discipline */ + speed = physical_GetSpeed(p); + + if (ioctl(p->fd, TIOCGETD, &dev->real.disc) < 0) { + log_Printf(LogDEBUG, "%s: Couldn't get tty line discipline\n", + p->link.name); + return 0; + } + ldisc = NETGRAPHDISC; + if (ID0ioctl(p->fd, TIOCSETD, &ldisc) < 0) { + log_Printf(LogDEBUG, "%s: Couldn't set NETGRAPHDISC line discipline\n", + p->link.name); + return 0; + } + + /* Get the name of the tty node */ + if (ioctl(p->fd, NGIOCGINFO, info) < 0) { + log_Printf(LogWARN, "%s: ioctl(NGIOCGINFO): %s\n", p->link.name, + strerror(errno)); + ID0ioctl(p->fd, TIOCSETD, &dev->real.disc); + return 0; + } + snprintf(ttypath, sizeof ttypath, "%s:", info->name); + + /* Create a socket node for our endpoint (and to send messages via) */ + if (ID0NgMkSockNode(NULL, &cs, &ds) == -1) { + log_Printf(LogWARN, "%s: NgMkSockNode: %s\n", p->link.name, + strerror(errno)); + ID0ioctl(p->fd, TIOCSETD, &dev->real.disc); + return 0; + } + + /* Set the ``hot char'' on the TTY node */ + hot = HDLC_SYN; + log_Printf(LogDEBUG, "%s: Set tty hotchar to 0x%02x\n", p->link.name, hot); + if (NgSendMsg(cs, ttypath, NGM_TTY_COOKIE, + NGM_TTY_SET_HOTCHAR, &hot, sizeof hot) < 0) { + log_Printf(LogWARN, "%s: Can't set hot char\n", p->link.name); + goto failed; + } + + /* Attach an async converter node */ + snprintf(ngm.type, sizeof ngm.type, "%s", NG_ASYNC_NODE_TYPE); + snprintf(ngm.ourhook, sizeof ngm.ourhook, "%s", NG_TTY_HOOK); + snprintf(ngm.peerhook, sizeof ngm.peerhook, "%s", NG_ASYNC_HOOK_ASYNC); + log_Printf(LogDEBUG, "%s: Send mkpeer async:%s to %s:%s\n", p->link.name, + ngm.peerhook, ttypath, ngm.ourhook); + if (NgSendMsg(cs, ttypath, NGM_GENERIC_COOKIE, + NGM_MKPEER, &ngm, sizeof ngm) < 0) { + log_Printf(LogWARN, "%s: Can't create %s node\n", p->link.name, + NG_ASYNC_NODE_TYPE); + goto failed; + } + + /* Connect the async node to our socket */ + snprintf(ngc.path, sizeof ngc.path, "%s%s", ttypath, NG_TTY_HOOK); + snprintf(ngc.peerhook, sizeof ngc.peerhook, "%s", NG_ASYNC_HOOK_SYNC); + memcpy(ngc.ourhook, ngc.peerhook, sizeof ngc.ourhook); + log_Printf(LogDEBUG, "%s: Send connect %s:%s to .:%s\n", p->link.name, + ngc.path, ngc.peerhook, ngc.ourhook); + if (NgSendMsg(cs, ".:", NGM_GENERIC_COOKIE, NGM_CONNECT, + &ngc, sizeof ngc) < 0) { + log_Printf(LogWARN, "%s: Can't connect .:%s -> %s.%s: %s\n", + p->link.name, ngc.ourhook, ngc.path, ngc.peerhook, + strerror(errno)); + goto failed; + } + + /* Get the async node id */ + if (NgSendMsg(cs, ngc.path, NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) { + log_Printf(LogWARN, "%s: Can't request async node info at %s: %s\n", + p->link.name, ngc.path, strerror(errno)); + goto failed; + } + if (NgRecvMsg(cs, reply, sizeof rbuf, NULL) < 0) { + log_Printf(LogWARN, "%s: Can't obtain async node info at %s: %s\n", + p->link.name, ngc.path, strerror(errno)); + goto failed; + } + + /* All done, set up our device state */ + snprintf(dev->hook, sizeof dev->hook, "%s", ngc.ourhook); + dev->cs = cs; + dev->real.fd = p->fd; + p->fd = ds; + dev->real.speed = speed; + physical_SetSync(p); + + tty_SetAsyncParams(p, 0xffffffff, 0xffffffff); + physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); + log_Printf(LogPHASE, "%s: Loaded netgraph tty line discipline\n", + p->link.name); + + return 1; + +failed: + ID0ioctl(p->fd, TIOCSETD, &dev->real.disc); + close(ds); + close(cs); + + return 0; +} + +static void +UnloadLineDiscipline(struct physical *p) +{ + struct ttydevice *dev = device2tty(p->handler); + + if (isngtty(dev)) { +log_Printf(LogPHASE, "back to speed %d\n", dev->real.speed); + if (!physical_SetSpeed(p, dev->real.speed)) + log_Printf(LogWARN, "Couldn't reset tty speed to %d\n", dev->real.speed); + dev->real.speed = 0; + close(p->fd); + p->fd = dev->real.fd; + dev->real.fd = -1; + close(dev->cs); + dev->cs = -1; + *dev->hook = '\0'; + if (ID0ioctl(p->fd, TIOCSETD, &dev->real.disc) == 0) { + physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); + log_Printf(LogPHASE, "%s: Unloaded netgraph tty line discipline\n", + p->link.name); + } else + log_Printf(LogWARN, "%s: Failed to unload netgraph tty line discipline\n", + p->link.name); + } +} + +static ssize_t +tty_Write(struct physical *p, const void *v, size_t n) +{ + struct ttydevice *dev = device2tty(p->handler); + + if (isngtty(dev)) + return NgSendData(p->fd, dev->hook, v, n) == -1 ? -1 : n; + else + return write(p->fd, v, n); +} + +static ssize_t +tty_Read(struct physical *p, void *v, size_t n) +{ + struct ttydevice *dev = device2tty(p->handler); + char hook[sizeof NG_ASYNC_HOOK_SYNC]; + + if (isngtty(dev)) + return NgRecvData(p->fd, v, n, hook); + else + return read(p->fd, v, n); +} + +#endif /* NETGRAPH */ + static int tty_Raw(struct physical *p) { @@ -206,19 +434,24 @@ tty_Raw(struct physical *p) p->link.name, p->fd, dev->mbits); if (!physical_IsSync(p)) { - tcgetattr(p->fd, &ios); - cfmakeraw(&ios); - if (p->cfg.rts_cts) - ios.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW; - else - ios.c_cflag |= CLOCAL; - - if (p->type != PHYS_DEDICATED) - ios.c_cflag |= HUPCL; - - if (tcsetattr(p->fd, TCSANOW, &ios) == -1) - log_Printf(LogWARN, "%s: tcsetattr: Failed configuring device\n", - p->link.name); +#ifndef NONETGRAPH + if (!LoadLineDiscipline(p)) +#endif + { + tcgetattr(p->fd, &ios); + cfmakeraw(&ios); + if (p->cfg.rts_cts) + ios.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW; + else + ios.c_cflag |= CLOCAL; + + if (p->type != PHYS_DEDICATED) + ios.c_cflag |= HUPCL; + + if (tcsetattr(p->fd, TCSANOW, &ios) == -1) + log_Printf(LogWARN, "%s: tcsetattr: Failed configuring device\n", + p->link.name); + } } oldflag = fcntl(p->fd, F_GETFL, 0); @@ -262,6 +495,10 @@ tty_Cooked(struct physical *p) log_Printf(LogWARN, "%s: tcsetattr: Unable to restore device settings\n", p->link.name); +#ifndef NONETGRAPH + UnloadLineDiscipline(p); +#endif + if ((oldflag = fcntl(p->fd, F_GETFL, 0)) != -1) fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); } @@ -324,6 +561,13 @@ tty_device2iov(struct device *d, struct iovec *iov, int *niov, iov[*niov].iov_len = sz; (*niov)++; +#ifndef NONETGRAPH + if (dev->cs >= 0) { + *auxfd = dev->cs; + (*nauxfd)++; + } +#endif + if (dev->Timer.state != TIMER_STOPPED) { timer_Stop(&dev->Timer); dev->Timer.state = TIMER_RUNNING; @@ -340,10 +584,11 @@ static struct device basettydevice = { tty_Raw, tty_Offline, tty_Cooked, + tty_SetAsyncParams, tty_StopTimer, tty_Free, - NULL, - NULL, + tty_Read, + tty_Write, tty_device2iov, tty_Speed, tty_OpenInfo @@ -363,6 +608,14 @@ tty_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, AbortProgram(EX_OSERR); } +#ifndef NONETGRAPH + if (*nauxfd) { + dev->cs = *auxfd; + (*nauxfd)--; + } else + dev->cs = -1; +#endif + /* Refresh function pointers etc */ memcpy(&dev->dev, &basettydevice, sizeof dev->dev); @@ -408,6 +661,12 @@ tty_Create(struct physical *p) memcpy(&dev->dev, &basettydevice, sizeof dev->dev); memset(&dev->Timer, '\0', sizeof dev->Timer); dev->mbits = -1; +#ifndef NONETGRAPH + dev->real.speed = 0; + dev->real.fd = -1; + dev->real.disc = -1; + *dev->hook = '\0'; +#endif tcgetattr(p->fd, &ios); dev->ios = ios; diff --git a/usr.sbin/ppp/ppp/udp.c b/usr.sbin/ppp/ppp/udp.c index 48b46780715..19477fb016b 100644 --- a/usr.sbin/ppp/ppp/udp.c +++ b/usr.sbin/ppp/ppp/udp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: udp.c,v 1.13 2002/01/23 23:41:32 brian Exp $ + * $OpenBSD: udp.c,v 1.14 2002/03/31 02:38:49 brian Exp $ */ #include <sys/types.h> @@ -162,6 +162,7 @@ static const struct device baseudpdevice = { NULL, NULL, NULL, + NULL, udp_Free, udp_Recvfrom, udp_Sendto, |