diff options
author | brian <brian@cvs.openbsd.org> | 2000-01-07 03:26:57 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 2000-01-07 03:26:57 +0000 |
commit | 27f54ded34080678fc4c377bf2442d27828f491a (patch) | |
tree | dc31374f45c9fdc5d9d75f1a607b25f3a1cd7e0e /usr.sbin | |
parent | b2251b1313131981728d2f775c918c53e83b89fe (diff) |
Upgrade from 2.23 -> 2.26
I'll follow up with a list of changes (too big for a commit message IMHO)
Diffstat (limited to 'usr.sbin')
80 files changed, 4062 insertions, 1578 deletions
diff --git a/usr.sbin/ppp/ppp/Makefile b/usr.sbin/ppp/ppp/Makefile index 7e125d03d58..102f6af9e9f 100644 --- a/usr.sbin/ppp/ppp/Makefile +++ b/usr.sbin/ppp/ppp/Makefile @@ -1,15 +1,15 @@ -# $Id: Makefile,v 1.11 1999/07/15 02:10:31 brian Exp $ +# $Id: Makefile,v 1.12 2000/01/07 03:26:52 brian Exp $ PROG= ppp -SRCS= alias.c alias_cmd.c alias_cuseeme.c alias_db.c alias_ftp.c \ - alias_irc.c alias_nbt.c alias_proxy.c alias_util.c \ - acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chap_ms.c \ - chat.c command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c \ - hdlc.c id.c iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c \ - main.c mbuf.c mp.c pap.c physical.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 throughput.c timer.c tty.c tun.c udp.c vjcomp.c -CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH +SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ + alias_nbt.c alias_proxy.c alias_util.c acf.c arp.c async.c auth.c \ + bundle.c cbcp.c ccp.c chap.c chap_ms.c chat.c command.c datalink.c \ + deflate.c defs.c exec.c filter.c fsm.c hdlc.c id.c iface.c ip.c \ + ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c mbuf.c mp.c nat_cmd.c \ + pap.c physical.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 \ + throughput.c timer.c tty.c tun.c udp.c vjcomp.c +CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH LDADD+= -ldes -lutil -lz DPADD+= ${LIBDES} ${LIBUTIL} ${LIBZ} BINMODE=4554 diff --git a/usr.sbin/ppp/ppp/README.changes b/usr.sbin/ppp/ppp/README.changes index c8e82a3237d..931de39ee6b 100644 --- a/usr.sbin/ppp/ppp/README.changes +++ b/usr.sbin/ppp/ppp/README.changes @@ -83,11 +83,18 @@ o Ppp now accepts M$CHAP (as well as normal CHAP) by default. If this o The ``set device'' command now expects each device to be specified as an argument rather than concatentating all arguments and splitting based on commas and spaces. -o The ``show modem'' command is depricated and has been changed to +o The ``show modem'' command is deprecated and has been changed to ``show physical''. o The words ``host'' and ``port'' are no longer accepted by the ``set filter'' command. Removing them should yield the same results as before. -o The ``set weight'' command has been depricated. The ``set bandwidth'' +o The ``set weight'' command has been deprecated. The ``set bandwidth'' command should now be used instead. o The ``set autoload'' command syntax and implementation have changed as the old implementation was mis-designed and dysfunctional. +o Ppp now waits either the full ``set cd'' time or until carrier is detected + before running the login script (whichever comes first). +o The -alias flag has been deprecated. The -nat flag should be used instead. +o Unbalanced quotes in commands are now warned about and the entire command + is ignored. +o It is now only necessary to escape the `-' character in chat scripts twice. + See the example files for details. diff --git a/usr.sbin/ppp/ppp/acf.c b/usr.sbin/ppp/ppp/acf.c index 4dc1f1c50ab..2cbea45d719 100644 --- a/usr.sbin/ppp/ppp/acf.c +++ b/usr.sbin/ppp/ppp/acf.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: acf.c,v 1.2 1999/06/02 15:58:39 brian Exp $ + * $Id: acf.c,v 1.3 2000/01/07 03:26:52 brian Exp $ */ #include <sys/types.h> @@ -62,8 +62,8 @@ acf_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, const u_char cp[2] = { HDLC_ADDR, HDLC_UI }; if (*proto == PROTO_LCP || l->lcp.his_acfcomp == 0) { - bp = mbuf_Prepend(bp, cp, 2, 0); - mbuf_SetType(bp, MB_ACFOUT); + bp = m_prepend(bp, cp, 2, 0); + m_settype(bp, MB_ACFOUT); } return bp; @@ -88,24 +88,24 @@ acf_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) p->hdlc.lqm.SaveInErrors++; p->hdlc.stats.badaddr++; log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]); - mbuf_Free(bp); + m_freem(bp); return NULL; } if (cp[1] != HDLC_UI) { p->hdlc.lqm.SaveInErrors++; p->hdlc.stats.badcommand++; log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]); - mbuf_Free(bp); + m_freem(bp); return NULL; } - mbuf_SetType(bp, MB_ACFIN); + m_settype(bp, MB_ACFIN); } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) { /* * We can receive compressed packets, but the peer still sends * uncompressed packets (or maybe this is a PROTO_LCP packet) ! */ bp = mbuf_Read(bp, cp, 2); - mbuf_SetType(bp, MB_ACFIN); + m_settype(bp, MB_ACFIN); } } diff --git a/usr.sbin/ppp/ppp/alias.c b/usr.sbin/ppp/ppp/alias.c index 8b18a73af14..60f606c5ce7 100644 --- a/usr.sbin/ppp/ppp/alias.c +++ b/usr.sbin/ppp/ppp/alias.c @@ -78,6 +78,7 @@ See HISTORY file for additional revisions. + $Id: alias.c,v 1.5 2000/01/07 03:26:52 brian Exp $ */ #include <stdio.h> @@ -95,6 +96,8 @@ #ifndef IPPROTO_GRE #define IPPROTO_GRE 47 +#define IPPROTO_ESP 50 +#define IPPROTO_AH 51 #endif #include "alias_local.h" @@ -115,7 +118,7 @@ TcpMonitorIn() -- These routines monitor TCP connections, and TcpMonitorOut() delete a link when a connection is closed. -These routines look for SYN, ACK and RST flags to determine when TCP +These routines look for SYN, FIN and RST flags to determine when TCP connections open and close. When a TCP connection closes, the data structure containing packet aliasing information is deleted after a timeout period. @@ -137,12 +140,13 @@ TcpMonitorIn(struct ip *pip, struct alias_link *link) switch (GetStateIn(link)) { case ALIAS_TCP_STATE_NOT_CONNECTED: - if (tc->th_flags & TH_SYN) + if (tc->th_flags & TH_RST) + SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); + else if (tc->th_flags & TH_SYN) SetStateIn(link, ALIAS_TCP_STATE_CONNECTED); break; case ALIAS_TCP_STATE_CONNECTED: - if (tc->th_flags & TH_FIN - || tc->th_flags & TH_RST) + if (tc->th_flags & (TH_FIN | TH_RST)) SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); break; } @@ -158,12 +162,13 @@ TcpMonitorOut(struct ip *pip, struct alias_link *link) switch (GetStateOut(link)) { case ALIAS_TCP_STATE_NOT_CONNECTED: - if (tc->th_flags & TH_SYN) + if (tc->th_flags & TH_RST) + SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); + else if (tc->th_flags & TH_SYN) SetStateOut(link, ALIAS_TCP_STATE_CONNECTED); break; case ALIAS_TCP_STATE_CONNECTED: - if (tc->th_flags & TH_FIN - || tc->th_flags & TH_RST) + if (tc->th_flags & (TH_FIN | TH_RST)) SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); break; } @@ -1206,6 +1211,8 @@ PacketAliasIn(char *ptr, int maxpacketsize) iresult = TcpAliasIn(pip); break; case IPPROTO_GRE: + case IPPROTO_ESP: + case IPPROTO_AH: iresult = PptpAliasIn(pip); break; } @@ -1312,6 +1319,8 @@ PacketAliasOut(char *ptr, /* valid IP packet */ iresult = TcpAliasOut(pip, maxpacketsize); break; case IPPROTO_GRE: + case IPPROTO_ESP: + case IPPROTO_AH: iresult = PptpAliasOut(pip); break; } diff --git a/usr.sbin/ppp/ppp/alias_cmd.h b/usr.sbin/ppp/ppp/alias_cmd.h deleted file mode 100644 index b43595e6f93..00000000000 --- a/usr.sbin/ppp/ppp/alias_cmd.h +++ /dev/null @@ -1,15 +0,0 @@ -/*- - * The code in this file was written by Eivind Eklund <perhaps@yes.no>, - * who places it in the public domain without restriction. - * - * $Id: alias_cmd.h,v 1.4 1999/05/08 11:06:33 brian Exp $ - */ - -struct cmdargs; - -extern int alias_RedirectPort(struct cmdargs const *); -extern int alias_RedirectAddr(struct cmdargs const *); -extern int alias_ProxyRule(struct cmdargs const *); -extern int alias_Pptp(struct cmdargs const *); - -extern struct layer aliaslayer; diff --git a/usr.sbin/ppp/ppp/alias_db.c b/usr.sbin/ppp/ppp/alias_db.c index d01188e9cd6..b5329d2d477 100644 --- a/usr.sbin/ppp/ppp/alias_db.c +++ b/usr.sbin/ppp/ppp/alias_db.c @@ -104,15 +104,17 @@ implements static network address translation. See HISTORY file for additional revisions. + + $Id: alias_db.c,v 1.5 2000/01/07 03:26:52 brian Exp $ */ /* System include files */ +#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> -#include <sys/errno.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/types.h> @@ -142,7 +144,7 @@ #define ALIAS_CLEANUP_INTERVAL_SECS 60 #define ALIAS_CLEANUP_MAX_SPOKES 30 -/* Timouts (in seconds) for different link types) */ +/* Timeouts (in seconds) for different link types */ #define ICMP_EXPIRE_TIME 60 #define UDP_EXPIRE_TIME 60 #define FRAGMENT_ID_EXPIRE_TIME 10 @@ -365,9 +367,9 @@ static struct in_addr pptpAliasAddr; /* Address of source of PPTP */ Lookup table starting points: StartPointIn() -- link table initial search point for - outgoing packets - StartPointOut() -- port table initial search point for incoming packets + StartPointOut() -- port table initial search point for + outgoing packets Miscellaneous: SeqDiff() -- difference between two TCP sequences @@ -508,7 +510,7 @@ ReLink(struct alias_link *, u_short, u_short, int, int); static struct alias_link * -FindLinkOut(struct in_addr, struct in_addr, u_short, u_short, int); +FindLinkOut(struct in_addr, struct in_addr, u_short, u_short, int, int); static struct alias_link * FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int); @@ -607,7 +609,7 @@ GetNewPort(struct alias_link *link, int alias_port_param) if (go_ahead) { - if ((packetAliasMode && PKT_ALIAS_USE_SOCKETS) + if ((packetAliasMode & PKT_ALIAS_USE_SOCKETS) && (link->flags & LINK_PARTIALLY_SPECIFIED)) { if (GetSocket(port_net, &link->sockfd, link->link_type)) @@ -857,17 +859,6 @@ AddLink(struct in_addr src_addr, link = malloc(sizeof(struct alias_link)); if (link != NULL) { - /* If either the aliasing address or source address are - equal to the default device address (equal to the - global variable aliasAddress), then set the alias - address field of the link record to zero */ - - if (src_addr.s_addr == aliasAddress.s_addr) - src_addr.s_addr = 0; - - if (alias_addr.s_addr == aliasAddress.s_addr) - alias_addr.s_addr = 0; - /* Basic initialization */ link->src_addr = src_addr; link->dst_addr = dst_addr; @@ -1028,18 +1019,16 @@ ReLink(struct alias_link *old_link, } static struct alias_link * -FindLinkOut(struct in_addr src_addr, +_FindLinkOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_port, u_short dst_port, - int link_type) + int link_type, + int replace_partial_links) { u_int i; struct alias_link *link; - if (src_addr.s_addr == aliasAddress.s_addr) - src_addr.s_addr = 0; - i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type); link = linkTableOut[i]; while (link != NULL) @@ -1056,12 +1045,64 @@ FindLinkOut(struct in_addr src_addr, link = link->next_out; } +/* Search for partially specified links. */ + if (link == NULL) + { + if (dst_port != 0) + { + link = _FindLinkOut(src_addr, dst_addr, src_port, 0, + link_type, 0); + if (link != NULL && replace_partial_links) + { + link = ReLink(link, + src_addr, dst_addr, link->alias_addr, + src_port, dst_port, link->alias_port, + link_type); + } + } + else if (dst_addr.s_addr != 0) + { + link = _FindLinkOut(src_addr, nullAddress, src_port, 0, + link_type, 0); + } + } + + return(link); +} + +static struct alias_link * +FindLinkOut(struct in_addr src_addr, + struct in_addr dst_addr, + u_short src_port, + u_short dst_port, + int link_type, + int replace_partial_links) +{ + struct alias_link *link; + + link = _FindLinkOut(src_addr, dst_addr, src_port, dst_port, + link_type, replace_partial_links); + + if (link == NULL) + { + /* The following allows permanent links to be + specified as using the default source address + (i.e. device interface address) without knowing + in advance what that address is. */ + if (aliasAddress.s_addr != 0 && + src_addr.s_addr == aliasAddress.s_addr) + { + link = _FindLinkOut(nullAddress, dst_addr, src_port, dst_port, + link_type, replace_partial_links); + } + } + return(link); } struct alias_link * -FindLinkIn(struct in_addr dst_addr, +_FindLinkIn(struct in_addr dst_addr, struct in_addr alias_addr, u_short dst_port, u_short alias_port, @@ -1091,14 +1132,6 @@ FindLinkIn(struct in_addr dst_addr, if (dst_port == 0) flags_in |= LINK_UNKNOWN_DEST_PORT; -/* The following allows permanent links to be - be specified as using the default aliasing address - (i.e. device interface address) without knowing - in advance what that address is. */ - - if (alias_addr.s_addr == aliasAddress.s_addr) - alias_addr.s_addr = 0; - /* Search loop */ start_point = StartPointIn(alias_addr, alias_port, link_type); link = linkTableIn[start_point]; @@ -1159,6 +1192,7 @@ FindLinkIn(struct in_addr dst_addr, if (link_fully_specified != NULL) { + link_fully_specified->timestamp = timeStamp; return link_fully_specified; } else if (link_unknown_dst_port != NULL) @@ -1194,6 +1228,36 @@ FindLinkIn(struct in_addr dst_addr, } } +struct alias_link * +FindLinkIn(struct in_addr dst_addr, + struct in_addr alias_addr, + u_short dst_port, + u_short alias_port, + int link_type, + int replace_partial_links) +{ + struct alias_link *link; + + link = _FindLinkIn(dst_addr, alias_addr, dst_port, alias_port, + link_type, replace_partial_links); + + if (link == NULL) + { + /* The following allows permanent links to be + specified as using the default aliasing address + (i.e. device interface address) without knowing + in advance what that address is. */ + if (aliasAddress.s_addr != 0 && + alias_addr.s_addr == aliasAddress.s_addr) + { + link = _FindLinkIn(dst_addr, nullAddress, dst_port, alias_port, + link_type, replace_partial_links); + } + } + + return(link); +} + @@ -1231,7 +1295,7 @@ FindIcmpOut(struct in_addr src_addr, link = FindLinkOut(src_addr, dst_addr, id, NO_DEST_PORT, - LINK_ICMP); + LINK_ICMP, 0); if (link == NULL) { struct in_addr alias_addr; @@ -1365,7 +1429,7 @@ FindUdpTcpOut(struct in_addr src_addr, break; } - link = FindLinkOut(src_addr, dst_addr, src_port, dst_port, link_type); + link = FindLinkOut(src_addr, dst_addr, src_port, dst_port, link_type, 1); if (link == NULL) { @@ -1412,7 +1476,7 @@ FindAliasAddress(struct in_addr original_addr) struct alias_link *link; link = FindLinkOut(original_addr, nullAddress, - 0, 0, LINK_ADDR); + 0, 0, LINK_ADDR, 0); if (link == NULL) { return aliasAddress; diff --git a/usr.sbin/ppp/ppp/alias_ftp.c b/usr.sbin/ppp/ppp/alias_ftp.c index 73769fdc624..13efc42a156 100644 --- a/usr.sbin/ppp/ppp/alias_ftp.c +++ b/usr.sbin/ppp/ppp/alias_ftp.c @@ -34,6 +34,8 @@ withing the packet alising module. See HISTORY file for record of revisions. + + $Id: alias_ftp.c,v 1.3 2000/01/07 03:26:52 brian Exp $ */ /* Includes */ diff --git a/usr.sbin/ppp/ppp/alias_irc.c b/usr.sbin/ppp/ppp/alias_irc.c index 910e9343404..e3443acec76 100644 --- a/usr.sbin/ppp/ppp/alias_irc.c +++ b/usr.sbin/ppp/ppp/alias_irc.c @@ -19,6 +19,8 @@ Very minor changes to conform with local/global/function naming conventions withing the packet alising module. + + $Id: alias_irc.c,v 1.2 2000/01/07 03:26:52 brian Exp $ */ /* Includes */ diff --git a/usr.sbin/ppp/ppp/alias_local.h b/usr.sbin/ppp/ppp/alias_local.h index 23b04a83285..d2f558fe4d3 100644 --- a/usr.sbin/ppp/ppp/alias_local.h +++ b/usr.sbin/ppp/ppp/alias_local.h @@ -12,7 +12,9 @@ Initial version: August, 1996 (cjm) - <updated several times by original author and Eivind Eiklund> + <updated several times by original author and Eivind Eklund> + + $Id: alias_local.h,v 1.4 2000/01/07 03:26:52 brian Exp $ */ #ifndef ALIAS_LOCAL_H #define ALIAS_LOCAL_H diff --git a/usr.sbin/ppp/ppp/alias_proxy.c b/usr.sbin/ppp/ppp/alias_proxy.c index 60437bfafd2..f4ceadbc20b 100644 --- a/usr.sbin/ppp/ppp/alias_proxy.c +++ b/usr.sbin/ppp/ppp/alias_proxy.c @@ -21,6 +21,8 @@ Initial development: April, 1998 (cjm) + + $Id: alias_proxy.c,v 1.4 2000/01/07 03:26:52 brian Exp $ */ diff --git a/usr.sbin/ppp/ppp/alias_util.c b/usr.sbin/ppp/ppp/alias_util.c index fe076531201..9321ac71001 100644 --- a/usr.sbin/ppp/ppp/alias_util.c +++ b/usr.sbin/ppp/ppp/alias_util.c @@ -11,6 +11,8 @@ Version 1.7: January 9, 1997 Added differential checksum update function. + + $Id: alias_util.c,v 1.2 2000/01/07 03:26:52 brian Exp $ */ /* @@ -43,7 +45,8 @@ PacketAliasInternetChecksum(u_short *ptr, int nbytes) if (nbytes == 1) { oddbyte = 0; - *((u_char *) &oddbyte) = *(u_char *) ptr; + ((u_char *) &oddbyte)[0] = *(u_char *) ptr; + ((u_char *) &oddbyte)[1] = 0; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); @@ -84,7 +87,8 @@ TcpChecksum(struct ip *pip) if (nbytes == 1) { oddbyte = 0; - *((u_char *) &oddbyte) = *(u_char *) ptr; + ((u_char *) &oddbyte)[0] = *(u_char *) ptr; + ((u_char *) &oddbyte)[1] = 0; sum += oddbyte; } diff --git a/usr.sbin/ppp/ppp/async.c b/usr.sbin/ppp/ppp/async.c index 2e12c5b64a0..00f1482dc0c 100644 --- a/usr.sbin/ppp/ppp/async.c +++ b/usr.sbin/ppp/ppp/async.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: async.c,v 1.6 1999/06/02 15:58:40 brian Exp $ + * $Id: async.c,v 1.7 2000/01/07 03:26:52 brian Exp $ * */ #include <sys/types.h> @@ -92,8 +92,8 @@ async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, struct mbuf *wp; int cnt; - if (!p || mbuf_Length(bp) > HDLCSIZE) { - mbuf_Free(bp); + if (!p || m_length(bp) > HDLCSIZE) { + m_freem(bp); return NULL; } @@ -103,20 +103,20 @@ async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, *cp++ = HDLC_SYN; while (wp) { sp = MBUF_CTOP(wp); - for (cnt = wp->cnt; cnt > 0; cnt--) { + for (cnt = wp->m_len; cnt > 0; cnt--) { async_Encode(&p->async, &cp, *sp++, *proto); if (cp >= ep) { - mbuf_Free(bp); + m_freem(bp); return NULL; } } - wp = wp->next; + wp = wp->m_next; } *cp++ = HDLC_SYN; cnt = cp - p->async.xbuff; - mbuf_Free(bp); - bp = mbuf_Alloc(cnt, MB_ASYNCOUT); + m_freem(bp); + bp = m_get(cnt, MB_ASYNCOUT); memcpy(MBUF_CTOP(bp), p->async.xbuff, cnt); log_DumpBp(LogASYNC, "Write", bp); @@ -135,7 +135,7 @@ async_Decode(struct async *async, u_char c) case HDLC_SYN: async->mode &= ~MODE_HUNT; if (async->length) { /* packet is ready. */ - bp = mbuf_Alloc(async->length, MB_ASYNCIN); + bp = m_get(async->length, MB_ASYNCIN); mbuf_Write(bp, async->hbuff, async->length); async->length = 0; return bp; @@ -185,12 +185,12 @@ async_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, log_DumpBp(LogASYNC, "Read", bp); while (bp) { ch = MBUF_CTOP(bp); - for (cnt = bp->cnt; cnt; cnt--) { + for (cnt = bp->m_len; cnt; cnt--) { *last = async_Decode(&p->async, *ch++); if (*last != NULL) - last = &(*last)->pnext; + last = &(*last)->m_nextpkt; } - bp = mbuf_FreeSeg(bp); + bp = m_free(bp); } return nbp; diff --git a/usr.sbin/ppp/ppp/auth.c b/usr.sbin/ppp/ppp/auth.c index ff08d8f8864..ef426403501 100644 --- a/usr.sbin/ppp/ppp/auth.c +++ b/usr.sbin/ppp/ppp/auth.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: auth.c,v 1.12 1999/06/08 20:12:23 brian Exp $ + * $Id: auth.c,v 1.13 2000/01/07 03:26:52 brian Exp $ * * TODO: * o Implement check against with registered IP addresses. @@ -104,18 +104,21 @@ int auth_SetPhoneList(const char *name, char *phone, int phonelen) { FILE *fp; - int n; + int n, lineno; char *vector[6]; char buff[LINE_LEN]; fp = OpenSecret(SECRETFILE); + lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { + lineno++; if (buff[0] == '#') continue; buff[strlen(buff) - 1] = '\0'; memset(vector, '\0', sizeof vector); - n = MakeArgs(buff, vector, VECSIZE(vector)); + if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) + log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 5) continue; if (strcmp(vector[0], name) == 0) { @@ -137,7 +140,7 @@ int auth_Select(struct bundle *bundle, const char *name) { FILE *fp; - int n; + int n, lineno; char *vector[5]; char buff[LINE_LEN]; @@ -157,13 +160,16 @@ auth_Select(struct bundle *bundle, const char *name) #endif fp = OpenSecret(SECRETFILE); + lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { + lineno++; if (buff[0] == '#') continue; buff[strlen(buff) - 1] = '\0'; memset(vector, '\0', sizeof vector); - n = MakeArgs(buff, vector, VECSIZE(vector)); + if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) + log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strcmp(vector[0], name) == 0) { @@ -208,18 +214,21 @@ auth_Validate(struct bundle *bundle, const char *name, /* Used by PAP routines */ FILE *fp; - int n; + int n, lineno; char *vector[5]; char buff[LINE_LEN]; fp = OpenSecret(SECRETFILE); + lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { + lineno++; if (buff[0] == '#') continue; buff[strlen(buff) - 1] = 0; memset(vector, '\0', sizeof vector); - n = MakeArgs(buff, vector, VECSIZE(vector)); + if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) + log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strcmp(vector[0], name) == 0) { @@ -245,7 +254,7 @@ auth_GetSecret(struct bundle *bundle, const char *name, int len, /* Used by CHAP routines */ FILE *fp; - int n; + int n, lineno; char *vector[5]; static char buff[LINE_LEN]; /* vector[] will point here when returned */ @@ -253,14 +262,17 @@ auth_GetSecret(struct bundle *bundle, const char *name, int len, if (fp == NULL) return (NULL); + lineno = 0; while (fgets(buff, sizeof buff, fp)) { + lineno++; if (buff[0] == '#') continue; n = strlen(buff) - 1; if (buff[n] == '\n') buff[n] = '\0'; /* Trim the '\n' */ memset(vector, '\0', sizeof vector); - n = MakeArgs(buff, vector, VECSIZE(vector)); + if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) + log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) { @@ -327,7 +339,7 @@ auth_ReadHeader(struct authinfo *authp, struct mbuf *bp) { int len; - len = mbuf_Length(bp); + len = m_length(bp); if (len >= sizeof authp->in.hdr) { bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr); if (len >= ntohs(authp->in.hdr.length)) @@ -341,7 +353,7 @@ auth_ReadHeader(struct authinfo *authp, struct mbuf *bp) (int)(sizeof authp->in.hdr), len); } - mbuf_Free(bp); + m_freem(bp); return NULL; } @@ -351,7 +363,7 @@ auth_ReadName(struct authinfo *authp, struct mbuf *bp, int len) if (len > sizeof authp->in.name - 1) log_Printf(LogWARN, "auth_ReadName: Name too long (%d) !\n", len); else { - int mlen = mbuf_Length(bp); + int mlen = m_length(bp); if (len > mlen) log_Printf(LogWARN, "auth_ReadName: Short packet (%d > %d) !\n", @@ -364,6 +376,6 @@ auth_ReadName(struct authinfo *authp, struct mbuf *bp, int len) } *authp->in.name = '\0'; - mbuf_Free(bp); + m_freem(bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index 7a75073b741..920fab01a42 100644 --- a/usr.sbin/ppp/ppp/bundle.c +++ b/usr.sbin/ppp/ppp/bundle.c @@ -23,14 +23,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.c,v 1.26 1999/08/17 17:25:34 brian Exp $ + * $Id: bundle.c,v 1.27 2000/01/07 03:26:53 brian Exp $ */ #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/if.h> -#include <net/if_tun.h> +#include <net/if_tun.h> /* For TUNSIFMODE & TUNSLMODE */ #include <arpa/inet.h> #include <net/route.h> #include <netinet/in_systm.h> @@ -39,13 +39,21 @@ #include <errno.h> #include <fcntl.h> +#ifdef __OpenBSD__ +#include <util.h> +#else +#include <libutil.h> +#endif #include <paths.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/ioctl.h> #include <sys/uio.h> #include <sys/wait.h> +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include <sys/linker.h> +#include <sys/module.h> +#endif #include <termios.h> #include <unistd.h> @@ -87,14 +95,15 @@ #include "ip.h" #include "iface.h" -#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical, - throughput, device */ -#define SOCKET_OVERHEAD 100 /* additional buffer space for large */ - /* {recv,send}msg() calls */ +#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical, + throughput, device */ + +#define SEND_MAXFD 3 /* Max file descriptors passed through + the local domain socket */ static int bundle_RemainingIdleTime(struct bundle *); -static const char *PhaseNames[] = { +static const char * const PhaseNames[] = { "Dead", "Establish", "Authenticate", "Network", "Terminate" }; @@ -310,7 +319,7 @@ bundle_LayerFinish(void *v, struct fsm *fp) if (bundle_Phase(bundle) != PHASE_DEAD) bundle_NewPhase(bundle, PHASE_TERMINATE); for (dl = bundle->links; dl; dl = dl->next) - datalink_Close(dl, CLOSE_NORMAL); + datalink_Close(dl, CLOSE_STAYDOWN); fsm2initial(fp); } else if (fp->proto == PROTO_LCP) { int others_active; @@ -393,12 +402,36 @@ bundle_Down(struct bundle *bundle, int how) datalink_Down(dl, how); } +static size_t +bundle_FillQueues(struct bundle *bundle) +{ + size_t total; + + if (bundle->ncp.mp.active) + total = mp_FillQueues(bundle); + else { + struct datalink *dl; + size_t add; + + for (total = 0, dl = bundle->links; dl; dl = dl->next) + if (dl->state == DATALINK_OPEN) { + add = link_QueueLen(&dl->physical->link); + if (add == 0 && dl->physical->out == NULL) + add = ip_PushPacket(&dl->physical->link, bundle); + total += add; + } + } + + return total + ip_QueueLen(&bundle->ncp.ipcp); +} + static int bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct bundle *bundle = descriptor2bundle(d); struct datalink *dl; - int result, queued, nlinks; + int result, nlinks; + size_t queued; result = 0; @@ -412,7 +445,7 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) if (r && (bundle->phase == PHASE_NETWORK || bundle->phys_type.all & PHYS_AUTO)) { /* enough surplus so that we can tell if we're getting swamped */ - if (queued < 20) { + if (queued < 30) { /* Not enough - select() for more */ if (bundle->choked.timer.state == TIMER_RUNNING) timer_Stop(&bundle->choked.timer); /* Not needed any more */ @@ -597,11 +630,14 @@ bundle_UnlockTun(struct bundle *bundle) } struct bundle * -bundle_Create(const char *prefix, int type, const char **argv) +bundle_Create(const char *prefix, int type, int unit) { static struct bundle bundle; /* there can be only one */ - int enoentcount, err; + int enoentcount, err, minunit, maxunit; const char *ifname; +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) + int kldtried; +#endif #if defined(TUNSIFMODE) || defined(TUNSLMODE) int iff; #endif @@ -611,15 +647,40 @@ bundle_Create(const char *prefix, int type, const char **argv) return NULL; } + if (unit == -1) { + minunit = 0; + maxunit = -1; + } else { + minunit = unit; + maxunit = unit + 1; + } err = ENOENT; enoentcount = 0; - for (bundle.unit = 0; ; bundle.unit++) { +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) + kldtried = 0; +#endif + for (bundle.unit = minunit; bundle.unit != maxunit; bundle.unit++) { snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d", prefix, bundle.unit); bundle.dev.fd = ID0open(bundle.dev.Name, O_RDWR); if (bundle.dev.fd >= 0) break; else if (errno == ENXIO) { +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) + if (bundle.unit == minunit && !kldtried++) { + /* + * 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)); + } + } +#endif err = errno; break; } else if (errno == ENOENT) { @@ -630,15 +691,15 @@ bundle_Create(const char *prefix, int type, const char **argv) } if (bundle.dev.fd < 0) { - log_Printf(LogWARN, "No available tunnel devices found (%s).\n", - strerror(err)); + if (unit == -1) + log_Printf(LogWARN, "No available tunnel devices found (%s)\n", + strerror(err)); + else + log_Printf(LogWARN, "%s%d: %s\n", prefix, unit, strerror(err)); return NULL; } log_SetTun(bundle.unit); - bundle.argv = argv; - bundle.argv0 = argv[0]; - bundle.argv1 = argv[1]; ifname = strrchr(bundle.dev.Name, '/'); if (ifname == NULL) @@ -681,7 +742,7 @@ bundle_Create(const char *prefix, int type, const char **argv) bundle.routing_seq = 0; bundle.phase = PHASE_DEAD; bundle.CleaningUp = 0; - bundle.AliasEnabled = 0; + bundle.NatEnabled = 0; bundle.fsm.LayerStart = bundle_LayerStart; bundle.fsm.LayerUp = bundle_LayerUp; @@ -790,6 +851,8 @@ bundle_Destroy(struct bundle *bundle) while (dl) dl = datalink_Destroy(dl); + ipcp_Destroy(&bundle->ncp.ipcp); + close(bundle->dev.fd); bundle_UnlockTun(bundle); @@ -885,7 +948,8 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, log_Printf(LogTCPIP, "bundle_SetRoute failure:\n"); log_Printf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmdstr); log_Printf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst)); - log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n", inet_ntoa(gateway)); + log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n", + inet_ntoa(gateway)); log_Printf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask)); failed: if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST || @@ -926,7 +990,7 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl) /* * Our datalink has closed. * CleanDatalinks() (called from DoLoop()) will remove closed - * BACKGROUND and DIRECT links. + * BACKGROUND, FOREGROUND and DIRECT links. * If it's the last data link, enter phase DEAD. * * NOTE: dl may not be in our list (bundle_SendDatalink()) ! @@ -993,29 +1057,6 @@ bundle2datalink(struct bundle *bundle, const char *name) } int -bundle_FillQueues(struct bundle *bundle) -{ - int total; - - if (bundle->ncp.mp.active) - total = mp_FillQueues(bundle); - else { - struct datalink *dl; - int add; - - for (total = 0, dl = bundle->links; dl; dl = dl->next) - if (dl->state == DATALINK_OPEN) { - add = link_QueueLen(&dl->physical->link); - if (add == 0 && dl->physical->out == NULL) - add = ip_PushPacket(&dl->physical->link, bundle); - total += add; - } - } - - return total + ip_QueueLen(&bundle->ncp.ipcp); -} - -int bundle_ShowLinks(struct cmdargs const *arg) { struct datalink *dl; @@ -1058,7 +1099,6 @@ bundle_ShowStatus(struct cmdargs const *arg) int remaining; prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle)); - prompt_Printf(arg->prompt, " Title: %s\n", arg->bundle->argv[0]); prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name); prompt_Printf(arg->prompt, " Interface: %s @ %lubps", arg->bundle->iface->name, arg->bundle->bandwidth); @@ -1243,7 +1283,8 @@ bundle_CleanDatalinks(struct bundle *bundle) while (*dlp) if ((*dlp)->state == DATALINK_CLOSED && - (*dlp)->physical->type & (PHYS_DIRECT|PHYS_BACKGROUND)) { + (*dlp)->physical->type & + (PHYS_DIRECT|PHYS_BACKGROUND|PHYS_FOREGROUND)) { *dlp = datalink_Destroy(*dlp); found++; } else @@ -1289,93 +1330,182 @@ bundle_GetLabel(struct bundle *bundle) return *bundle->cfg.label ? bundle->cfg.label : NULL; } +int +bundle_LinkSize() +{ + struct iovec iov[SCATTER_SEGMENTS]; + int niov, expect, f; + + iov[0].iov_len = strlen(Version) + 1; + iov[0].iov_base = NULL; + niov = 1; + if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) { + log_Printf(LogERROR, "Cannot determine space required for link\n"); + return 0; + } + + for (f = expect = 0; f < niov; f++) + expect += iov[f].iov_len; + + return expect; +} + void -bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) +bundle_ReceiveDatalink(struct bundle *bundle, int s) { - char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)]; - struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf; - struct msghdr msg; + char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD]; + int niov, expect, f, *fd, nfd, onfd, got; struct iovec iov[SCATTER_SEGMENTS]; + struct cmsghdr *cmsg; + struct msghdr msg; struct datalink *dl; - int niov, link_fd, expect, f; pid_t pid; log_Printf(LogPHASE, "Receiving datalink\n"); - /* Create our scatter/gather array */ - niov = 1; + /* + * Create our scatter/gather array - passing NULL gets the space + * allocation requirement rather than actually flattening the + * structures. + */ iov[0].iov_len = strlen(Version) + 1; - iov[0].iov_base = (char *)malloc(iov[0].iov_len); - if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov, 0) == -1) { - close(s); + iov[0].iov_base = NULL; + niov = 1; + if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) { + log_Printf(LogERROR, "Cannot determine space required for link\n"); return; } - pid = getpid(); - write(s, &pid, sizeof pid); - - for (f = expect = 0; f < niov; f++) - expect += iov[f].iov_len; + /* Allocate the scatter/gather array for recvmsg() */ + for (f = expect = 0; f < niov; f++) { + if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) { + log_Printf(LogERROR, "Cannot allocate space to receive link\n"); + return; + } + if (f) + expect += iov[f].iov_len; + } /* Set up our message */ + cmsg = (struct cmsghdr *)cmsgbuf; cmsg->cmsg_len = sizeof cmsgbuf; cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = 0; memset(&msg, '\0', sizeof msg); - msg.msg_name = (caddr_t)sun; - msg.msg_namelen = sizeof *sun; + msg.msg_name = NULL; + msg.msg_namelen = 0; msg.msg_iov = iov; - msg.msg_iovlen = niov; + msg.msg_iovlen = 1; /* Only send the version at the first pass */ msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof cmsgbuf; - log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect); - f = expect + 100; - setsockopt(s, SOL_SOCKET, SO_RCVBUF, &f, sizeof f); - if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) { - if (f == -1) + log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", iov[0].iov_len); + + if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) { + if (got == -1) log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno)); else - log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect); + log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", + got, iov[0].iov_len); while (niov--) free(iov[niov].iov_base); - close(s); return; } - write(s, "!", 1); /* ACK */ - close(s); - - if (cmsg->cmsg_type != SCM_RIGHTS) { - log_Printf(LogERROR, "Recvmsg: no descriptor received !\n"); + if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { + log_Printf(LogERROR, "Recvmsg: no descriptors received !\n"); while (niov--) free(iov[niov].iov_base); return; } - /* We've successfully received an open file descriptor through our socket */ - log_Printf(LogDEBUG, "Receiving device descriptor\n"); - link_fd = *(int *)CMSG_DATA(cmsg); + fd = (int *)(cmsg + 1); + nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int); + + if (nfd < 2) { + log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n", + nfd, nfd == 1 ? "" : "s"); + while (nfd--) + close(fd[nfd]); + while (niov--) + free(iov[niov].iov_base); + return; + } + /* + * We've successfully received two or more open file descriptors + * through our socket, plus a version string. Make sure it's the + * correct version, and drop the connection if it's not. + */ if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) { log_Printf(LogWARN, "Cannot receive datalink, incorrect version" " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len, (char *)iov[0].iov_base, Version); - close(link_fd); + while (nfd--) + close(fd[nfd]); while (niov--) free(iov[niov].iov_base); return; } - niov = 1; - dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, link_fd); + /* + * Everything looks good. Send the other side our process id so that + * they can transfer lock ownership, and wait for them to send the + * actual link data. + */ + pid = getpid(); + if ((got = write(fd[1], &pid, sizeof pid)) != sizeof pid) { + if (got == -1) + log_Printf(LogERROR, "Failed write: %s\n", strerror(errno)); + else + log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, + (int)(sizeof pid)); + while (nfd--) + close(fd[nfd]); + while (niov--) + free(iov[niov].iov_base); + return; + } + + if ((got = readv(fd[1], iov + 1, niov - 1)) != expect) { + if (got == -1) + log_Printf(LogERROR, "Failed write: %s\n", strerror(errno)); + else + log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, expect); + while (nfd--) + close(fd[nfd]); + while (niov--) + free(iov[niov].iov_base); + return; + } + close(fd[1]); + + onfd = nfd; /* We've got this many in our array */ + nfd -= 2; /* Don't include p->fd and our reply descriptor */ + niov = 1; /* Skip the version id */ + dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0], + fd + 2, &nfd); if (dl) { - bundle_DatalinkLinkin(bundle, dl); - datalink_AuthOk(dl); - bundle_CalculateBandwidth(dl->bundle); - } else - close(link_fd); + + if (nfd) { + log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d " + "auxiliary file descriptors (%d remain)\n", onfd, nfd); + datalink_Destroy(dl); + while (nfd--) + close(fd[onfd--]); + close(fd[0]); + } else { + bundle_DatalinkLinkin(bundle, dl); + datalink_AuthOk(dl); + bundle_CalculateBandwidth(dl->bundle); + } + } else { + while (nfd--) + close(fd[onfd--]); + close(fd[0]); + close(fd[1]); + } free(iov[0].iov_base); } @@ -1383,15 +1513,25 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) void bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) { - char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int)], ack; - struct cmsghdr *cmsg = (struct cmsghdr *)cmsgbuf; + char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD]; + const char *constlock; + char *lock; + struct cmsghdr *cmsg; struct msghdr msg; struct iovec iov[SCATTER_SEGMENTS]; - int niov, link_fd, f, expect, newsid; + int niov, f, expect, newsid, fd[SEND_MAXFD], nfd, reply[2], got; pid_t newpid; log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name); + /* Record the base device name for a lock transfer later */ + constlock = physical_LockedDevice(dl->physical); + if (constlock) { + lock = alloca(strlen(constlock) + 1); + strcpy(lock, constlock); + } else + lock = NULL; + bundle_LinkClosed(dl->bundle, dl); bundle_DatalinkLinkout(dl->bundle, dl); @@ -1399,42 +1539,96 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) iov[0].iov_len = strlen(Version) + 1; iov[0].iov_base = strdup(Version); niov = 1; + nfd = 0; - read(s, &newpid, sizeof newpid); - link_fd = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov, newpid); + fd[0] = datalink2iov(dl, iov, &niov, SCATTER_SEGMENTS, fd + 2, &nfd); - if (link_fd != -1) { + if (fd[0] != -1 && socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, reply) != -1) { + /* + * fd[1] is used to get the peer process id back, then to confirm that + * we've transferred any device locks to that process id. + */ + fd[1] = reply[1]; + + nfd += 2; /* Include fd[0] and fd[1] */ memset(&msg, '\0', sizeof msg); - msg.msg_name = (caddr_t)sun; - msg.msg_namelen = sizeof *sun; + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* + * Only send the version to start... We used to send the whole lot, but + * this caused problems with our RECVBUF size as a single link is about + * 22k ! This way, we should bump into no limits. + */ + msg.msg_iovlen = 1; msg.msg_iov = iov; - msg.msg_iovlen = niov; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd; + msg.msg_flags = 0; - cmsg->cmsg_len = sizeof cmsgbuf; + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_len = msg.msg_controllen; cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; - *(int *)CMSG_DATA(cmsg) = link_fd; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof cmsgbuf; - for (f = expect = 0; f < niov; f++) + for (f = 0; f < nfd; f++) + *((int *)(cmsg + 1) + f) = fd[f]; + + for (f = 1, expect = 0; f < niov; f++) expect += iov[f].iov_len; - log_Printf(LogDEBUG, "Sending %d bytes in scatter/gather array\n", expect); + if (setsockopt(reply[0], SOL_SOCKET, SO_SNDBUF, &expect, sizeof(int)) == -1) + log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect, + strerror(errno)); + if (setsockopt(reply[1], SOL_SOCKET, SO_RCVBUF, &expect, sizeof(int)) == -1) + log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect, + strerror(errno)); + + log_Printf(LogDEBUG, "Sending %d descriptor%s and %d bytes in scatter" + "/gather array\n", nfd, nfd == 1 ? "" : "s", iov[0].iov_len); + + if ((got = sendmsg(s, &msg, 0)) == -1) + log_Printf(LogERROR, "Failed sendmsg: %s: %s\n", + sun->sun_path, strerror(errno)); + else if (got != iov[0].iov_len) + log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %d\n", + sun->sun_path, got, iov[0].iov_len); + else { + /* We must get the ACK before closing the descriptor ! */ + int res; + + if ((got = read(reply[0], &newpid, sizeof newpid)) == sizeof newpid) { + log_Printf(LogDEBUG, "Received confirmation from pid %d\n", + (int)newpid); + if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK) + log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res)); + + log_Printf(LogDEBUG, "Transmitting link (%d bytes)\n", expect); + if ((got = writev(reply[0], iov + 1, niov - 1)) != expect) { + if (got == -1) + log_Printf(LogERROR, "%s: Failed writev: %s\n", + sun->sun_path, strerror(errno)); + else + log_Printf(LogERROR, "%s: Failed writev: Wrote %d of %d\n", + sun->sun_path, got, expect); + } + } else if (got == -1) + log_Printf(LogERROR, "%s: Failed socketpair read: %s\n", + sun->sun_path, strerror(errno)); + else + log_Printf(LogERROR, "%s: Failed socketpair read: Got %d of %d\n", + sun->sun_path, got, (int)(sizeof newpid)); + } - f = expect + SOCKET_OVERHEAD; - setsockopt(s, SOL_SOCKET, SO_SNDBUF, &f, sizeof f); - if (sendmsg(s, &msg, 0) == -1) - log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno)); - /* We must get the ACK before closing the descriptor ! */ - read(s, &ack, 1); + close(reply[0]); + close(reply[1]); newsid = Enabled(dl->bundle, OPT_KEEPSESSION) || - tcgetpgrp(link_fd) == getpgrp(); - close(link_fd); + tcgetpgrp(fd[0]) == getpgrp(); + while (nfd) + close(fd[--nfd]); if (newsid) - bundle_setsid(dl->bundle, 1); + bundle_setsid(dl->bundle, got != -1); } close(s); @@ -1503,6 +1697,16 @@ bundle_setsid(struct bundle *bundle, int holdsession) char done; struct datalink *dl; + if (!holdsession && bundle_IsDead(bundle)) { + /* + * No need to lose our session after all... we're going away anyway + * + * We should really stop the timer and pause if holdsession is set and + * the bundle's dead, but that leaves other resources lying about :-( + */ + return; + } + orig = getpid(); if (pipe(fds) == -1) { log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); @@ -1547,7 +1751,7 @@ bundle_setsid(struct bundle *bundle, int holdsession) physical_ChangedPid(dl->physical, pid); write(fds[1], "!", 1); /* done */ close(fds[1]); - exit(0); + _exit(0); break; } break; @@ -1571,15 +1775,14 @@ bundle_setsid(struct bundle *bundle, int holdsession) signal(SIGQUIT, SIG_DFL); for (fd = getdtablesize(); fd >= 0; fd--) close(fd); - setuid(geteuid()); /* * Reap the intermediate process. As we're not exiting but the * intermediate is, we don't want it to become defunct. */ waitpid(pid, &status, 0); /* Tweak our process arguments.... */ - bundle->argv[0] = "session owner"; - bundle->argv[1] = NULL; + ID0setproctitle("session owner"); + setuid(ID0realuid()); /* * Hang around for a HUP. This should happen as soon as the * ppp that we passed our ctty descriptor to closes it. @@ -1590,7 +1793,7 @@ bundle_setsid(struct bundle *bundle, int holdsession) */ pause(); } - exit(0); + _exit(0); break; } } @@ -1709,7 +1912,7 @@ bundle_AutoAdjust(struct bundle *bundle, int percent, int what) } else if (otherlinkup) { /* Only bring the second-last link down */ log_Printf(LogPHASE, "%d%% saturation -> Closing link ``%s''\n", percent, choice->name); - datalink_Down(choice, CLOSE_NORMAL); + datalink_Close(choice, CLOSE_STAYDOWN); mp_StopAutoloadTimer(&bundle->ncp.mp); } } diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index 0b148a6759b..9c45dac23eb 100644 --- a/usr.sbin/ppp/ppp/bundle.h +++ b/usr.sbin/ppp/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.h,v 1.8 1999/08/17 17:25:34 brian Exp $ + * $Id: bundle.h,v 1.9 2000/01/07 03:26:53 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -63,9 +63,6 @@ struct iface; struct bundle { struct descriptor desc; /* really all our datalinks */ int unit; /* The device/interface unit number */ - const char **argv; /* From main() */ - const char *argv0; /* Original */ - const char *argv1; /* Original */ struct { char Name[20]; /* The /dev/XXXX name */ @@ -84,7 +81,7 @@ struct bundle { } phys_type; unsigned CleaningUp : 1; /* Going to exit.... */ - unsigned AliasEnabled : 1; /* Are we using libalias ? */ + unsigned NatEnabled : 1; /* Are we using libalias ? */ struct fsm_parent fsm; /* Our callback functions */ struct datalink *links; /* Our data links */ @@ -142,7 +139,7 @@ struct bundle { #define descriptor2bundle(d) \ ((d)->type == BUNDLE_DESCRIPTOR ? (struct bundle *)(d) : NULL) -extern struct bundle *bundle_Create(const char *, int, const char **); +extern struct bundle *bundle_Create(const char *, int, int); extern void bundle_Destroy(struct bundle *); extern const char *bundle_PhaseName(struct bundle *); #define bundle_Phase(b) ((b)->phase) @@ -156,7 +153,6 @@ extern void bundle_Down(struct bundle *, int); extern void bundle_Open(struct bundle *, const char *, int, int); extern void bundle_LinkClosed(struct bundle *, struct datalink *); -extern int bundle_FillQueues(struct bundle *); extern int bundle_ShowLinks(struct cmdargs const *); extern int bundle_ShowStatus(struct cmdargs const *); extern void bundle_StartIdleTimer(struct bundle *); @@ -177,7 +173,8 @@ extern void bundle_CleanDatalinks(struct bundle *); extern void bundle_SetLabel(struct bundle *, const char *); extern const char *bundle_GetLabel(struct bundle *); extern void bundle_SendDatalink(struct datalink *, int, struct sockaddr_un *); -extern void bundle_ReceiveDatalink(struct bundle *, int, struct sockaddr_un *); +extern int bundle_LinkSize(void); +extern void bundle_ReceiveDatalink(struct bundle *, int); extern int bundle_SetMode(struct bundle *, struct datalink *, int); extern int bundle_RenameDatalink(struct bundle *, struct datalink *, const char *); diff --git a/usr.sbin/ppp/ppp/cbcp.c b/usr.sbin/ppp/ppp/cbcp.c index 21f7e9328f3..c3d7c06f281 100644 --- a/usr.sbin/ppp/ppp/cbcp.c +++ b/usr.sbin/ppp/ppp/cbcp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cbcp.c,v 1.10 1999/07/27 13:50:20 brian Exp $ + * $Id: cbcp.c,v 1.11 2000/01/07 03:26:53 brian Exp $ */ #include <sys/param.h> @@ -142,7 +142,7 @@ cbcp_StartTimer(struct cbcp *cbcp, int timeout) #define CBCP_RESPSENT (3) /* Waiting for an ACK */ #define CBCP_ACKSENT (4) /* Waiting for an LCP Term REQ */ -static const char *cbcpname[] = { +static const char * const cbcpname[] = { "closed", "stopped", "req-sent", "resp-sent", "ack-sent" }; @@ -195,7 +195,7 @@ cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data) struct cbcp_header *head; struct mbuf *bp; - bp = mbuf_Alloc(sizeof *head + data->length, MB_CBCPOUT); + bp = m_get(sizeof *head + data->length, MB_CBCPOUT); head = (struct cbcp_header *)MBUF_CTOP(bp); head->code = code; head->id = cbcp->fsm.id; @@ -203,13 +203,13 @@ cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data) memcpy(MBUF_CTOP(bp) + sizeof *head, data, data->length); log_DumpBp(LogDEBUG, "cbcp_Output", bp); link_PushPacket(&cbcp->p->link, bp, cbcp->p->dl->bundle, - PRI_LINK, PROTO_CBCP); + LINK_QUEUES(&cbcp->p->link) - 1, PROTO_CBCP); } static const char * cbcp_data_Type(int type) { - static const char *types[] = { + static const char * const types[] = { "No callback", "User-spec", "Server-spec", "list" }; @@ -622,29 +622,29 @@ cbcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p == NULL) { log_Printf(LogERROR, "cbcp_Input: Not a physical link - dropped\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } - bp = mbuf_Contiguous(bp); - len = mbuf_Length(bp); + bp = m_pullup(bp); + len = m_length(bp); if (len < sizeof(struct cbcp_header)) { - mbuf_Free(bp); + m_freem(bp); return NULL; } head = (struct cbcp_header *)MBUF_CTOP(bp); if (ntohs(head->length) != len) { log_Printf(LogWARN, "Corrupt CBCP packet (code %d, length %d not %d)" " - ignored\n", head->code, ntohs(head->length), len); - mbuf_Free(bp); + m_freem(bp); return NULL; } - mbuf_SetType(bp, MB_CBCPIN); + m_settype(bp, MB_CBCPIN); /* XXX check the id */ - bp->offset += sizeof(struct cbcp_header); - bp->cnt -= sizeof(struct cbcp_header); + bp->m_offset += sizeof(struct cbcp_header); + bp->m_len -= sizeof(struct cbcp_header); data = (struct cbcp_data *)MBUF_CTOP(bp); switch (head->code) { @@ -731,7 +731,7 @@ cbcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) break; } - mbuf_Free(bp); + m_freem(bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/ccp.c b/usr.sbin/ppp/ppp/ccp.c index 263ebdc5ff6..1b533b252e5 100644 --- a/usr.sbin/ppp/ppp/ccp.c +++ b/usr.sbin/ppp/ppp/ccp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ccp.c,v 1.10 1999/06/02 15:58:40 brian Exp $ + * $Id: ccp.c,v 1.11 2000/01/07 03:26:53 brian Exp $ * * TODO: * o Support other compression protocols @@ -30,7 +30,7 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <string.h> /* memcpy() on some archs */ #include <termios.h> #include "layer.h" @@ -90,10 +90,10 @@ static struct fsm_callbacks ccp_Callbacks = { CcpRecvResetAck }; -static const char *ccp_TimerNames[] = +static const char * const ccp_TimerNames[] = {"CCP restart", "CCP openmode", "CCP stopped"}; -static char const *cftypes[] = { +static char const * const cftypes[] = { /* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */ "OUI", /* 0: OUI */ "PRED1", /* 1: Predictor type 1 */ @@ -126,7 +126,7 @@ protoname(int proto) } /* We support these algorithms, and Req them in the given order */ -static const struct ccp_algorithm *algorithm[] = { +static const struct ccp_algorithm * const algorithm[] = { &DeflateAlgorithm, &Pred1Algorithm, &PppdDeflateAlgorithm @@ -534,14 +534,14 @@ extern struct mbuf * ccp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { /* Got PROTO_CCP from link */ - mbuf_SetType(bp, MB_CCPIN); + m_settype(bp, MB_CCPIN); if (bundle_Phase(bundle) == PHASE_NETWORK) fsm_Input(&l->ccp.fsm, bp); else { if (bundle_Phase(bundle) < PHASE_NETWORK) log_Printf(LogCCP, "%s: Error: Unexpected CCP in phase %s (ignored)\n", l->ccp.fsm.link->name, bundle_PhaseName(bundle)); - mbuf_Free(bp); + m_freem(bp); } return NULL; } @@ -584,10 +584,10 @@ ccp_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, (l->ccp.out.state, &l->ccp, l, pri, proto, bp); switch (*proto) { case PROTO_ICOMPD: - mbuf_SetType(bp, MB_ICOMPDOUT); + m_settype(bp, MB_ICOMPDOUT); break; case PROTO_COMPD: - mbuf_SetType(bp, MB_COMPDOUT); + m_settype(bp, MB_COMPDOUT); break; } } @@ -616,15 +616,15 @@ ccp_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) (l->ccp.in.state, &l->ccp, proto, bp); switch (*proto) { case PROTO_ICOMPD: - mbuf_SetType(bp, MB_ICOMPDIN); + m_settype(bp, MB_ICOMPDIN); break; case PROTO_COMPD: - mbuf_SetType(bp, MB_COMPDIN); + m_settype(bp, MB_COMPDIN); break; } return bp; } - mbuf_Free(bp); + m_freem(bp); bp = NULL; } else if (PROTO_COMPRESSIBLE(*proto) && l->ccp.in.state != NULL) { log_Printf(LogDEBUG, "ccp_LayerPull: Ignore packet (dict only)\n"); diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c index c53bc69a821..e27f2840962 100644 --- a/usr.sbin/ppp/ppp/chap.c +++ b/usr.sbin/ppp/ppp/chap.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: chap.c,v 1.17 1999/08/17 15:00:38 brian Exp $ + * $Id: chap.c,v 1.18 2000/01/07 03:26:53 brian Exp $ * * TODO: */ @@ -76,8 +76,9 @@ #ifdef HAVE_DES #include "chap_ms.h" #endif +#include "id.h" -static const char *chapcodes[] = { +static const char * const chapcodes[] = { "???", "CHALLENGE", "RESPONSE", "SUCCESS", "FAILURE" }; #define MAXCHAPCODE (sizeof chapcodes / sizeof chapcodes[0] - 1) @@ -94,7 +95,7 @@ ChapOutput(struct physical *physical, u_int code, u_int id, lh.code = code; lh.id = id; lh.length = htons(plen); - bp = mbuf_Alloc(plen, MB_CHAPOUT); + bp = m_get(plen, MB_CHAPOUT); memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); if (count) memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); @@ -104,7 +105,7 @@ ChapOutput(struct physical *physical, u_int code, u_int id, else log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text); link_PushPacket(&physical->link, bp, physical->dl->bundle, - PRI_LINK, PROTO_CHAP); + LINK_QUEUES(&physical->link) - 1, PROTO_CHAP); } static char * @@ -230,6 +231,15 @@ chap_StartChild(struct chap *chap, char *prog, const char *name) case 0: timer_TermService(); + + if ((argc = command_Interpret(prog, strlen(prog), argv)) <= 0) { + if (argc < 0) { + log_Printf(LogWARN, "CHAP: Invalid command syntax\n"); + _exit(255); + } + _exit(0); + } + close(in[1]); close(out[0]); if (out[1] == STDIN_FILENO) @@ -244,8 +254,7 @@ chap_StartChild(struct chap *chap, char *prog, const char *name) } for (fd = getdtablesize(); fd > STDERR_FILENO; fd--) fcntl(fd, F_SETFD, 1); - setuid(geteuid()); - argc = command_Interpret(prog, strlen(prog), argv); + setuid(ID0realuid()); command_Expand(nargv, argc, (char const *const *)argv, chap->auth.physical->dl->bundle, 0, pid); execvp(nargv[0], nargv); @@ -546,18 +555,18 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p == NULL) { log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } if (bundle_Phase(bundle) != PHASE_NETWORK && bundle_Phase(bundle) != PHASE_AUTHENTICATE) { log_Printf(LogPHASE, "Unexpected chap input - dropped !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } - mbuf_SetType(bp, MB_CHAPIN); + m_settype(bp, MB_CHAPIN); if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL && ntohs(chap->auth.in.hdr.length) == 0) log_Printf(LogWARN, "Chap Input: Truncated header !\n"); @@ -565,7 +574,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n", chap->auth.in.hdr.code); else { - len = mbuf_Length(bp); + len = m_length(bp); ans = NULL; if (chap->auth.in.hdr.code != CHAP_CHALLENGE && @@ -575,7 +584,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n", chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id, chap->auth.id); - mbuf_Free(bp); + m_freem(bp); return NULL; } chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */ @@ -589,7 +598,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) len -= alen + 1; if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated challenge !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } *chap->challenge.peer = alen; @@ -608,12 +617,12 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) len -= alen + 1; if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated response !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } if ((ans = malloc(alen + 2)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } *ans = chap->auth.id; @@ -630,7 +639,7 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) /* chap->auth.in.name is already set up at CHALLENGE time */ if ((ans = malloc(len + 1)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } bp = mbuf_Read(bp, ans, len); @@ -769,6 +778,6 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) free(ans); } - mbuf_Free(bp); + m_freem(bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/chat.c b/usr.sbin/ppp/ppp/chat.c index 370d0770d63..b4176c4c501 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. * - * $Id: chat.c,v 1.10 1999/08/17 15:00:38 brian Exp $ + * $Id: chat.c,v 1.11 2000/01/07 03:26:53 brian Exp $ */ #include <sys/param.h> @@ -72,6 +72,7 @@ #include "radius.h" #endif #include "bundle.h" +#include "id.h" #define BUFLEFT(c) (sizeof (c)->buf - ((c)->bufend - (c)->buf)) @@ -531,8 +532,7 @@ chat_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } void -chat_Init(struct chat *c, struct physical *p, const char *data, int emptybuf, - const char *phone) +chat_Init(struct chat *c, struct physical *p) { c->desc.type = CHAT_DESCRIPTOR; c->desc.UpdateSet = chat_UpdateSet; @@ -540,7 +540,20 @@ chat_Init(struct chat *c, struct physical *p, const char *data, int emptybuf, c->desc.Read = chat_Read; c->desc.Write = chat_Write; c->physical = p; + *c->script = '\0'; + c->argc = 0; + c->arg = -1; + c->argptr = NULL; + c->nargptr = NULL; + c->bufstart = c->bufend = c->buf; + + memset(&c->pause, '\0', sizeof c->pause); + memset(&c->timeout, '\0', sizeof c->timeout); +} +int +chat_Setup(struct chat *c, const char *data, const char *phone) +{ c->state = CHAT_EXPECT; if (data == NULL) { @@ -549,27 +562,26 @@ chat_Init(struct chat *c, struct physical *p, const char *data, int emptybuf, } else { strncpy(c->script, data, sizeof c->script - 1); c->script[sizeof c->script - 1] = '\0'; - c->argc = MakeArgs(c->script, c->argv, VECSIZE(c->argv)); + c->argc = MakeArgs(c->script, c->argv, VECSIZE(c->argv), PARSE_NOHASH); } c->arg = -1; c->argptr = NULL; c->nargptr = NULL; - if (emptybuf) - c->bufstart = c->bufend = c->buf; - c->TimeoutSec = 30; c->TimedOut = 0; c->phone = phone; c->abort.num = 0; - memset(&c->pause, '\0', sizeof c->pause); - memset(&c->timeout, '\0', sizeof c->timeout); + timer_Stop(&c->pause); + timer_Stop(&c->timeout); + + return c->argc >= 0; } void -chat_Destroy(struct chat *c) +chat_Finish(struct chat *c) { timer_Stop(&c->pause); timer_Stop(&c->timeout); @@ -578,6 +590,12 @@ chat_Destroy(struct chat *c) c->abort.num = 0; } +void +chat_Destroy(struct chat *c) +{ + chat_Finish(c); +} + /* * \c don't add a cr * \d Sleep a little (delay 2 seconds @@ -685,7 +703,13 @@ ExecStr(struct physical *physical, char *command, char *out, int olen) int stat, nb, argc, i; log_Printf(LogCHAT, "Exec: %s\n", command); - argc = MakeArgs(command, vector, VECSIZE(vector)); + if ((argc = MakeArgs(command, vector, VECSIZE(vector), + PARSE_REDUCE|PARSE_NOHASH)) <= 0) { + if (argc < 0) + log_Printf(LogWARN, "Syntax error in exec command\n"); + *out = '\0'; + return; + } command_Expand(argv, argc, (char const *const *)vector, physical->dl->bundle, 0, getpid()); @@ -708,7 +732,7 @@ ExecStr(struct physical *physical, char *command, char *out, int olen) open(_PATH_DEVNULL, O_RDWR); /* Leave it closed if it fails... */ for (i = getdtablesize(); i > 3; i--) fcntl(i, F_SETFD, 1); - setuid(geteuid()); + setuid(ID0realuid()); execvp(argv[0], argv); fprintf(stderr, "execvp: %s: %s\n", argv[0], strerror(errno)); _exit(127); diff --git a/usr.sbin/ppp/ppp/chat.h b/usr.sbin/ppp/ppp/chat.h index 7fd96c7592c..8caceba8e68 100644 --- a/usr.sbin/ppp/ppp/chat.h +++ b/usr.sbin/ppp/ppp/chat.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: chat.h,v 1.3 1999/05/08 11:06:34 brian Exp $ + * $Id: chat.h,v 1.4 2000/01/07 03:26:53 brian Exp $ */ #define CHAT_EXPECT 0 @@ -76,6 +76,7 @@ struct chat { ((d)->type == CHAT_DESCRIPTOR ? (struct chat *)(d) : NULL) #define VECSIZE(v) (sizeof(v) / sizeof(v[0])) -extern void chat_Init(struct chat *, struct physical *, const char *, int, - const char *); +extern void chat_Init(struct chat *, struct physical *); +extern int chat_Setup(struct chat *, const char *, const char *); +extern void chat_Finish(struct chat *); extern void chat_Destroy(struct chat *); diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 1c6b6dab1d5..865f1455378 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.35 1999/08/22 01:33:15 brian Exp $ + * $Id: command.c,v 1.36 2000/01/07 03:26:53 brian Exp $ * */ #include <sys/param.h> @@ -33,6 +33,11 @@ #include <ctype.h> #include <errno.h> #include <fcntl.h> +#ifdef __OpenBSD__ +#include <util.h> +#else +#include <libutil.h> +#endif #include <paths.h> #include <stdio.h> #include <stdlib.h> @@ -41,7 +46,7 @@ #include <termios.h> #include <unistd.h> -#ifndef NOALIAS +#ifndef NONAT #ifdef __FreeBSD__ #include <alias.h> #else @@ -62,8 +67,8 @@ #include "lqr.h" #include "hdlc.h" #include "ipcp.h" -#ifndef NOALIAS -#include "alias_cmd.h" +#ifndef NONAT +#include "nat_cmd.h" #endif #include "systems.h" #include "filter.h" @@ -87,6 +92,7 @@ #include "cbcp.h" #include "datalink.h" #include "iface.h" +#include "id.h" /* ``set'' values */ #define VAR_AUTHKEY 0 @@ -122,6 +128,8 @@ #define VAR_CD 30 #define VAR_PARITY 31 #define VAR_CRTSCTS 32 +#define VAR_URGENTPORTS 33 +#define VAR_LOGOUT 34 /* ``accept|deny|disable|enable'' masks */ #define NEG_HISMASK (1) @@ -143,8 +151,7 @@ #define NEG_SHORTSEQ 52 #define NEG_VJCOMP 53 -const char Version[] = "2.23"; -const char VersionDate[] = "$Date: 1999/08/22 01:33:15 $"; +const char Version[] = "2.26"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -163,7 +170,7 @@ static int IfaceAddCommand(struct cmdargs const *); static int IfaceDeleteCommand(struct cmdargs const *); static int IfaceClearCommand(struct cmdargs const *); static int SetProcTitle(struct cmdargs const *); -#ifndef NOALIAS +#ifndef NONAT static int AliasEnable(struct cmdargs const *); static int AliasOption(struct cmdargs const *); #endif @@ -484,7 +491,7 @@ ShellCommand(struct cmdargs const *arg, int bg) for (i = getdtablesize(); i > STDERR_FILENO; i--) fcntl(i, F_SETFD, 1); - setuid(geteuid()); + setuid(ID0realuid()); if (arg->argc > arg->argn) { /* substitute pseudo args */ char *argv[MAXARGS]; @@ -546,37 +553,37 @@ FgShellCommand(struct cmdargs const *arg) return ShellCommand(arg, 0); } -#ifndef NOALIAS +#ifndef NONAT static struct cmdtab const AliasCommands[] = { - {"addr", NULL, alias_RedirectAddr, LOCAL_AUTH, - "static address translation", "alias addr [addr_local addr_alias]"}, + {"addr", NULL, nat_RedirectAddr, LOCAL_AUTH, + "static address translation", "nat addr [addr_local addr_alias]"}, {"deny_incoming", NULL, AliasOption, LOCAL_AUTH, - "stop incoming connections", "alias deny_incoming [yes|no]", + "stop incoming connections", "nat deny_incoming yes|no", (const void *) PKT_ALIAS_DENY_INCOMING}, {"enable", NULL, AliasEnable, LOCAL_AUTH, - "enable IP aliasing", "alias enable [yes|no]"}, + "enable NAT", "nat enable yes|no"}, {"log", NULL, AliasOption, LOCAL_AUTH, - "log aliasing link creation", "alias log [yes|no]", + "log NAT link creation", "nat log yes|no", (const void *) PKT_ALIAS_LOG}, - {"port", NULL, alias_RedirectPort, LOCAL_AUTH, "port redirection", - "alias port proto localaddr:port[-port] aliasport[-aliasport]"}, - {"pptp", NULL, alias_Pptp, LOCAL_AUTH, - "Set the PPTP address", "alias pptp IP"}, - {"proxy", NULL, alias_ProxyRule, LOCAL_AUTH, - "proxy control", "alias proxy server host[:port] ..."}, + {"port", NULL, nat_RedirectPort, LOCAL_AUTH, "port redirection", + "nat port proto localaddr:port[-port] aliasport[-aliasport]"}, + {"pptp", NULL, nat_Pptp, LOCAL_AUTH, + "Set the PPTP address", "nat pptp IP"}, + {"proxy", NULL, nat_ProxyRule, LOCAL_AUTH, + "proxy control", "nat proxy server host[:port] ..."}, {"same_ports", NULL, AliasOption, LOCAL_AUTH, - "try to leave port numbers unchanged", "alias same_ports [yes|no]", + "try to leave port numbers unchanged", "nat same_ports yes|no", (const void *) PKT_ALIAS_SAME_PORTS}, {"unregistered_only", NULL, AliasOption, LOCAL_AUTH, - "alias unregistered (private) IP address space only", - "alias unregistered_only [yes|no]", + "translate unregistered (private) IP address space only", + "nat unregistered_only yes|no", (const void *) PKT_ALIAS_UNREGISTERED_ONLY}, {"use_sockets", NULL, AliasOption, LOCAL_AUTH, - "allocate host sockets", "alias use_sockets [yes|no]", + "allocate host sockets", "nat use_sockets yes|no", (const void *) PKT_ALIAS_USE_SOCKETS}, {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, - "Display this message", "alias help|? [command]", AliasCommands}, + "Display this message", "nat help|? [command]", AliasCommands}, {NULL, NULL, NULL}, }; #endif @@ -609,7 +616,7 @@ static struct cmdtab const IfaceCommands[] = {"show", NULL, iface_Show, LOCAL_AUTH, "Show iface address(es)", "iface show"}, {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, - "Display this message", "alias help|? [command]", IfaceCommands}, + "Display this message", "nat help|? [command]", IfaceCommands}, {NULL, NULL, NULL}, }; @@ -620,10 +627,6 @@ static struct cmdtab const Commands[] = { "add route", "add dest mask gateway", NULL}, {NULL, "add!", AddCommand, LOCAL_AUTH, "add or change route", "add! dest mask gateway", (void *)1}, -#ifndef NOALIAS - {"alias", NULL, RunListCommand, LOCAL_AUTH, - "alias control", "alias option [yes|no]", AliasCommands}, -#endif {"allow", "auth", RunListCommand, LOCAL_AUTH, "Allow ppp access", "allow users|modes ....", AllowCommands}, {"bg", "!bg", BgShellCommand, LOCAL_AUTH, @@ -655,6 +658,10 @@ static struct cmdtab const Commands[] = { "Link specific commands", "link name command ..."}, {"load", NULL, LoadCommand, LOCAL_AUTH | LOCAL_CX_OPT, "Load settings", "load [system ...]"}, +#ifndef NONAT + {"nat", "alias", RunListCommand, LOCAL_AUTH, + "NAT control", "nat option yes|no", AliasCommands}, +#endif {"open", NULL, OpenCommand, LOCAL_AUTH | LOCAL_CX_OPT, "Open an FSM", "open! [lcp|ccp|ipcp]", (void *)1}, {"passwd", NULL, PasswdCommand, LOCAL_NO_AUTH, @@ -731,7 +738,7 @@ ShowStopped(struct cmdargs const *arg) static int ShowVersion(struct cmdargs const *arg) { - prompt_Printf(arg->prompt, "PPP Version %s - %s\n", Version, VersionDate); + prompt_Printf(arg->prompt, "PPP Version %s - %s\n", Version, __DATE__); return 0; } @@ -906,7 +913,7 @@ command_Interpret(char *buff, int nb, char *argv[MAXARGS]) cp = buff + strcspn(buff, "\r\n"); if (cp) *cp = '\0'; - return MakeArgs(buff, argv, MAXARGS); + return MakeArgs(buff, argv, MAXARGS, PARSE_REDUCE); } return 0; } @@ -969,15 +976,18 @@ command_Run(struct bundle *bundle, int argc, char const *const *argv, } } -void +int command_Decode(struct bundle *bundle, char *buff, int nb, struct prompt *prompt, const char *label) { int argc; char *argv[MAXARGS]; - argc = command_Interpret(buff, nb, argv); + if ((argc = command_Interpret(buff, nb, argv)) < 0) + return 0; + command_Run(bundle, argc, (char const *const *)argv, prompt, label, NULL); + return 1; } static int @@ -1137,7 +1147,7 @@ SetModemSpeed(struct cmdargs const *arg) if (arg->argc > arg->argn && *arg->argv[arg->argn]) { if (arg->argc > arg->argn+1) { - log_Printf(LogWARN, "SetModemSpeed: Too many arguments"); + log_Printf(LogWARN, "SetModemSpeed: Too many arguments\n"); return -1; } if (strcasecmp(arg->argv[arg->argn], "sync") == 0) { @@ -1178,9 +1188,6 @@ SetStoppedTimeout(struct cmdargs const *arg) return -1; } -#define ismask(x) \ - (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3) - static int SetServer(struct cmdargs const *arg) { @@ -1188,6 +1195,7 @@ SetServer(struct cmdargs const *arg) if (arg->argc > arg->argn && arg->argc < arg->argn+4) { const char *port, *passwd, *mask; + int mlen; /* What's what ? */ port = arg->argv[arg->argn]; @@ -1197,8 +1205,13 @@ SetServer(struct cmdargs const *arg) } else if (arg->argc == arg->argn + 3) { passwd = arg->argv[arg->argn+1]; mask = arg->argv[arg->argn+2]; - if (!ismask(mask)) + mlen = strlen(mask); + if (mlen == 0 || mlen > 4 || strspn(mask, "01234567") != mlen || + (mlen == 4 && *mask != '0')) { + log_Printf(LogWARN, "%s %s: %s: Invalid mask\n", + arg->argv[arg->argn - 2], arg->argv[arg->argn - 1], mask); return -1; + } } else if (strcasecmp(port, "none") == 0) { if (server_Close(arg->bundle)) log_Printf(LogPHASE, "Disabled server port.\n"); @@ -1213,15 +1226,10 @@ SetServer(struct cmdargs const *arg) mode_t imask; char *ptr, name[LINE_LEN + 12]; - if (mask != NULL) { - unsigned m; - - if (sscanf(mask, "%o", &m) == 1) - imask = m; - else - return -1; - } else + if (mask == NULL) imask = (mode_t)-1; + else for (imask = mlen = 0; mask[mlen]; mlen++) + imask = (imask * 8) + mask[mlen] - '0'; ptr = strstr(port, "%d"); if (ptr) { @@ -1375,7 +1383,7 @@ static int SetVariable(struct cmdargs const *arg) { long long_val, param = (long)arg->cmd->args; - int mode, dummyint; + int mode, dummyint, f, first; const char *argp; struct datalink *cx = arg->cx; /* LOCAL_CX uses this */ const char *err = NULL; @@ -1595,6 +1603,11 @@ SetVariable(struct cmdargs const *arg) cx->cfg.script.hangup[sizeof cx->cfg.script.hangup - 1] = '\0'; break; + case VAR_LOGOUT: + strncpy(cx->cfg.script.logout, argp, sizeof cx->cfg.script.logout - 1); + cx->cfg.script.logout[sizeof cx->cfg.script.logout - 1] = '\0'; + break; + case VAR_IDLETIMEOUT: if (arg->argc > arg->argn+2) err = "Too many idle timeout values\n"; @@ -1757,14 +1770,18 @@ SetVariable(struct cmdargs const *arg) case VAR_CD: if (*argp) { - long_val = atol(argp); - if (long_val < 0) - long_val = 0; - cx->physical->cfg.cd.delay = long_val; - cx->physical->cfg.cd.required = argp[strlen(argp)-1] == '!'; + if (strcasecmp(argp, "off")) { + long_val = atol(argp); + if (long_val < 0) + long_val = 0; + cx->physical->cfg.cd.delay = long_val; + cx->physical->cfg.cd.necessity = argp[strlen(argp)-1] == '!' ? + CD_REQUIRED : CD_VARIABLE; + } else + cx->physical->cfg.cd.necessity = CD_NOTREQUIRED; } else { - cx->physical->cfg.cd.delay = DEF_CDDELAY; - cx->physical->cfg.cd.required = 0; + cx->physical->cfg.cd.delay = 0; + cx->physical->cfg.cd.necessity = CD_DEFAULT; } break; @@ -1787,6 +1804,43 @@ SetVariable(struct cmdargs const *arg) log_Printf(LogWARN, err); } break; + + case VAR_URGENTPORTS: + if (arg->argn == arg->argc) { + ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp); + ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp); + } else if (!strcasecmp(arg->argv[arg->argn], "udp")) { + if (arg->argn == arg->argc - 1) + ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp); + else for (f = arg->argn + 1; f < arg->argc; f++) + if (*arg->argv[f] == '+') + ipcp_AddUrgentUdpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1)); + else if (*arg->argv[f] == '-') + ipcp_RemoveUrgentUdpPort(&arg->bundle->ncp.ipcp, + atoi(arg->argv[f] + 1)); + else { + if (f == arg->argn) + ipcp_ClearUrgentUdpPorts(&arg->bundle->ncp.ipcp); + ipcp_AddUrgentUdpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f])); + } + } else { + first = arg->argn; + if (!strcasecmp(arg->argv[first], "tcp") && ++first == arg->argc) + ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp); + + for (f = first; f < arg->argc; f++) + if (*arg->argv[f] == '+') + ipcp_AddUrgentTcpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f] + 1)); + else if (*arg->argv[f] == '-') + ipcp_RemoveUrgentTcpPort(&arg->bundle->ncp.ipcp, + atoi(arg->argv[f] + 1)); + else { + if (f == first) + ipcp_ClearUrgentTcpPorts(&arg->bundle->ncp.ipcp); + ipcp_AddUrgentTcpPort(&arg->bundle->ncp.ipcp, atoi(arg->argv[f])); + } + } + break; } return err ? 1 : 0; @@ -1802,6 +1856,8 @@ static struct cmdtab const SetCommands[] = { {"autoload", NULL, SetVariable, LOCAL_AUTH, "auto link [de]activation", "set autoload maxtime maxload mintime minload", (const void *)VAR_AUTOLOAD}, + {"bandwidth", NULL, mp_SetDatalinkBandwidth, LOCAL_AUTH | LOCAL_CX, + "datalink bandwidth", "set bandwidth value"}, {"callback", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "callback control", "set callback [none|auth|cbcp|" "E.164 *|number[,number]...]...", (const void *)VAR_CALLBACK}, @@ -1851,6 +1907,8 @@ static struct cmdtab const SetCommands[] = { "ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."}, {"login", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "login script", "set login chat-script", (const void *) VAR_LOGIN}, + {"logout", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, + "logout script", "set logout chat-script", (const void *) VAR_LOGOUT}, {"lqrperiod", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT, "LQR period", "set lqrperiod value", (const void *)VAR_LQRPERIOD}, {"mode", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "mode value", @@ -1893,10 +1951,10 @@ static struct cmdtab const SetCommands[] = { "STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"}, {"timeout", NULL, SetVariable, LOCAL_AUTH, "Idle timeout", "set timeout idletime", (const void *)VAR_IDLETIMEOUT}, + {"urgent", NULL, SetVariable, LOCAL_AUTH, "urgent ports", + "set urgent [tcp|udp] [+|-]port...", (const void *)VAR_URGENTPORTS}, {"vj", NULL, ipcp_vjset, LOCAL_AUTH, "vj values", "set vj slots|slotcomp [value]"}, - {"bandwidth", NULL, mp_SetDatalinkBandwidth, LOCAL_AUTH | LOCAL_CX, - "datalink bandwidth", "set bandwidth value"}, {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, "Display this message", "set help|? [command]", SetCommands}, {NULL, NULL, NULL}, @@ -2006,20 +2064,20 @@ DeleteCommand(struct cmdargs const *arg) return 0; } -#ifndef NOALIAS +#ifndef NONAT static int AliasEnable(struct cmdargs const *arg) { if (arg->argc == arg->argn+1) { if (strcasecmp(arg->argv[arg->argn], "yes") == 0) { - if (!arg->bundle->AliasEnabled) { + if (!arg->bundle->NatEnabled) { if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED) PacketAliasSetAddress(arg->bundle->ncp.ipcp.my_ip); - arg->bundle->AliasEnabled = 1; + arg->bundle->NatEnabled = 1; } return 0; } else if (strcasecmp(arg->argv[arg->argn], "no") == 0) { - arg->bundle->AliasEnabled = 0; + arg->bundle->NatEnabled = 0; arg->bundle->cfg.opt &= ~OPT_IFACEALIAS; /* Don't iface_Clear() - there may be manually configured addresses */ return 0; @@ -2037,22 +2095,22 @@ AliasOption(struct cmdargs const *arg) if (arg->argc == arg->argn+1) { if (strcasecmp(arg->argv[arg->argn], "yes") == 0) { - if (arg->bundle->AliasEnabled) { + if (arg->bundle->NatEnabled) { PacketAliasSetMode(param, param); return 0; } - log_Printf(LogWARN, "alias not enabled\n"); + log_Printf(LogWARN, "nat not enabled\n"); } else if (strcmp(arg->argv[arg->argn], "no") == 0) { - if (arg->bundle->AliasEnabled) { + if (arg->bundle->NatEnabled) { PacketAliasSetMode(0, param); return 0; } - log_Printf(LogWARN, "alias not enabled\n"); + log_Printf(LogWARN, "nat not enabled\n"); } } return -1; } -#endif /* #ifndef NOALIAS */ +#endif /* #ifndef NONAT */ static int LinkCommand(struct cmdargs const *arg) @@ -2187,9 +2245,9 @@ IfaceAliasOptSet(struct cmdargs const *arg) int result = OptSet(arg); if (result == 0) - if (Enabled(arg->bundle, OPT_IFACEALIAS) && !arg->bundle->AliasEnabled) { + if (Enabled(arg->bundle, OPT_IFACEALIAS) && !arg->bundle->NatEnabled) { arg->bundle->cfg.opt = save; - log_Printf(LogWARN, "Cannot enable iface-alias without IP aliasing\n"); + log_Printf(LogWARN, "Cannot enable iface-alias without NAT\n"); result = 2; } @@ -2560,8 +2618,7 @@ SetProcTitle(struct cmdargs const *arg) int len, remaining, f, argc = arg->argc - arg->argn; if (arg->argc == arg->argn) { - arg->bundle->argv[0] = arg->bundle->argv0; - arg->bundle->argv[1] = arg->bundle->argv1; + ID0setproctitle(NULL); return 0; } @@ -2587,8 +2644,7 @@ SetProcTitle(struct cmdargs const *arg) } *ptr = '\0'; - arg->bundle->argv[0] = title; - arg->bundle->argv[1] = NULL; + ID0setproctitle(title); return 0; } diff --git a/usr.sbin/ppp/ppp/command.h b/usr.sbin/ppp/ppp/command.h index 854fa6b093c..1ec319afede 100644 --- a/usr.sbin/ppp/ppp/command.h +++ b/usr.sbin/ppp/ppp/command.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.h,v 1.4 1999/06/09 08:47:23 brian Exp $ + * $Id: command.h,v 1.5 2000/01/07 03:26:53 brian Exp $ * * TODO: */ @@ -52,14 +52,13 @@ struct cmdtab { #define IsEnabled(x) ((x) & NEG_ENABLED) extern const char Version[]; -extern const char VersionDate[]; extern void command_Expand(char **, int, char const *const *, struct bundle *, int, pid_t); extern int command_Interpret(char *, int, char *vector[MAXARGS]); extern void command_Run(struct bundle *, int, char const *const *, struct prompt *, const char *, struct datalink *); -extern void command_Decode(struct bundle *, char *, int, struct prompt *, +extern int command_Decode(struct bundle *, char *, int, struct prompt *, const char *); extern struct link *command_ChooseLink(struct cmdargs const *); extern const char *command_ShowNegval(unsigned); diff --git a/usr.sbin/ppp/ppp/datalink.c b/usr.sbin/ppp/ppp/datalink.c index b2e3312d02b..e5a2e81d66b 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. * - * $Id: datalink.c,v 1.24 1999/08/05 10:32:13 brian Exp $ + * $Id: datalink.c,v 1.25 2000/01/07 03:26:53 brian Exp $ */ #include <sys/param.h> @@ -120,6 +120,7 @@ datalink_HangupDone(struct datalink *dl) return; } + chat_Finish(&dl->chat); physical_Close(dl->physical); dl->phone.chosen = "N/A"; @@ -144,7 +145,8 @@ datalink_HangupDone(struct datalink *dl) datalink_StartDialTimer(dl, dl->cbcp.fsm.delay); cbcp_Down(&dl->cbcp); datalink_NewState(dl, DATALINK_OPENING); - if (bundle_Phase(dl->bundle) != PHASE_TERMINATE) + if (bundle_Phase(dl->bundle) == PHASE_DEAD || + bundle_Phase(dl->bundle) == PHASE_TERMINATE) bundle_NewPhase(dl->bundle, PHASE_ESTABLISH); } else if (dl->bundle->CleaningUp || (dl->physical->type == PHYS_DIRECT) || @@ -159,7 +161,8 @@ datalink_HangupDone(struct datalink *dl) datalink_StartDialTimer(dl, datalink_GetDialTimeout(dl)); } else { datalink_NewState(dl, DATALINK_OPENING); - if (bundle_Phase(dl->bundle) != PHASE_TERMINATE) + if (bundle_Phase(dl->bundle) == PHASE_DEAD || + bundle_Phase(dl->bundle) == PHASE_TERMINATE) bundle_NewPhase(dl->bundle, PHASE_ESTABLISH); if (dl->dial.tries < 0) { datalink_StartDialTimer(dl, dl->cfg.reconnect.timeout); @@ -175,7 +178,7 @@ datalink_HangupDone(struct datalink *dl) } } -static const char * +const char * datalink_ChoosePhoneNumber(struct datalink *dl) { char *phone; @@ -200,6 +203,8 @@ datalink_ChoosePhoneNumber(struct datalink *dl) static void datalink_LoginDone(struct datalink *dl) { + chat_Finish(&dl->chat); + if (!dl->script.packetmode) { dl->dial.tries = -1; dl->dial.incs = 0; @@ -208,9 +213,9 @@ datalink_LoginDone(struct datalink *dl) dl->dial.tries = 0; log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n"); if (dl->script.run) { - datalink_NewState(dl, DATALINK_HANGUP); - physical_Offline(dl->physical); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL); + datalink_NewState(dl, DATALINK_LOGOUT); + if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) + log_Printf(LogWARN, "Invalid logout script\n"); } else { physical_StopDeviceTimer(dl->physical); if (dl->physical->type == PHYS_DEDICATED) @@ -245,13 +250,14 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, result = 0; switch (dl->state) { case DATALINK_CLOSED: - if ((dl->physical->type & - (PHYS_DIRECT|PHYS_DEDICATED|PHYS_BACKGROUND|PHYS_DDIAL)) && + if ((dl->physical->type & (PHYS_DIRECT|PHYS_DEDICATED|PHYS_BACKGROUND| + PHYS_FOREGROUND|PHYS_DDIAL)) && !dl->bundle->CleaningUp) /* * Our first time in - DEDICATED & DDIAL never come down, and - * DIRECT & BACKGROUND get deleted when they enter DATALINK_CLOSED. - * Go to DATALINK_OPENING via datalink_Up() and fall through. + * DIRECT, FOREGROUND & BACKGROUND get deleted when they enter + * DATALINK_CLOSED. Go to DATALINK_OPENING via datalink_Up() + * and fall through. */ datalink_Up(dl, 1, 1); else @@ -268,15 +274,17 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, dl->physical->name.full); if (dl->script.run) { datalink_NewState(dl, DATALINK_DIAL); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.dial, 1, - datalink_ChoosePhoneNumber(dl)); + if (!chat_Setup(&dl->chat, dl->cfg.script.dial, + *dl->cfg.script.dial ? + datalink_ChoosePhoneNumber(dl) : "")) + log_Printf(LogWARN, "Invalid dial script\n"); if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && dl->cfg.dial.max) log_Printf(LogCHAT, "%s: Dial attempt %u of %d\n", dl->name, dl->cfg.dial.max - dl->dial.tries, dl->cfg.dial.max); } else - datalink_LoginDone(dl); + datalink_NewState(dl, DATALINK_CARRIER); return datalink_UpdateSet(d, r, w, e, n); } else { if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && @@ -307,21 +315,55 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, } break; + case DATALINK_CARRIER: + /* Wait for carrier on the device */ + switch (physical_AwaitCarrier(dl->physical)) { + case CARRIER_PENDING: + log_Printf(LogDEBUG, "Waiting for carrier\n"); + return 0; /* A device timer is running to wake us up again */ + + case CARRIER_OK: + if (dl->script.run) { + datalink_NewState(dl, DATALINK_LOGIN); + if (!chat_Setup(&dl->chat, dl->cfg.script.login, NULL)) + log_Printf(LogWARN, "Invalid login script\n"); + } else + datalink_LoginDone(dl); + return datalink_UpdateSet(d, r, w, e, n); + + case CARRIER_LOST: + physical_Offline(dl->physical); /* Is this required ? */ + if (dl->script.run) { + datalink_NewState(dl, DATALINK_HANGUP); + if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) + log_Printf(LogWARN, "Invalid hangup script\n"); + return datalink_UpdateSet(d, r, w, e, n); + } else { + datalink_HangupDone(dl); + return 0; /* Maybe bundle_CleanDatalinks() has something to do */ + } + } + case DATALINK_HANGUP: case DATALINK_DIAL: + case DATALINK_LOGOUT: case DATALINK_LOGIN: result = descriptor_UpdateSet(&dl->chat.desc, r, w, e, n); switch (dl->chat.state) { case CHAT_DONE: /* script succeeded */ - chat_Destroy(&dl->chat); switch(dl->state) { case DATALINK_HANGUP: datalink_HangupDone(dl); break; case DATALINK_DIAL: - datalink_NewState(dl, DATALINK_LOGIN); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.login, 0, NULL); + datalink_NewState(dl, DATALINK_CARRIER); + return datalink_UpdateSet(d, r, w, e, n); + case DATALINK_LOGOUT: + datalink_NewState(dl, DATALINK_HANGUP); + physical_Offline(dl->physical); + if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) + log_Printf(LogWARN, "Invalid hangup script\n"); return datalink_UpdateSet(d, r, w, e, n); case DATALINK_LOGIN: dl->phone.alt = NULL; @@ -332,16 +374,17 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, case CHAT_FAILED: /* Going down - script failed */ log_Printf(LogWARN, "Chat script failed\n"); - chat_Destroy(&dl->chat); switch(dl->state) { case DATALINK_HANGUP: datalink_HangupDone(dl); break; case DATALINK_DIAL: + case DATALINK_LOGOUT: case DATALINK_LOGIN: datalink_NewState(dl, DATALINK_HANGUP); - physical_Offline(dl->physical); /* Is this required ? */ - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL); + physical_Offline(dl->physical); + if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) + log_Printf(LogWARN, "Invalid hangup script\n"); return datalink_UpdateSet(d, r, w, e, n); } break; @@ -378,6 +421,7 @@ datalink_IsSet(struct descriptor *d, const fd_set *fdset) case DATALINK_HANGUP: case DATALINK_DIAL: + case DATALINK_LOGOUT: case DATALINK_LOGIN: return descriptor_IsSet(&dl->chat.desc, fdset); @@ -404,6 +448,7 @@ datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) case DATALINK_HANGUP: case DATALINK_DIAL: + case DATALINK_LOGOUT: case DATALINK_LOGIN: descriptor_Read(&dl->chat.desc, bundle, fdset); break; @@ -434,6 +479,7 @@ datalink_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) case DATALINK_HANGUP: case DATALINK_DIAL: + case DATALINK_LOGOUT: case DATALINK_LOGIN: result = descriptor_Write(&dl->chat.desc, bundle, fdset); break; @@ -469,10 +515,16 @@ datalink_ComeDown(struct datalink *dl, int how) datalink_NewState(dl, DATALINK_READY); } else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP) { physical_Offline(dl->physical); - chat_Destroy(&dl->chat); if (dl->script.run && dl->state != DATALINK_OPENING) { - datalink_NewState(dl, DATALINK_HANGUP); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL); + if (dl->state == DATALINK_LOGOUT) { + datalink_NewState(dl, DATALINK_HANGUP); + if (!chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL)) + log_Printf(LogWARN, "Invalid hangup script\n"); + } else { + datalink_NewState(dl, DATALINK_LOGOUT); + if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) + log_Printf(LogWARN, "Invalid logout script\n"); + } } else datalink_HangupDone(dl); } @@ -728,6 +780,7 @@ datalink_Create(const char *name, struct bundle *bundle, int type) *dl->cfg.script.dial = '\0'; *dl->cfg.script.login = '\0'; + *dl->cfg.script.logout = '\0'; *dl->cfg.script.hangup = '\0'; *dl->cfg.phone.list = '\0'; *dl->phone.list = '\0'; @@ -778,7 +831,9 @@ datalink_Create(const char *name, struct bundle *bundle, int type) pap_Init(&dl->pap, dl->physical); chap_Init(&dl->chap, dl->physical); cbcp_Init(&dl->cbcp, dl->physical); - chat_Init(&dl->chat, dl->physical, NULL, 1, NULL); + + memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Created in %s state\n", dl->name, datalink_State(dl)); @@ -840,7 +895,9 @@ datalink_Clone(struct datalink *odl, const char *name) sizeof dl->physical->async.cfg); cbcp_Init(&dl->cbcp, dl->physical); - chat_Init(&dl->chat, dl->physical, NULL, 1, NULL); + + memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Cloned in %s state\n", dl->name, datalink_State(dl)); @@ -860,11 +917,12 @@ datalink_Destroy(struct datalink *dl) case DATALINK_HANGUP: case DATALINK_DIAL: case DATALINK_LOGIN: - chat_Destroy(&dl->chat); /* Gotta blat the timers ! */ + chat_Finish(&dl->chat); /* Gotta blat the timers ! */ break; } } + chat_Destroy(&dl->chat); timer_Stop(&dl->dial.timer); result = dl->next; physical_Destroy(dl->physical); @@ -1056,6 +1114,8 @@ datalink_Show(struct cmdargs const *arg) arg->cx->cfg.script.dial); prompt_Printf(arg->prompt, " Login Script: %s\n", arg->cx->cfg.script.login); + prompt_Printf(arg->prompt, " Logout Script: %s\n", + arg->cx->cfg.script.logout); prompt_Printf(arg->prompt, " Hangup Script: %s\n", arg->cx->cfg.script.hangup); return 0; @@ -1159,11 +1219,13 @@ datalink_SetRedial(struct cmdargs const *arg) return -1; } -static const char *states[] = { +static const char * const states[] = { "closed", "opening", "hangup", "dial", + "carrier", + "logout", "login", "ready", "lcp", @@ -1195,7 +1257,7 @@ datalink_NewState(struct datalink *dl, int state) struct datalink * iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, - int fd) + int fd, int *auxfd, int *nauxfd) { struct datalink *dl, *cdl; struct fsm_retry copy; @@ -1256,7 +1318,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, dl->fsmp.LayerFinish = datalink_LayerFinish; dl->fsmp.object = dl; - dl->physical = iov2physical(dl, iov, niov, maxiov, fd); + dl->physical = iov2physical(dl, iov, niov, maxiov, fd, auxfd, nauxfd); if (!dl->physical) { free(dl->name); @@ -1272,7 +1334,9 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, dl->chap.auth.cfg.fsm = copy; cbcp_Init(&dl->cbcp, dl->physical); - chat_Init(&dl->chat, dl->physical, NULL, 1, NULL); + + memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Transferred in %s state\n", dl->name, datalink_State(dl)); @@ -1283,7 +1347,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, int datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, - pid_t newpid) + int *auxfd, int *nauxfd) { /* If `dl' is NULL, we're allocating before a Fromiov() */ int link_fd; @@ -1305,13 +1369,13 @@ datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, return -1; } - iov[*niov].iov_base = dl ? dl : malloc(sizeof *dl); + iov[*niov].iov_base = (void *)dl; iov[(*niov)++].iov_len = sizeof *dl; - iov[*niov].iov_base = - dl ? realloc(dl->name, DATALINK_MAXNAME) : malloc(DATALINK_MAXNAME); + iov[*niov].iov_base = dl ? realloc(dl->name, DATALINK_MAXNAME) : NULL; iov[(*niov)++].iov_len = DATALINK_MAXNAME; - link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, newpid); + link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, auxfd, + nauxfd); if (link_fd == -1 && dl) { free(dl->name); @@ -1356,7 +1420,8 @@ datalink_SetMode(struct datalink *dl, int mode) dl->script.run = 0; if (dl->physical->type == PHYS_DIRECT) dl->reconnect_tries = 0; - if (mode & (PHYS_DDIAL|PHYS_BACKGROUND) && dl->state <= DATALINK_READY) + if (mode & (PHYS_DDIAL|PHYS_BACKGROUND|PHYS_FOREGROUND) && + dl->state <= DATALINK_READY) datalink_Up(dl, 1, 1); return 1; } diff --git a/usr.sbin/ppp/ppp/datalink.h b/usr.sbin/ppp/ppp/datalink.h index 8c65bca1654..62e072ec0ab 100644 --- a/usr.sbin/ppp/ppp/datalink.h +++ b/usr.sbin/ppp/ppp/datalink.h @@ -23,19 +23,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: datalink.h,v 1.5 1999/07/15 02:10:32 brian Exp $ + * $Id: datalink.h,v 1.6 2000/01/07 03:26:53 brian Exp $ */ #define DATALINK_CLOSED (0) #define DATALINK_OPENING (1) #define DATALINK_HANGUP (2) #define DATALINK_DIAL (3) -#define DATALINK_LOGIN (4) -#define DATALINK_READY (5) -#define DATALINK_LCP (6) -#define DATALINK_AUTH (7) -#define DATALINK_CBCP (8) -#define DATALINK_OPEN (9) +#define DATALINK_CARRIER (4) +#define DATALINK_LOGOUT (5) +#define DATALINK_LOGIN (6) +#define DATALINK_READY (7) +#define DATALINK_LCP (8) +#define DATALINK_AUTH (9) +#define DATALINK_CBCP (10) +#define DATALINK_OPEN (11) #define DATALINK_MAXNAME (20) /* Maximum datalink::name length */ @@ -64,10 +66,11 @@ struct datalink { struct { struct { - char dial[SCRIPT_LEN]; /* dial */ - char login[SCRIPT_LEN]; /* login */ - char hangup[SCRIPT_LEN]; /* hangup */ - } script; + char dial[SCRIPT_LEN]; + char login[SCRIPT_LEN]; + char logout[SCRIPT_LEN]; + char hangup[SCRIPT_LEN]; + } script; /* various chat scripts */ struct { char list[SCRIPT_LEN]; /* Telephone Numbers */ } phone; @@ -125,8 +128,9 @@ struct datalink { extern struct datalink *datalink_Create(const char *name, struct bundle *, int); extern struct datalink *datalink_Clone(struct datalink *, const char *); extern struct datalink *iov2datalink(struct bundle *, struct iovec *, int *, - int, int); -extern int datalink2iov(struct datalink *, struct iovec *, int *, int, pid_t); + int, int, int *, int *); +extern int datalink2iov(struct datalink *, struct iovec *, int *, int, int *, + int *); extern struct datalink *datalink_Destroy(struct datalink *); extern void datalink_GotAuthname(struct datalink *, const char *); extern void datalink_Up(struct datalink *, int, int); @@ -149,3 +153,4 @@ extern int datalink_RemoveFromSet(struct datalink *, fd_set *, fd_set *, fd_set *); extern int datalink_SetMode(struct datalink *, int); extern int datalink_GetDialTimeout(struct datalink *); +extern const char *datalink_ChoosePhoneNumber(struct datalink *); diff --git a/usr.sbin/ppp/ppp/deflate.c b/usr.sbin/ppp/ppp/deflate.c index 199848bd978..93bbb88c1e0 100644 --- a/usr.sbin/ppp/ppp/deflate.c +++ b/usr.sbin/ppp/ppp/deflate.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: deflate.c,v 1.7 1999/07/15 02:10:32 brian Exp $ + * $Id: deflate.c,v 1.8 2000/01/07 03:26:53 brian Exp $ */ #include <sys/types.h> @@ -37,8 +37,6 @@ #include "mbuf.h" #include "log.h" #include "timer.h" -#include "lqr.h" -#include "hdlc.h" #include "fsm.h" #include "lcp.h" #include "ccp.h" @@ -55,7 +53,7 @@ struct deflate_state { static char garbage[10]; static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff }; -#define DEFLATE_CHUNK_LEN 1600 /* Allocate mbufs this size */ +#define DEFLATE_CHUNK_LEN (1536 - sizeof(struct mbuf)) static void DeflateResetOutput(void *v) @@ -77,26 +75,26 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, int olen, ilen, len, res, flush; struct mbuf *mo_head, *mo, *mi_head, *mi; - ilen = mbuf_Length(mp); + ilen = m_length(mp); log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", *proto, ilen); log_DumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp); /* Stuff the protocol in front of the input */ - mi_head = mi = mbuf_Alloc(2, MB_CCPOUT); - mi->next = mp; + mi_head = mi = m_get(2, MB_CCPOUT); + mi->m_next = mp; rp = MBUF_CTOP(mi); if (*proto < 0x100) { /* Compress the protocol */ rp[0] = *proto & 0377; - mi->cnt = 1; + mi->m_len = 1; } else { /* Don't compress the protocol */ rp[0] = *proto >> 8; rp[1] = *proto & 0377; - mi->cnt = 2; + mi->m_len = 2; } /* Allocate the initial output mbuf */ - mo_head = mo = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_CCPOUT); - mo->cnt = 2; + mo_head = mo = m_get(DEFLATE_CHUNK_LEN, MB_CCPOUT); + mo->m_len = 2; wp = MBUF_CTOP(mo); *wp++ = state->seqno >> 8; *wp++ = state->seqno & 0377; @@ -107,7 +105,7 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, state->cx.next_out = wp; state->cx.avail_out = DEFLATE_CHUNK_LEN - 2; state->cx.next_in = MBUF_CTOP(mi); - state->cx.avail_in = mi->cnt; + state->cx.avail_in = mi->m_len; flush = Z_NO_FLUSH; olen = 0; @@ -117,8 +115,8 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, break; /* Done */ log_Printf(LogWARN, "DeflateOutput: deflate returned %d (%s)\n", res, state->cx.msg ? state->cx.msg : ""); - mbuf_Free(mo_head); - mbuf_FreeSeg(mi_head); + m_freem(mo_head); + m_free(mi_head); state->seqno--; return mp; /* Our dictionary's probably dead now :-( */ } @@ -126,25 +124,25 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0) break; - if (state->cx.avail_in == 0 && mi->next != NULL) { - mi = mi->next; + if (state->cx.avail_in == 0 && mi->m_next != NULL) { + mi = mi->m_next; state->cx.next_in = MBUF_CTOP(mi); - state->cx.avail_in = mi->cnt; - if (mi->next == NULL) + state->cx.avail_in = mi->m_len; + if (mi->m_next == NULL) flush = Z_SYNC_FLUSH; } if (state->cx.avail_out == 0) { - mo->next = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_CCPOUT); - olen += (mo->cnt = DEFLATE_CHUNK_LEN); - mo = mo->next; - mo->cnt = 0; + mo->m_next = m_get(DEFLATE_CHUNK_LEN, MB_CCPOUT); + olen += (mo->m_len = DEFLATE_CHUNK_LEN); + mo = mo->m_next; + mo->m_len = 0; state->cx.next_out = MBUF_CTOP(mo); state->cx.avail_out = DEFLATE_CHUNK_LEN; } } - olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out); + olen += (mo->m_len = DEFLATE_CHUNK_LEN - state->cx.avail_out); olen -= 4; /* exclude the trailing EMPTY_BLOCK */ /* @@ -152,8 +150,8 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, * got bigger, send the original. */ if (olen >= ilen) { - mbuf_Free(mo_head); - mbuf_FreeSeg(mi_head); + m_freem(mo_head); + m_free(mi_head); log_Printf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n", ilen, olen, *proto); ccp->uncompout += ilen; @@ -161,19 +159,20 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, return mp; } - mbuf_Free(mi_head); + m_freem(mi_head); /* * Lose the last four bytes of our output. * XXX: We should probably assert that these are the same as the * contents of EMPTY_BLOCK. */ - for (mo = mo_head, len = mo->cnt; len < olen; mo = mo->next, len += mo->cnt) + mo = mo_head; + for (len = mo->m_len; len < olen; mo = mo->m_next, len += mo->m_len) ; - mo->cnt -= len - olen; - if (mo->next != NULL) { - mbuf_Free(mo->next); - mo->next = NULL; + mo->m_len -= len - olen; + if (mo->m_next != NULL) { + m_freem(mo->m_next); + mo->m_next = NULL; } ccp->uncompout += ilen; @@ -225,7 +224,7 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) else { log_Printf(LogCCP, "DeflateInput: Seq error: Got %d, expected %d\n", seq, state->seqno); - mbuf_Free(mi_head); + m_freem(mi_head); ccp_SendResetReq(&ccp->fsm); return NULL; } @@ -234,7 +233,7 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) state->uncomp_rec = 0; /* Allocate an output mbuf */ - mo_head = mo = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_CCPIN); + mo_head = mo = m_get(DEFLATE_CHUNK_LEN, MB_CCPIN); /* Our proto starts with 0 if it's compressed */ wp = MBUF_CTOP(mo); @@ -246,12 +245,12 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) * proto field. */ state->cx.next_in = MBUF_CTOP(mi); - state->cx.avail_in = mi->cnt; + state->cx.avail_in = mi->m_len; state->cx.next_out = wp + 1; state->cx.avail_out = 1; - ilen += mi->cnt; + ilen += mi->m_len; - flush = mi->next ? Z_NO_FLUSH : Z_SYNC_FLUSH; + flush = mi->m_next ? Z_NO_FLUSH : Z_SYNC_FLUSH; first = 1; olen = 0; @@ -261,8 +260,8 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) break; /* Done */ log_Printf(LogCCP, "DeflateInput: inflate returned %d (%s)\n", res, state->cx.msg ? state->cx.msg : ""); - mbuf_Free(mo_head); - mbuf_Free(mi); + m_freem(mo_head); + m_freem(mi); ccp_SendResetReq(&ccp->fsm); return NULL; } @@ -270,11 +269,11 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0) break; - if (state->cx.avail_in == 0 && mi && (mi = mbuf_FreeSeg(mi)) != NULL) { + if (state->cx.avail_in == 0 && mi && (mi = m_free(mi)) != NULL) { /* underflow */ state->cx.next_in = MBUF_CTOP(mi); - ilen += (state->cx.avail_in = mi->cnt); - if (mi->next == NULL) + ilen += (state->cx.avail_in = mi->m_len); + if (mi->m_next == NULL) flush = Z_SYNC_FLUSH; } @@ -290,9 +289,9 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) state->cx.avail_out = DEFLATE_CHUNK_LEN-2; first = 0; } else { - olen += (mo->cnt = DEFLATE_CHUNK_LEN); - mo->next = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_CCPIN); - mo = mo->next; + olen += (mo->m_len = DEFLATE_CHUNK_LEN); + mo->m_next = m_get(DEFLATE_CHUNK_LEN, MB_CCPIN); + mo = mo->m_next; state->cx.next_out = MBUF_CTOP(mo); state->cx.avail_out = DEFLATE_CHUNK_LEN; } @@ -300,20 +299,20 @@ DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi) } if (mi != NULL) - mbuf_Free(mi); + m_freem(mi); if (first) { log_Printf(LogCCP, "DeflateInput: Length error\n"); - mbuf_Free(mo_head); + m_freem(mo_head); ccp_SendResetReq(&ccp->fsm); return NULL; } - olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out); + olen += (mo->m_len = DEFLATE_CHUNK_LEN - state->cx.avail_out); *proto = ((u_short)wp[0] << 8) | wp[1]; - mo_head->offset += 2; - mo_head->cnt -= 2; + mo_head->m_offset += 2; + mo_head->m_len -= 2; olen -= 2; ccp->compin += ilen; @@ -350,19 +349,19 @@ DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) * Stuff an ``uncompressed data'' block header followed by the * protocol in front of the input */ - mi_head = mbuf_Alloc(7, MB_CCPOUT); - mi_head->next = mi; - len = mbuf_Length(mi); + mi_head = m_get(7, MB_CCPOUT); + mi_head->m_next = mi; + len = m_length(mi); mi = mi_head; rp = MBUF_CTOP(mi); if (proto < 0x100) { /* Compress the protocol */ rp[5] = proto & 0377; - mi->cnt = 6; + mi->m_len = 6; len++; } else { /* Don't compress the protocol */ rp[5] = proto >> 8; rp[6] = proto & 0377; - mi->cnt = 7; + mi->m_len = 7; len += 2; } rp[0] = 0x80; /* BITS: 100xxxxx */ @@ -372,7 +371,7 @@ DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) rp[4] = (~len) >> 8; state->cx.next_in = rp; - state->cx.avail_in = mi->cnt; + state->cx.avail_in = mi->m_len; state->cx.next_out = garbage; state->cx.avail_out = sizeof garbage; flush = Z_NO_FLUSH; @@ -389,18 +388,18 @@ DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) log_Printf(LogCCP, "DeflateDictSetup: avail_in %d, avail_out %d\n", state->cx.avail_in, state->cx.avail_out); ccp_SendResetReq(&ccp->fsm); - mbuf_FreeSeg(mi_head); /* lose our allocated ``head'' buf */ + m_free(mi_head); /* lose our allocated ``head'' buf */ return; } if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0) break; - if (state->cx.avail_in == 0 && mi && (mi = mi->next) != NULL) { + if (state->cx.avail_in == 0 && mi && (mi = mi->m_next) != NULL) { /* underflow */ state->cx.next_in = MBUF_CTOP(mi); - state->cx.avail_in = mi->cnt; - if (mi->next == NULL) + state->cx.avail_in = mi->m_len; + if (mi->m_next == NULL) flush = Z_SYNC_FLUSH; } @@ -429,7 +428,7 @@ DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) state->seqno++; state->uncomp_rec++; - mbuf_FreeSeg(mi_head); /* lose our allocated ``head'' buf */ + m_free(mi_head); /* lose our allocated ``head'' buf */ } static const char * diff --git a/usr.sbin/ppp/ppp/defs.c b/usr.sbin/ppp/ppp/defs.c index 835d20c9e9e..2d6e1c53909 100644 --- a/usr.sbin/ppp/ppp/defs.c +++ b/usr.sbin/ppp/ppp/defs.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: defs.c,v 1.6 1999/05/27 16:52:48 brian Exp $ + * $Id: defs.c,v 1.7 2000/01/07 03:26:53 brian Exp $ */ @@ -90,6 +90,7 @@ static struct { { PHYS_DEDICATED, "dedicated" }, { PHYS_DDIAL, "ddial" }, { PHYS_BACKGROUND, "background" }, + { PHYS_FOREGROUND, "foreground" }, { PHYS_ALL, "*" }, { 0, 0 } }; @@ -262,55 +263,52 @@ IntToSpeed(int nspeed) return B0; } -static char * -findblank(char *p, int instring) +char * +findblank(char *p, int flags) { - if (instring) { - while (*p) { - if (*p == '\\') { - memmove(p, p + 1, strlen(p)); - if (!*p) - break; - } else if (*p == '"') - return (p); - p++; - } - } else { - while (*p) { - if (issep(*p)) - return (p); - p++; - } + int instring; + + instring = 0; + while (*p) { + if (*p == '\\') { + if (flags & PARSE_REDUCE) { + memmove(p, p + 1, strlen(p)); + if (!*p) + break; + } else + p++; + } else if (*p == '"') { + memmove(p, p + 1, strlen(p)); + instring = !instring; + continue; + } else if (!instring && (issep(*p) || + (*p == '#' && !(flags & PARSE_NOHASH)))) + return p; + p++; } - return p; + return instring ? NULL : p; } int -MakeArgs(char *script, char **pvect, int maxargs) +MakeArgs(char *script, char **pvect, int maxargs, int flags) { - int nargs, nb; - int instring; + int nargs; nargs = 0; while (*script) { - nb = strspn(script, " \t"); - script += nb; + script += strspn(script, " \t"); if (*script) { - if (*script == '"') { - instring = 1; - script++; - if (*script == '\0') - break; /* Shouldn't return here. Need to NULL - * terminate below */ - } else - instring = 0; if (nargs >= maxargs - 1) break; *pvect++ = script; nargs++; - script = findblank(script, instring); - if (*script) + script = findblank(script, flags); + if (script == NULL) + return -1; + else if (*script == '#') + *script = '\0'; + else if (*script) *script++ = '\0'; } } diff --git a/usr.sbin/ppp/ppp/defs.h b/usr.sbin/ppp/ppp/defs.h index 78e95da2275..c87b42a6dec 100644 --- a/usr.sbin/ppp/ppp/defs.h +++ b/usr.sbin/ppp/ppp/defs.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: defs.h,v 1.10 1999/08/05 10:32:13 brian Exp $ + * $Id: defs.h,v 1.11 2000/01/07 03:26:53 brian Exp $ * * TODO: */ @@ -58,8 +58,7 @@ #define MIN_FSMRETRY 3 /* Minimum FSM retry frequency */ #define DEF_FSMRETRY 3 /* FSM retry frequency */ #define DEF_FSMTRIES 5 /* Default max retries */ -#define DEF_FSMAUTHTRIES 3 /* Default max auth retries */ -#define DEF_CDDELAY 1 /* Delay before checking for carrier */ +#define DEF_FSMAUTHTRIES 3 /* Default max auth retries */ #define CONFFILE "ppp.conf" #define LINKUPFILE "ppp.linkup" @@ -89,7 +88,13 @@ #define PHYS_DEDICATED 8 /* Dedicated link */ #define PHYS_DDIAL 16 /* Dial immediately, stay connected */ #define PHYS_BACKGROUND 32 /* Dial immediately, deleted when closed */ -#define PHYS_ALL 63 +#define PHYS_FOREGROUND 64 /* Pseudo mode, same as background */ +#define PHYS_ALL 127 + +/* flags passed to findblank() and MakeArgs() */ +#define PARSE_NORMAL 0 +#define PARSE_REDUCE 1 +#define PARSE_NOHASH 2 extern void randinit(void); extern ssize_t fullread(int, void *, size_t); @@ -98,4 +103,5 @@ extern int Nam2mode(const char *); extern struct in_addr GetIpAddr(const char *); extern int SpeedToInt(speed_t); extern speed_t IntToSpeed(int); -extern int MakeArgs(char *, char **, int); +extern char *findblank(char *, int); +extern int MakeArgs(char *, char **, int, int); diff --git a/usr.sbin/ppp/ppp/ether.c b/usr.sbin/ppp/ppp/ether.c new file mode 100644 index 00000000000..0fc1e053176 --- /dev/null +++ b/usr.sbin/ppp/ppp/ether.c @@ -0,0 +1,656 @@ +/*- + * Copyright (c) 1999 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. + * + * $Id: ether.c,v 1.1 2000/01/07 03:26:53 brian Exp $ + */ + +#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_pppoe.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> +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include <sys/linker.h> +#include <sys/module.h> +#endif +#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 "ipcp.h" +#include "filter.h" +#ifndef NORADIUS +#include "radius.h" +#endif +#include "bundle.h" +#include "id.h" +#include "ether.h" + + +#define PPPOE_NODE_TYPE_LEN (sizeof NG_PPPOE_NODE_TYPE - 1) /* "PPPoE" */ + +struct etherdevice { + struct device dev; /* What struct physical knows about */ + int cs; /* Control socket */ + int connected; /* Are we connected yet ? */ + int timeout; /* Seconds attempting to connect */ + char hook[sizeof TUN_NAME + 11]; /* Our socket node hook */ +}; + +#define device2ether(d) \ + ((d)->type == ETHER_DEVICE ? (struct etherdevice *)d : NULL) + +int +ether_DeviceSize(void) +{ + return sizeof(struct etherdevice); +} + +static ssize_t +ether_Write(struct physical *p, const void *v, size_t n) +{ + struct etherdevice *dev = device2ether(p->handler); + + return NgSendData(p->fd, dev->hook, v, n) == -1 ? -1 : n; +} + +static ssize_t +ether_Read(struct physical *p, void *v, size_t n) +{ + char hook[sizeof TUN_NAME + 11]; + + return NgRecvData(p->fd, v, n, hook); +} + +static int +ether_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) +{ + struct etherdevice *dev = device2ether(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 = ether_RemoveFromSet; + + return result; +} + +static void +ether_Free(struct physical *p) +{ + struct etherdevice *dev = device2ether(p->handler); + + physical_SetDescriptor(p); + if (dev->cs != -1) + close(dev->cs); + free(dev); +} + +static const char * +ether_OpenInfo(struct physical *p) +{ + struct etherdevice *dev = device2ether(p->handler); + + switch (dev->connected) { + case CARRIER_PENDING: + return "negotiating"; + case CARRIER_OK: + return "established"; + } + + return "disconnected"; +} + +static void +ether_device2iov(struct device *d, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + struct etherdevice *dev = device2ether(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)++; + + if (dev->cs >= 0) { + *auxfd = dev->cs; + (*nauxfd)++; + } +} + +static void +ether_MessageIn(struct etherdevice *dev) +{ + char msgbuf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)]; + struct ng_mesg *rep = (struct ng_mesg *)msgbuf; + struct ngpppoe_sts *sts = (struct ngpppoe_sts *)(msgbuf + sizeof *rep); + char unknown[14]; + const char *msg; + struct timeval t; + fd_set r; + + if (dev->cs < 0) + return; + + FD_ZERO(&r); + FD_SET(dev->cs, &r); + t.tv_sec = t.tv_usec = 0; + if (select(dev->cs + 1, &r, NULL, NULL, &t) <= 0) + return; + + if (NgRecvMsg(dev->cs, rep, sizeof msgbuf, NULL) < 0) + return; + + if (rep->header.version != NG_VERSION) { + log_Printf(LogWARN, "%ld: Unexpected netgraph version, expected %ld\n", + (long)rep->header.version, (long)NG_VERSION); + return; + } + + if (rep->header.typecookie != NGM_PPPOE_COOKIE) { + log_Printf(LogWARN, "%ld: Unexpected netgraph cookie, expected %ld\n", + (long)rep->header.typecookie, (long)NGM_PPPOE_COOKIE); + return; + } + + switch (rep->header.cmd) { + case NGM_PPPOE_SET_FLAG: msg = "SET_FLAG"; break; + case NGM_PPPOE_CONNECT: msg = "CONNECT"; break; + case NGM_PPPOE_LISTEN: msg = "LISTEN"; break; + case NGM_PPPOE_OFFER: msg = "OFFER"; break; + case NGM_PPPOE_SUCCESS: msg = "SUCCESS"; break; + case NGM_PPPOE_FAIL: msg = "FAIL"; break; + case NGM_PPPOE_CLOSE: msg = "CLOSE"; break; + case NGM_PPPOE_GET_STATUS: msg = "GET_STATUS"; break; + default: + snprintf(unknown, sizeof unknown, "<%d>", (int)rep->header.cmd); + msg = unknown; + break; + } + + log_Printf(LogPHASE, "Received NGM_PPPOE_%s (hook \"%s\")\n", msg, sts->hook); + + switch (rep->header.cmd) { + case NGM_PPPOE_SUCCESS: + dev->connected = CARRIER_OK; + break; + case NGM_PPPOE_FAIL: + case NGM_PPPOE_CLOSE: + dev->connected = CARRIER_LOST; + break; + } +} + +static int +ether_AwaitCarrier(struct physical *p) +{ + struct etherdevice *dev = device2ether(p->handler); + + if (dev->connected != CARRIER_OK && !dev->timeout--) + dev->connected = CARRIER_LOST; + else if (dev->connected == CARRIER_PENDING) + ether_MessageIn(dev); + + return dev->connected; +} + +static const struct device baseetherdevice = { + ETHER_DEVICE, + "ether", + { CD_REQUIRED, DEF_ETHERCDDELAY }, + ether_AwaitCarrier, + ether_RemoveFromSet, + NULL, + NULL, + NULL, + NULL, + ether_Free, + ether_Read, + ether_Write, + ether_device2iov, + NULL, + ether_OpenInfo +}; + +struct device * +ether_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + if (type == ETHER_DEVICE) { + struct etherdevice *dev = (struct etherdevice *)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, &baseetherdevice, sizeof dev->dev); + + physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF); + return &dev->dev; + } + + return NULL; +} + +static int +ether_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +{ + struct physical *p = descriptor2physical(d); + struct etherdevice *dev = device2ether(p->handler); + int result; + + if (r && dev->cs >= 0) { + FD_SET(dev->cs, r); + log_Printf(LogTIMER, "%s(ctrl): fdset(r) %d\n", p->link.name, dev->cs); + result = 1; + } else + result = 0; + + result += physical_doUpdateSet(d, r, w, e, n, 0); + + return result; +} + +static int +ether_IsSet(struct descriptor *d, const fd_set *fdset) +{ + struct physical *p = descriptor2physical(d); + struct etherdevice *dev = device2ether(p->handler); + int result; + + result = dev->cs >= 0 && FD_ISSET(dev->cs, fdset); + result += physical_IsSet(d, fdset); + + return result; +} + +static void +ether_DescriptorRead(struct descriptor *d, struct bundle *bundle, + const fd_set *fdset) +{ + struct physical *p = descriptor2physical(d); + struct etherdevice *dev = device2ether(p->handler); + + if (dev->cs >= 0 && FD_ISSET(dev->cs, fdset)) { + ether_MessageIn(dev); + if (dev->connected == CARRIER_LOST) { + log_Printf(LogPHASE, "%s: Device disconnected\n", p->link.name); + datalink_Down(p->dl, CLOSE_NORMAL); + return; + } + } + + if (physical_IsSet(d, fdset)) + physical_DescriptorRead(d, bundle, fdset); +} + +static struct device * +ether_Abandon(struct etherdevice *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; +} + +struct device * +ether_Create(struct physical *p) +{ + u_char rbuf[2048]; + struct etherdevice *dev; + struct ng_mesg *resp; + const struct hooklist *hlist; + const struct nodeinfo *ninfo; + int f; + + dev = NULL; + if (p->fd < 0 && !strncasecmp(p->name.full, NG_PPPOE_NODE_TYPE, + PPPOE_NODE_TYPE_LEN) && + p->name.full[PPPOE_NODE_TYPE_LEN] == ':') { + const struct linkinfo *nlink; + struct ngpppoe_init_data *data; + struct ngm_mkpeer mkp; + struct ngm_connect ngc; + const char *iface, *provider; + char *path, etherid[12]; + int ifacelen, providerlen; + char connectpath[sizeof dev->hook + 2]; /* .:<hook> */ + + p->fd--; /* We own the device - change fd */ + +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) + if (modfind("netgraph") == -1) { + log_Printf(LogWARN, "Netgraph is not built into the kernel\n"); + return NULL; + } + + if (modfind("ng_socket") == -1 && + ID0kldload("ng_socket") == -1) { + log_Printf(LogWARN, "kldload: ng_socket: %s\n", strerror(errno)); + return NULL; + } +#endif + + if ((dev = malloc(sizeof *dev)) == NULL) + return NULL; + + iface = p->name.full + PPPOE_NODE_TYPE_LEN + 1; + + provider = strchr(iface, ':'); + if (provider) { + ifacelen = provider - iface; + provider++; + providerlen = strlen(provider); + } else { + ifacelen = strlen(iface); + provider = ""; + providerlen = 0; + } + + /* + * We're going to do this (where tunN is our tunnel device): + * + * .---------. + * | ether | + * | <iface> | dev->cs + * `---------' | + * (orphan) p->fd | + * | | | + * | | | + * (ethernet) | | + * .---------. .-----------. + * | pppoe | | socket | + * | <iface> |(tunN)<---->(tunN)| <unnamed> | + * `--------- `-----------' + * (tunX) + * ^ + * | + * `--->(tunX) + */ + + /* 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); + return NULL; + } + + /* + * Ask for a list of hooks attached to the "ether" node. This node should + * magically exist as a way of hooking stuff onto an ethernet device + */ + path = (char *)alloca(ifacelen + 2); + sprintf(path, "%.*s:", ifacelen, iface); + if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, NGM_LISTHOOKS, + NULL, 0) < 0) { + log_Printf(LogWARN, "%s Cannot send a netgraph message: %s\n", + path, strerror(errno)); + return ether_Abandon(dev, p); + } + + /* Get our list back */ + resp = (struct ng_mesg *)rbuf; + if (NgRecvMsg(dev->cs, resp, sizeof rbuf, NULL) < 0) { + log_Printf(LogWARN, "Cannot get netgraph response: %s\n", + strerror(errno)); + return ether_Abandon(dev, p); + } + + hlist = (const struct hooklist *)resp->data; + ninfo = &hlist->nodeinfo; + + /* Make sure we've got the right type of node */ + if (strncmp(ninfo->type, NG_ETHER_NODE_TYPE, + sizeof NG_ETHER_NODE_TYPE - 1)) { + log_Printf(LogWARN, "%s Unexpected node type ``%s'' (wanted ``" + NG_ETHER_NODE_TYPE "'')\n", path, ninfo->type); + return ether_Abandon(dev, p); + } + + 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\n", nlink->ourhook, + nlink->peerhook); + + if (!strcmp(nlink->ourhook, NG_ETHER_HOOK_ORPHAN) || + !strcmp(nlink->ourhook, NG_ETHER_HOOK_DIVERT)) { + /* + * Something is using the data coming out of this ``ether'' node. + * If it's a PPPoE node, we use that node, otherwise we complain that + * someone else is using the node. + */ + if (!strcmp(nlink->nodeinfo.type, NG_PPPOE_NODE_TYPE)) + /* Use this PPPoE node ! */ + snprintf(ngc.path, sizeof ngc.path, "[%x]:", nlink->nodeinfo.id); + else { + log_Printf(LogWARN, "%s Node type ``%s'' is currently active\n", + path, nlink->nodeinfo.type); + return ether_Abandon(dev, p); + } + break; + } + } + + if (f == ninfo->hooks) { + /* + * Create a new ``PPPoE'' node connected to the ``ether'' node using + * the magic ``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); + snprintf(mkp.peerhook, sizeof mkp.peerhook, "%s", NG_PPPOE_HOOK_ETHERNET); + snprintf(etherid, sizeof etherid, "[%x]:", ninfo->id); + + log_Printf(LogDEBUG, "Creating PPPoE netgraph node %s%s -> %s\n", + etherid, mkp.ourhook, mkp.peerhook); + + if (NgSendMsg(dev->cs, etherid, NGM_GENERIC_COOKIE, + NGM_MKPEER, &mkp, sizeof mkp) < 0) { + log_Printf(LogWARN, "%s Cannot create PPPoE netgraph node: %s\n", + etherid, strerror(errno)); + return ether_Abandon(dev, p); + } + + snprintf(ngc.path, sizeof ngc.path, "%s%s", path, NG_ETHER_HOOK_ORPHAN); + } + + snprintf(dev->hook, sizeof dev->hook, "%s%d", + TUN_NAME, p->dl->bundle->unit); + + /* + * Connect the PPPoE node to our socket node. + * ngc.path has already been set up + */ + 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 PPPoE and socket netgraph " + "nodes: %s\n", strerror(errno)); + return ether_Abandon(dev, p); + } + + /* And finally, request a connection to the given provider */ + + data = (struct ngpppoe_init_data *)alloca(sizeof *data + providerlen + 1); + + snprintf(data->hook, sizeof data->hook, "%s", dev->hook); + strcpy(data->data, provider); + data->data_len = providerlen; + + snprintf(connectpath, sizeof connectpath, ".:%s", dev->hook); + log_Printf(LogDEBUG, "Sending PPPOE_CONNECT to %s\n", connectpath); + if (NgSendMsg(dev->cs, connectpath, NGM_PPPOE_COOKIE, + NGM_PPPOE_CONNECT, data, sizeof *data + providerlen) == -1) { + log_Printf(LogWARN, "``%s'': Cannot start netgraph node: %s\n", + connectpath, strerror(errno)); + return ether_Abandon(dev, p); + } + + /* Hook things up so that we monitor dev->cs */ + p->desc.UpdateSet = ether_UpdateSet; + p->desc.IsSet = ether_IsSet; + p->desc.Read = ether_DescriptorRead; + + memcpy(&dev->dev, &baseetherdevice, sizeof dev->dev); + switch (p->cfg.cd.necessity) { + case CD_VARIABLE: + dev->dev.cd.delay = p->cfg.cd.delay; + break; + case CD_REQUIRED: + dev->dev.cd = p->cfg.cd; + break; + case CD_NOTREQUIRED: + log_Printf(LogWARN, "%s: Carrier must be set, using ``set cd %d!''\n", + p->link.name, dev->dev.cd.delay); + case CD_DEFAULT: + break; + } + + dev->timeout = dev->dev.cd.delay; + dev->connected = CARRIER_PENDING; + + } else { + /* See if we're a netgraph socket */ + struct sockaddr_ng ngsock; + struct sockaddr *sock = (struct sockaddr *)&ngsock; + int sz; + + 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, &baseetherdevice, sizeof dev->dev); + dev->cs = -1; + dev->timeout = 0; + dev->connected = CARRIER_OK; + *dev->hook = '\0'; + } + } + + if (dev) { + physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF); + + /* Moan about (and fix) invalid LCP configurations */ + if (p->link.lcp.cfg.mru > 1492) { + log_Printf(LogWARN, "%s: Reducing MRU to 1492\n", p->link.name); + p->link.lcp.cfg.mru = 1492; + } + if (p->dl->bundle->cfg.mtu > 1492) { + log_Printf(LogWARN, "%s: Reducing MTU to 1492\n", p->link.name); + p->dl->bundle->cfg.mtu = 1492; + } + + return &dev->dev; + } + + return NULL; +} diff --git a/usr.sbin/ppp/ppp/ether.h b/usr.sbin/ppp/ppp/ether.h new file mode 100644 index 00000000000..76853f8295b --- /dev/null +++ b/usr.sbin/ppp/ppp/ether.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 1999 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. + * + * $Id: ether.h,v 1.1 2000/01/07 03:26:53 brian Exp $ + */ + +struct physical; +struct device; + +#define DEF_ETHERCDDELAY 5 /* Default ``set cd'' value */ + +extern struct device *ether_Create(struct physical *); +extern struct device *ether_iov2device(int, struct physical *, struct iovec *, + int *, int, int *, int *); +extern int ether_DeviceSize(void); diff --git a/usr.sbin/ppp/ppp/exec.c b/usr.sbin/ppp/ppp/exec.c index 1a5b6a1e486..1ccac2623de 100644 --- a/usr.sbin/ppp/ppp/exec.c +++ b/usr.sbin/ppp/ppp/exec.c @@ -23,16 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exec.c,v 1.9 1999/08/17 15:00:39 brian Exp $ + * $Id: exec.c,v 1.10 2000/01/07 03:26:53 brian Exp $ */ #include <sys/param.h> #include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> #include <sys/un.h> #include <errno.h> @@ -49,7 +44,6 @@ #include "defs.h" #include "mbuf.h" #include "log.h" -#include "sync.h" #include "timer.h" #include "lqr.h" #include "hdlc.h" @@ -59,29 +53,24 @@ #include "ccp.h" #include "link.h" #include "async.h" -#include "slcompress.h" -#include "iplist.h" -#include "ipcp.h" -#include "filter.h" #include "descriptor.h" #include "physical.h" #include "mp.h" -#ifndef NORADIUS -#include "radius.h" -#endif #include "chat.h" #include "command.h" -#include "bundle.h" -#include "prompt.h" #include "auth.h" #include "chap.h" #include "cbcp.h" #include "datalink.h" +#include "id.h" #include "exec.h" static struct device execdevice = { EXEC_DEVICE, "exec", + { CD_NOTREQUIRED, 0 }, + NULL, + NULL, NULL, NULL, NULL, @@ -96,7 +85,7 @@ static struct device execdevice = { struct device * exec_iov2device(int type, struct physical *p, struct iovec *iov, - int *niov, int maxiov) + int *niov, int maxiov, int *auxfd, int *nauxfd) { if (type == EXEC_DEVICE) { free(iov[(*niov)++].iov_base); @@ -113,6 +102,8 @@ exec_Create(struct physical *p) if (p->fd < 0 && *p->name.full == '!') { int fids[2]; + p->fd--; /* We own the device but maybe can't use it - change fd */ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0) log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", strerror(errno)); @@ -136,7 +127,7 @@ exec_Create(struct physical *p) case 0: close(fids[0]); timer_TermService(); - setuid(geteuid()); + setuid(ID0realuid()); switch (fork()) { case 0: @@ -151,15 +142,21 @@ exec_Create(struct physical *p) log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); + if ((argc = MakeArgs(p->name.base, argv, VECSIZE(argv), + PARSE_REDUCE|PARSE_NOHASH)) < 0) { + log_Printf(LogWARN, "Syntax error in exec command\n"); + _exit(127); + } + + command_Expand(argv, argc, (char const *const *)argv, + p->dl->bundle, 0, realpid); + dup2(fids[1], STDIN_FILENO); dup2(fids[1], STDOUT_FILENO); dup2(fids[1], STDERR_FILENO); for (i = getdtablesize(); i > STDERR_FILENO; i--) fcntl(i, F_SETFD, 1); - argc = MakeArgs(p->name.base, argv, VECSIZE(argv)); - command_Expand(argv, argc, (char const *const *)argv, - p->dl->bundle, 0, realpid); execvp(*argv, argv); printf("execvp failed: %s: %s\r\n", *argv, strerror(errno)); _exit(127); @@ -171,6 +168,8 @@ exec_Create(struct physical *p) waitpid(pid, &stat, 0); log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); + if (p->cfg.cd.necessity != CD_DEFAULT) + log_Printf(LogWARN, "Carrier settings ignored\n"); return &execdevice; } } diff --git a/usr.sbin/ppp/ppp/exec.h b/usr.sbin/ppp/ppp/exec.h index eb9a786eb8a..c4ab6ff50d4 100644 --- a/usr.sbin/ppp/ppp/exec.h +++ b/usr.sbin/ppp/ppp/exec.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exec.h,v 1.3 1999/06/05 21:36:00 brian Exp $ + * $Id: exec.h,v 1.4 2000/01/07 03:26:53 brian Exp $ */ struct physical; @@ -31,5 +31,5 @@ struct device; extern struct device *exec_Create(struct physical *); extern struct device *exec_iov2device(int, struct physical *, - struct iovec *, int *, int); + struct iovec *, int *, int, int *, int *); #define exec_DeviceSize physical_DeviceSize diff --git a/usr.sbin/ppp/ppp/filter.c b/usr.sbin/ppp/ppp/filter.c index bba5957207c..8c99ebe6030 100644 --- a/usr.sbin/ppp/ppp/filter.c +++ b/usr.sbin/ppp/ppp/filter.c @@ -17,9 +17,9 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: filter.c,v 1.10 1999/08/02 15:28:47 brian Exp $ + * $Id: filter.c,v 1.11 2000/01/07 03:26:53 brian Exp $ * - * TODO: Shoud send ICMP error message when we discard packets. + * TODO: Should send ICMP error message when we discard packets. */ #include <sys/param.h> @@ -277,6 +277,24 @@ ParseIgmp(int argc, char const * const *argv, struct filterent *tgt) return 1; } +#ifdef P_GRE +static int +ParseGRE(int argc, char const * const *argv, struct filterent *tgt) +{ + /* + * Filter currently is a catch-all. Requests are either permitted or + * dropped. + */ + if (argc != 0) { + log_Printf(LogWARN, "ParseGRE: Too many parameters\n"); + return 0; + } else + tgt->f_srcop = OP_NONE; + + return 1; +} +#endif + #ifdef P_OSPF static int ParseOspf(int argc, char const * const *argv, struct filterent *tgt) @@ -458,6 +476,11 @@ Parse(struct ipcp *ipcp, int argc, char const *const *argv, val = ParseOspf(argc, argv, &filterdata); break; #endif +#ifdef P_GRE + case P_GRE: + val = ParseGRE(argc, argv, &filterdata); + break; +#endif } log_Printf(LogDEBUG, "Parse: Src: %s\n", inet_ntoa(filterdata.f_src.ipaddr)); @@ -510,7 +533,7 @@ filter_Set(struct cmdargs const *arg) const char * filter_Action2Nam(int act) { - static const char *actname[] = { " none ", "permit ", " deny " }; + static const char * const actname[] = { " none ", "permit ", " deny " }; static char buf[8]; if (act >= 0 && act < MAXFILTERS) { @@ -595,8 +618,8 @@ filter_Show(struct cmdargs const *arg) return 0; } -static const char *protoname[] = { - "none", "tcp", "udp", "icmp", "ospf", "igmp" +static const char * const protoname[] = { + "none", "tcp", "udp", "icmp", "ospf", "igmp", "gre" }; const char * @@ -622,7 +645,7 @@ filter_Nam2Proto(int argc, char const *const *argv) return proto; } -static const char *opname[] = {"none", "eq", "gt", "unknown", "lt"}; +static const char * const opname[] = {"none", "eq", "gt", "lt"}; const char * filter_Op2Nam(int op) diff --git a/usr.sbin/ppp/ppp/filter.h b/usr.sbin/ppp/ppp/filter.h index a6d1672b392..5e9edfe9ba2 100644 --- a/usr.sbin/ppp/ppp/filter.h +++ b/usr.sbin/ppp/ppp/filter.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: filter.h,v 1.7 1999/08/02 15:28:47 brian Exp $ + * $Id: filter.h,v 1.8 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -29,6 +29,9 @@ #define P_OSPF 4 #endif #define P_IGMP 5 +#ifdef IPPROTO_GRE +#define P_GRE 6 +#endif /* Operations - f_srcop, f_dstop */ #define OP_NONE 0 diff --git a/usr.sbin/ppp/ppp/fsm.c b/usr.sbin/ppp/ppp/fsm.c index 05fafcebd2f..515a5322a62 100644 --- a/usr.sbin/ppp/ppp/fsm.c +++ b/usr.sbin/ppp/ppp/fsm.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: fsm.c,v 1.11 1999/08/10 10:50:44 brian Exp $ + * $Id: fsm.c,v 1.12 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -103,7 +103,7 @@ Code2Nam(u_int code) const char * State2Nam(u_int state) { - static const char *StateNames[] = { + static const char * const StateNames[] = { "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", }; @@ -132,7 +132,7 @@ void fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode, int maxcode, int LogLevel, struct bundle *bundle, struct link *l, const struct fsm_parent *parent, - struct fsm_callbacks *fn, const char *timer_names[3]) + struct fsm_callbacks *fn, const char * const timer_names[3]) { fp->name = name; fp->proto = proto; @@ -201,12 +201,13 @@ fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, int count, lh.code = code; lh.id = id; lh.length = htons(plen); - bp = mbuf_Alloc(plen, mtype); + bp = m_get(plen, mtype); memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); if (count) memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); log_DumpBp(LogDEBUG, "fsm_Output", bp); - link_PushPacket(fp->link, bp, fp->bundle, PRI_LINK, fp->proto); + link_PushPacket(fp->link, bp, fp->bundle, LINK_QUEUES(fp->link) - 1, + fp->proto); } static void @@ -453,12 +454,12 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) int plen, flen; int ackaction = 0; - plen = mbuf_Length(bp); + plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; if (plen < flen) { log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", fp->link->name, plen, flen); - mbuf_Free(bp); + m_freem(bp); return; } @@ -470,28 +471,28 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) * ccp_SetOpenMode() leaves us in initial if we're disabling * & denying everything. */ - bp = mbuf_Prepend(bp, lhp, sizeof *lhp, 2); + bp = m_prepend(bp, lhp, sizeof *lhp, 2); bp = proto_Prepend(bp, fp->proto, 0, 0); - bp = mbuf_Contiguous(bp); - lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->cnt); - mbuf_Free(bp); + bp = m_pullup(bp); + lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len); + m_freem(bp); return; } /* Drop through */ case ST_STARTING: log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", fp->link->name, State2Nam(fp->state)); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSED: (*fp->fn->SendTerminateAck)(fp, lhp->id); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSING: log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", fp->link->name, State2Nam(fp->state)); case ST_STOPPING: - mbuf_Free(bp); + m_freem(bp); return; case ST_OPENED: (*fp->fn->LayerDown)(fp); @@ -499,7 +500,7 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) break; } - bp = mbuf_Contiguous(bp); + bp = m_pullup(bp); dec.ackend = dec.ack; dec.nakend = dec.nak; dec.rejend = dec.rej; @@ -569,7 +570,7 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) NewState(fp, ST_REQSENT); break; } - mbuf_Free(bp); + m_freem(bp); if (dec.rejend != dec.rej && --fp->more.rejs <= 0) { log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n", @@ -623,7 +624,7 @@ FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) (*fp->parent->LayerDown)(fp->parent->object, fp); break; } - mbuf_Free(bp); + m_freem(bp); } static void @@ -633,10 +634,10 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) struct fsm_decode dec; int plen, flen; - plen = mbuf_Length(bp); + plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; if (plen < flen) { - mbuf_Free(bp); + m_freem(bp); return; } @@ -648,20 +649,20 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) case ST_STARTING: log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", fp->link->name, State2Nam(fp->state)); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSED: case ST_STOPPED: (*fp->fn->SendTerminateAck)(fp, lhp->id); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSING: case ST_STOPPING: - mbuf_Free(bp); + m_freem(bp); return; } - bp = mbuf_Contiguous(bp); + bp = m_pullup(bp); dec.ackend = dec.ack; dec.nakend = dec.nak; dec.rejend = dec.rej; @@ -687,7 +688,7 @@ FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) break; } - mbuf_Free(bp); + m_freem(bp); } static void @@ -723,7 +724,7 @@ FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) /* A delayed ST_STOPPED is now scheduled */ break; } - mbuf_Free(bp); + m_freem(bp); } static void @@ -751,7 +752,7 @@ FsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) (*fp->parent->LayerDown)(fp->parent->object, fp); break; } - mbuf_Free(bp); + m_freem(bp); } static void @@ -761,10 +762,10 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) struct fsm_decode dec; int plen, flen; - plen = mbuf_Length(bp); + plen = m_length(bp); flen = ntohs(lhp->length) - sizeof *lhp; if (plen < flen) { - mbuf_Free(bp); + m_freem(bp); return; } @@ -776,20 +777,20 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) case ST_STARTING: log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", fp->link->name, State2Nam(fp->state)); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSED: case ST_STOPPED: (*fp->fn->SendTerminateAck)(fp, lhp->id); - mbuf_Free(bp); + m_freem(bp); return; case ST_CLOSING: case ST_STOPPING: - mbuf_Free(bp); + m_freem(bp); return; } - bp = mbuf_Contiguous(bp); + bp = m_pullup(bp); dec.ackend = dec.ack; dec.nakend = dec.nak; dec.rejend = dec.rej; @@ -814,13 +815,13 @@ FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) NewState(fp, ST_REQSENT); break; } - mbuf_Free(bp); + m_freem(bp); } static void FsmRecvCodeRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { - mbuf_Free(bp); + m_freem(bp); } static void @@ -829,8 +830,8 @@ FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) struct physical *p = link2physical(fp->link); u_short proto; - if (mbuf_Length(bp) < 2) { - mbuf_Free(bp); + if (m_length(bp) < 2) { + m_freem(bp); return; } bp = mbuf_Read(bp, &proto, 2); @@ -882,7 +883,7 @@ FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) } break; } - mbuf_Free(bp); + m_freem(bp); } static void @@ -892,21 +893,25 @@ FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) u_char *cp; u_int32_t magic; - mbuf_SetType(bp, MB_ECHOIN); - if (lcp && mbuf_Length(bp) >= 4) { + bp = m_pullup(bp); + m_settype(bp, MB_ECHOIN); + + if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) { cp = MBUF_CTOP(bp); ua_ntohl(cp, &magic); if (magic != lcp->his_magic) { - log_Printf(fp->LogLevel, "%s: RecvEchoReq: Error: His magic is bad!!\n", - fp->link->name); + log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong," + " expecting 0x%08lx\n", fp->link->name, (u_long)magic, + (u_long)lcp->his_magic); /* XXX: We should send terminate request */ } if (fp->state == ST_OPENED) { ua_htonl(&lcp->want_magic, cp); /* local magic */ - fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, mbuf_Length(bp), MB_ECHOOUT); + fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, + ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT); } } - mbuf_Free(bp); + m_freem(bp); } static void @@ -915,25 +920,25 @@ FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) if (fsm2lcp(fp)) bp = lqr_RecvEcho(fp, bp); - mbuf_Free(bp); + m_freem(bp); } static void FsmRecvDiscReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { - mbuf_Free(bp); + m_freem(bp); } static void FsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { - mbuf_Free(bp); + m_freem(bp); } static void FsmRecvTimeRemain(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { - mbuf_Free(bp); + m_freem(bp); } static void @@ -941,20 +946,20 @@ FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { (*fp->fn->RecvResetReq)(fp); /* - * All sendable compressed packets are queued in the PRI_NORMAL modem - * output queue.... dump 'em to the priority queue so that they arrive - * at the peer before our ResetAck. + * All sendable compressed packets are queued in the first (lowest + * priority) modem output queue.... dump 'em to the priority queue + * so that they arrive at the peer before our ResetAck. */ link_SequenceQueue(fp->link); fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT); - mbuf_Free(bp); + m_freem(bp); } static void FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) { (*fp->fn->RecvResetAck)(fp, lhp->id); - mbuf_Free(bp); + m_freem(bp); } void @@ -964,12 +969,17 @@ fsm_Input(struct fsm *fp, struct mbuf *bp) struct fsmheader lh; const struct fsmcodedesc *codep; - len = mbuf_Length(bp); + len = m_length(bp); if (len < sizeof(struct fsmheader)) { - mbuf_Free(bp); + m_freem(bp); return; } bp = mbuf_Read(bp, &lh, sizeof lh); + + if (ntohs(lh.length) != len) + log_Printf(LogWARN, "%s: Oops: Got %d bytes but %d byte payload\n", + fp->link->name, len, (int)ntohs(lh.length)); + if (lh.code < fp->min_code || lh.code > fp->max_code || lh.code > sizeof FsmCodes / sizeof *FsmCodes) { /* @@ -978,10 +988,10 @@ fsm_Input(struct fsm *fp, struct mbuf *bp) */ static u_char id; - bp = mbuf_Prepend(bp, &lh, sizeof lh, 0); - bp = mbuf_Contiguous(bp); - fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->cnt, MB_UNKNOWN); - mbuf_Free(bp); + bp = m_prepend(bp, &lh, sizeof lh, 0); + bp = m_pullup(bp); + fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN); + m_freem(bp); return; } diff --git a/usr.sbin/ppp/ppp/fsm.h b/usr.sbin/ppp/ppp/fsm.h index 3da36a3ea58..a2bc62dbc43 100644 --- a/usr.sbin/ppp/ppp/fsm.h +++ b/usr.sbin/ppp/ppp/fsm.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: fsm.h,v 1.4 1999/06/02 15:58:40 brian Exp $ + * $Id: fsm.h,v 1.5 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -159,7 +159,7 @@ struct fsmconfig { extern void fsm_Init(struct fsm *, const char *, u_short, int, int, int, struct bundle *, struct link *, const struct fsm_parent *, - struct fsm_callbacks *, const char *[3]); + struct fsm_callbacks *, const char * const [3]); extern void fsm_Output(struct fsm *, u_int, u_int, u_char *, int, int); extern void fsm_Open(struct fsm *); extern void fsm_Up(struct fsm *); diff --git a/usr.sbin/ppp/ppp/hdlc.c b/usr.sbin/ppp/ppp/hdlc.c index 8e7685107f4..97e0366d12d 100644 --- a/usr.sbin/ppp/ppp/hdlc.c +++ b/usr.sbin/ppp/ppp/hdlc.c @@ -17,14 +17,11 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.c,v 1.9 1999/07/15 02:10:32 brian Exp $ + * $Id: hdlc.c,v 1.10 2000/01/07 03:26:54 brian Exp $ * * TODO: */ #include <sys/param.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> #include <sys/un.h> #include <stdio.h> @@ -40,15 +37,8 @@ #include "fsm.h" #include "lqr.h" #include "hdlc.h" -#include "proto.h" -#include "iplist.h" #include "throughput.h" -#include "slcompress.h" -#include "ipcp.h" -#include "ip.h" -#include "vjcomp.h" #include "auth.h" -#include "pap.h" #include "lcp.h" #include "async.h" #include "ccp.h" @@ -61,11 +51,6 @@ #include "mp.h" #include "cbcp.h" #include "datalink.h" -#include "filter.h" -#ifndef NORADIUS -#include "radius.h" -#endif -#include "bundle.h" static u_int16_t const fcstab[256] = { /* 00 */ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, @@ -130,15 +115,15 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m) int len; u_char *pos, *end; - len = mbuf_Length(m); + len = m_length(m); pos = MBUF_CTOP(m); - end = pos + m->cnt; + end = pos + m->m_len; while (len--) { fcs = (fcs >> 8) ^ fcstab[(fcs ^ *pos++) & 0xff]; if (pos == end && len) { - m = m->next; + m = m->m_next; pos = MBUF_CTOP(m); - end = pos + m->cnt; + end = pos + m->m_len; } } return (fcs); @@ -158,19 +143,19 @@ hdlc_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, u_char *cp; u_short fcs; - mbuf_SetType(bp, MB_HDLCOUT); + m_settype(bp, MB_HDLCOUT); fcs = HdlcFcsBuf(INITFCS, bp); fcs = ~fcs; - for (last = bp; last->next; last = last->next) + for (last = bp; last->m_next; last = last->m_next) ; - if (last->size - last->offset - last->cnt >= 2) { - cp = MBUF_CTOP(last) + last->cnt; - last->cnt += 2; + if (last->m_size - last->m_offset - last->m_len >= 2) { + cp = MBUF_CTOP(last) + last->m_len; + last->m_len += 2; } else { - struct mbuf *tail = mbuf_Alloc(2, MB_HDLCOUT); - last->next = tail; + struct mbuf *tail = m_get(2, MB_HDLCOUT); + last->m_next = tail; cp = MBUF_CTOP(tail); } @@ -321,31 +306,31 @@ hdlc_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, return bp; } - log_DumpBp(LogHDLC, "hdlc_Input:", bp); + log_DumpBp(LogHDLC, "hdlc_LayerPull:", bp); - fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->cnt); + fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->m_len); - log_Printf(LogDEBUG, "%s: hdlc_Input: fcs = %04x (%s)\n", + log_Printf(LogDEBUG, "%s: hdlc_LayerPull: fcs = %04x (%s)\n", p->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!"); if (fcs != GOODFCS) { p->hdlc.lqm.SaveInErrors++; p->hdlc.stats.badfcs++; - mbuf_Free(bp); + m_freem(bp); return NULL; } - p->hdlc.lqm.SaveInOctets += bp->cnt + 1; + p->hdlc.lqm.SaveInOctets += bp->m_len + 1; p->hdlc.lqm.SaveInPackets++; - len = mbuf_Length(bp); + len = m_length(bp); if (len < 4) { /* rfc1662 section 4.3 */ - mbuf_Free(bp); + m_freem(bp); bp = NULL; } - bp = mbuf_Truncate(bp, len - 2); /* discard the FCS */ - mbuf_SetType(bp, MB_HDLCIN); + bp = m_adj(bp, -2); /* discard the FCS */ + m_settype(bp, MB_HDLCIN); return bp; } diff --git a/usr.sbin/ppp/ppp/hdlc.h b/usr.sbin/ppp/ppp/hdlc.h index 274330f105c..611062c00a2 100644 --- a/usr.sbin/ppp/ppp/hdlc.h +++ b/usr.sbin/ppp/ppp/hdlc.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.h,v 1.4 1999/05/08 11:06:35 brian Exp $ + * $Id: hdlc.h,v 1.5 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -43,19 +43,6 @@ #define MAX_MTU 2048 #define MIN_MTU 296 -/* - * Output priority - */ -/* PRI_NORMAL and PRI_FAST have meaning only on the IP queue. - * All IP frames have the same priority once they are compressed. - * IP frames stay on the IP queue till they can be sent on the - * link. They are compressed at that time. -*/ -#define PRI_NORMAL 0 /* Normal priority */ -#define PRI_FAST 1 /* Fast (interractive) */ -#define PRI_LINK 1 /* Urgent (LQR packets) */ -#define PRI_MAX 1 - struct physical; struct link; struct lcp; diff --git a/usr.sbin/ppp/ppp/i4b.c b/usr.sbin/ppp/ppp/i4b.c new file mode 100644 index 00000000000..4616dcde792 --- /dev/null +++ b/usr.sbin/ppp/ppp/i4b.c @@ -0,0 +1,429 @@ +/*- + * Copyright (c) 1999 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. + * + * $Id: i4b.c,v 1.1 2000/01/07 03:26:54 brian Exp $ + */ + +#include <sys/param.h> + +#include <sys/un.h> +#if defined(__OpenBSD__) || defined(__NetBSD__) +#include <sys/ioctl.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#ifdef __FreeBSD__ +#include <machine/i4b_ioctl.h> +#include <machine/i4b_rbch_ioctl.h> +#else +#include <i4b/i4b_ioctl.h> +#include <i4b/i4b_rbch_ioctl.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <sys/uio.h> +#include <termios.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 "mp.h" +#include "chat.h" +#include "auth.h" +#include "chap.h" +#include "cbcp.h" +#include "datalink.h" +#include "main.h" +#include "i4b.h" + +#define Online(dev) ((dev)->mbits & TIOCM_CD) + +struct i4bdevice { + struct device dev; /* What struct physical knows about */ + struct pppTimer Timer; /* CD checks */ + int mbits; /* Current DCD status */ + int carrier_seconds; /* seconds before CD is *required* */ +}; + +#define device2i4b(d) ((d)->type == I4B_DEVICE ? (struct i4bdevice *)d : NULL) + +int +i4b_DeviceSize(void) +{ + return sizeof(struct i4bdevice); +} + +/* + * i4b_Timeout() watches the DCD signal and mentions it if it's status + * changes. + */ +static void +i4b_Timeout(void *data) +{ + struct physical *p = data; + struct i4bdevice *dev = device2i4b(p->handler); + int ombits, change; + + timer_Stop(&dev->Timer); + dev->Timer.load = SECTICKS; /* Once a second please */ + timer_Start(&dev->Timer); + ombits = dev->mbits; + + if (p->fd >= 0) { + if (ioctl(p->fd, TIOCMGET, &dev->mbits) < 0) { + log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name, + strerror(errno)); + datalink_Down(p->dl, CLOSE_NORMAL); + timer_Stop(&dev->Timer); + return; + } + } else + dev->mbits = 0; + + if (ombits == -1) { + /* First time looking for carrier */ + if (Online(dev)) + log_Printf(LogPHASE, "%s: %s: CD detected\n", p->link.name, p->name.full); + else if (++dev->carrier_seconds >= dev->dev.cd.delay) { + log_Printf(LogPHASE, "%s: %s: No carrier" + " (increase ``set cd'' from %d ?)\n", + p->link.name, p->name.full, dev->dev.cd.delay); + timer_Stop(&dev->Timer); + /* i4b_AwaitCarrier() will notice */ + } else { + /* Keep waiting */ + log_Printf(LogDEBUG, "%s: %s: Still no carrier (%d/%d)\n", + p->link.name, p->name.full, dev->carrier_seconds, + dev->dev.cd.delay); + dev->mbits = -1; + } + } else { + change = ombits ^ dev->mbits; + if (change & TIOCM_CD) { + if (dev->mbits & TIOCM_CD) + log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name); + else { + log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name); + log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name); + datalink_Down(p->dl, CLOSE_NORMAL); + timer_Stop(&dev->Timer); + } + } else + log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name, + Online(dev) ? "on" : "off"); + } +} + +static void +i4b_StartTimer(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + + timer_Stop(&dev->Timer); + dev->Timer.load = SECTICKS; + dev->Timer.func = i4b_Timeout; + dev->Timer.name = "i4b CD"; + dev->Timer.arg = p; + log_Printf(LogDEBUG, "%s: Using i4b_Timeout [%p]\n", + p->link.name, i4b_Timeout); + timer_Start(&dev->Timer); +} + +static int +i4b_AwaitCarrier(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + + if (dev->mbits == -1) { + if (dev->Timer.state == TIMER_STOPPED) { + dev->carrier_seconds = 0; + i4b_StartTimer(p); + } + return CARRIER_PENDING; /* Not yet ! */ + } + + return Online(dev) ? CARRIER_OK : CARRIER_LOST; +} + +static int +i4b_Raw(struct physical *p) +{ + int oldflag; + + log_Printf(LogDEBUG, "%s: Entering i4b_Raw\n", p->link.name); + + oldflag = fcntl(p->fd, F_GETFL, 0); + if (oldflag < 0) + return 0; + fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK); + + return 1; +} + +static void +i4b_Offline(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + + if (p->fd >= 0) { + timer_Stop(&dev->Timer); + if (Online(dev)) { + int dummy; + + dummy = 1; + ioctl(p->fd, TIOCCDTR, &dummy); + } + } +} + +static void +i4b_Cooked(struct physical *p) +{ + int oldflag; + + i4b_Offline(p); /* In case of emergency close()s */ + + if ((oldflag = fcntl(p->fd, F_GETFL, 0)) != -1) + fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); +} + +static void +i4b_StopTimer(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + + timer_Stop(&dev->Timer); +} + +static void +i4b_Free(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + + i4b_Offline(p); /* In case of emergency close()s */ + free(dev); +} + +static int +i4b_Speed(struct physical *p) +{ + struct termios ios; + + if (tcgetattr(p->fd, &ios) == -1) + return 0; + + return SpeedToInt(cfgetispeed(&ios)); +} + +static const char * +i4b_OpenInfo(struct physical *p) +{ + struct i4bdevice *dev = device2i4b(p->handler); + static char buf[26]; + + if (Online(dev)) + snprintf(buf, sizeof buf, "carrier took %ds", dev->carrier_seconds); + else + *buf = '\0'; + + return buf; +} + +static void +i4b_device2iov(struct device *d, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + struct i4bdevice *dev = device2i4b(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)++; + + if (dev->Timer.state != TIMER_STOPPED) { + timer_Stop(&dev->Timer); + dev->Timer.state = TIMER_RUNNING; + } +} + +static struct device basei4bdevice = { + I4B_DEVICE, + "i4b", + { CD_REQUIRED, DEF_I4BCDDELAY }, + i4b_AwaitCarrier, + NULL, + i4b_Raw, + i4b_Offline, + i4b_Cooked, + i4b_StopTimer, + i4b_Free, + NULL, + NULL, + i4b_device2iov, + i4b_Speed, + i4b_OpenInfo +}; + +struct device * +i4b_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, + int maxiov, int *auxfd, int *nauxfd) +{ + if (type == I4B_DEVICE) { + struct i4bdevice *dev = (struct i4bdevice *)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); + } + + /* Refresh function pointers etc */ + memcpy(&dev->dev, &basei4bdevice, sizeof dev->dev); + + physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); + if (dev->Timer.state != TIMER_STOPPED) { + dev->Timer.state = TIMER_STOPPED; + p->handler = &dev->dev; /* For the benefit of StartTimer */ + i4b_StartTimer(p); + } + return &dev->dev; + } + + return NULL; +} + +struct device * +i4b_Create(struct physical *p) +{ + struct i4bdevice *dev; + int oldflag, dial; + msg_vr_req_t req; + telno_t number; + + if (p->fd < 0 || ioctl(p->fd, I4B_RBCH_VR_REQ, &req)) + /* Don't want this */ + return NULL; + + /* + * We don't bother validating the version.... all versions of i4b that + * support I4B_RBCH_VR_REQ are fair game :-) + */ + + if (*p->name.full == '\0') { + physical_SetDevice(p, ttyname(p->fd)); + log_Printf(LogDEBUG, "%s: Input is an i4b version %d.%d.%d isdn " + "device (%s)\n", p->link.name, req.version, req.release, + req.step, p->name.full); + dial = 0; + } else { + log_Printf(LogDEBUG, "%s: Opened %s (i4b version %d.%d.%d)\n", + p->link.name, p->name.full, req.version, req.release, req.step); + dial = 1; + } + + /* We're gonna return an i4bdevice (unless something goes horribly wrong) */ + + if ((dev = malloc(sizeof *dev)) == NULL) { + /* Complete failure - parent doesn't continue trying to ``create'' */ + close(p->fd); + p->fd = -1; + return NULL; + } + + memcpy(&dev->dev, &basei4bdevice, sizeof dev->dev); + memset(&dev->Timer, '\0', sizeof dev->Timer); + dev->mbits = -1; + + switch (p->cfg.cd.necessity) { + case CD_VARIABLE: + dev->dev.cd.delay = p->cfg.cd.delay; + break; + case CD_REQUIRED: + dev->dev.cd = p->cfg.cd; + break; + case CD_NOTREQUIRED: + log_Printf(LogWARN, "%s: Carrier must be set, using ``set cd %d!''\n", + p->link.name, dev->dev.cd.delay); + case CD_DEFAULT: + break; + } + + oldflag = fcntl(p->fd, F_GETFL, 0); + if (oldflag < 0) { + /* Complete failure - parent doesn't continue trying to ``create'' */ + + log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n", + p->link.name, strerror(errno)); + i4b_Cooked(p); + close(p->fd); + p->fd = -1; + free(dev); + return NULL; + } else + fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); + + if (dial) { + strncpy(number, datalink_ChoosePhoneNumber(p->dl), sizeof number - 1); + number[sizeof number - 1] = '\0'; + if (number[0] == '\0') + dial = 0; + } + if (dial && ioctl(p->fd, I4B_RBCH_DIALOUT, number) == -1) { + /* Complete failure - parent doesn't continue trying to ``create'' */ + + log_Printf(LogWARN, "%s: ioctl(I4B_RBCH_DIALOUT): %s\n", + p->link.name, strerror(errno)); + i4b_Cooked(p); + close(p->fd); + p->fd = -1; + free(dev); + return NULL; + } + + physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNC); + + return &dev->dev; +} diff --git a/usr.sbin/ppp/ppp/i4b.h b/usr.sbin/ppp/ppp/i4b.h new file mode 100644 index 00000000000..709e908b7a1 --- /dev/null +++ b/usr.sbin/ppp/ppp/i4b.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 1999 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. + * + * $Id: i4b.h,v 1.1 2000/01/07 03:26:54 brian Exp $ + */ + +struct physical; +struct device; + +#define DEF_I4BCDDELAY 6 /* Default ``set cd'' value */ + +extern struct device *i4b_Create(struct physical *); +extern struct device *i4b_iov2device(int, struct physical *, + struct iovec *, int *, int, int *, int *); +extern int i4b_DeviceSize(void); diff --git a/usr.sbin/ppp/ppp/id.c b/usr.sbin/ppp/ppp/id.c index d77c7554ec2..460b0cefa0e 100644 --- a/usr.sbin/ppp/ppp/id.c +++ b/usr.sbin/ppp/ppp/id.c @@ -23,20 +23,27 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: id.c,v 1.2 1999/02/06 03:22:37 brian Exp $ + * $Id: id.c,v 1.3 2000/01/07 03:26:54 brian Exp $ */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/ioctl.h> #include <fcntl.h> +#ifndef NONETGRAPH +#include <netgraph.h> +#endif #include <signal.h> #include <stdarg.h> #include <stdio.h> +#include <stdlib.h> /* setproctitle() under OpenBSD (+NetBSD ?)*/ #include <string.h> #include <sysexits.h> +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include <sys/linker.h> +#endif #include <unistd.h> #ifdef __OpenBSD__ #include <util.h> @@ -211,7 +218,7 @@ ID0login(struct utmp *ut) } void -ID0logout(const char *device) +ID0logout(const char *device, int nologout) { struct utmp ut; @@ -219,7 +226,7 @@ ID0logout(const char *device) ut.ut_line[sizeof ut.ut_line - 1] = '\0'; ID0set0(); - if (logout(ut.ut_line)) { + if (nologout || logout(ut.ut_line)) { log_Printf(LogID0, "logout(\"%s\")\n", ut.ut_line); logwtmp(ut.ut_line, "", ""); log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut.ut_line); @@ -265,3 +272,46 @@ ID0kill(pid_t pid, int sig) ID0setuser(); return result; } + +void +ID0setproctitle(const char *title) +{ + ID0set0(); + if (title == NULL) { + setproctitle(NULL); + log_Printf(LogID0, "setproctitle(NULL)\n"); + } else { + setproctitle("%s", title); + log_Printf(LogID0, "setproctitle(\"%%s\", \"%s\")\n", title); + } + ID0setuser(); +} + +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +int +ID0kldload(const char *dev) +{ + int result; + + ID0set0(); + result = kldload(dev); + log_Printf(LogID0, "%d = kldload(\"%s\")\n", result, dev); + ID0setuser(); + return result; +} +#endif + +#ifndef NONETGRAPH +int +ID0NgMkSockNode(const char *name, int *cs, int *ds) +{ + int result; + + ID0set0(); + result = NgMkSockNode(name, cs, ds); + log_Printf(LogID0, "%d = NgMkSockNode(\"%s\", &cs, &ds)\n", + result, name ? name : ""); + ID0setuser(); + return result; +} +#endif diff --git a/usr.sbin/ppp/ppp/id.h b/usr.sbin/ppp/ppp/id.h index 728caf430c5..c2e06c61c29 100644 --- a/usr.sbin/ppp/ppp/id.h +++ b/usr.sbin/ppp/ppp/id.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: id.h,v 1.2 1999/02/06 03:22:37 brian Exp $ + * $Id: id.h,v 1.3 2000/01/07 03:26:54 brian Exp $ */ struct utmp; @@ -41,7 +41,14 @@ extern int ID0uu_lock(const char *); extern int ID0uu_lock_txfr(const char *, pid_t); extern int ID0uu_unlock(const char *); extern void ID0login(struct utmp *); -extern void ID0logout(const char *); +extern void ID0logout(const char *, int); extern int ID0bind_un(int, const struct sockaddr_un *); extern int ID0connect_un(int, const struct sockaddr_un *); extern int ID0kill(pid_t, int); +extern void ID0setproctitle(const char *); +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +extern int ID0kldload(const char *); +#endif +#ifndef NONETGRAPH +extern int ID0NgMkSockNode(const char *, int *, int *); +#endif diff --git a/usr.sbin/ppp/ppp/iface.c b/usr.sbin/ppp/ppp/iface.c index 6cd4f28cea0..c55360303a8 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. * - * $Id: iface.c,v 1.6 1999/05/31 23:57:37 brian Exp $ + * $Id: iface.c,v 1.7 2000/01/07 03:26:54 brian Exp $ */ #include <sys/param.h> @@ -118,18 +118,20 @@ iface_Create(const char *name) mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { - fprintf(stderr, "clean: sysctl: estimate: %s\n", + fprintf(stderr, "iface_Create: sysctl: estimate: %s\n", strerror(errno)); close(s); return NULL; } if ((buf = (char *)malloc(needed)) == NULL) { + fprintf(stderr, "iface_Create: malloc failed: %s\n", strerror(errno)); close(s); return NULL; } if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + fprintf(stderr, "iface_Create: sysctl: %s\n", strerror(errno)); free(buf); close(s); return NULL; @@ -417,7 +419,7 @@ iface_ChangeFlags(struct iface *iface, int flags, int how) s = ID0socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { - log_Printf(LogERROR, "iface_ClearFlags: socket: %s\n", strerror(errno)); + log_Printf(LogERROR, "iface_ChangeFlags: socket: %s\n", strerror(errno)); return 0; } @@ -425,7 +427,7 @@ iface_ChangeFlags(struct iface *iface, int flags, int how) strncpy(ifrq.ifr_name, iface->name, sizeof ifrq.ifr_name - 1); ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { - log_Printf(LogERROR, "iface_ClearFlags: ioctl(SIOCGIFFLAGS): %s\n", + log_Printf(LogERROR, "iface_ChangeFlags: ioctl(SIOCGIFFLAGS): %s\n", strerror(errno)); close(s); return 0; @@ -437,7 +439,7 @@ iface_ChangeFlags(struct iface *iface, int flags, int how) ifrq.ifr_flags &= ~flags; if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) { - log_Printf(LogERROR, "iface_ClearFlags: ioctl(SIOCSIFFLAGS): %s\n", + log_Printf(LogERROR, "iface_ChangeFlags: ioctl(SIOCSIFFLAGS): %s\n", strerror(errno)); close(s); return 0; diff --git a/usr.sbin/ppp/ppp/ip.c b/usr.sbin/ppp/ppp/ip.c index 9c6a0a40189..9c72b2e4eef 100644 --- a/usr.sbin/ppp/ppp/ip.c +++ b/usr.sbin/ppp/ppp/ip.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ip.c,v 1.17 1999/08/02 15:28:47 brian Exp $ + * $Id: ip.c,v 1.18 2000/01/07 03:26:54 brian Exp $ * * TODO: * o Return ICMP message for filterd packet @@ -38,7 +38,6 @@ #include <errno.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <termios.h> #include <unistd.h> @@ -66,19 +65,13 @@ #include "radius.h" #endif #include "bundle.h" -#include "vjcomp.h" #include "tun.h" #include "ip.h" -static const u_short interactive_ports[32] = { - 544, 513, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80, 81, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 543, +static const char * const TcpFlags[] = { + "FIN", "SYN", "RST", "PSH", "ACK", "URG" }; -#define INTERACTIVE(p) (interactive_ports[(p) & 0x1F] == (p)) - -static const char *TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" }; - static __inline int PortMatch(int op, u_short pport, u_short rport) { @@ -130,7 +123,7 @@ FilterCheck(const struct ip *pip, const struct filter *filter) if (len < (24 >> 3)) /* don't allow fragment to over-write header */ return (1); /* permit fragments on in and out filter */ - return (filter->fragok); + return (!filter->fragok); } cproto = gotinfo = estab = syn = finrst = didname = 0; @@ -179,6 +172,15 @@ FilterCheck(const struct ip *pip, const struct filter *filter) estab = syn = finrst = -1; sport = ntohs(0); break; +#ifdef IPPROTO_GRE + case IPPROTO_GRE: + cproto = P_GRE; + if (datalen < 2) /* GRE uses 2-octet+ messages */ + return (1); + estab = syn = finrst = -1; + sport = ntohs(0); + break; +#endif #ifdef IPPROTO_OSPFIGP case IPPROTO_OSPFIGP: cproto = P_OSPF; @@ -301,10 +303,10 @@ IcmpError(struct ip *pip, int code) struct mbuf *bp; if (pip->ip_p != IPPROTO_ICMP) { - bp = mbuf_Alloc(cnt, MB_IPIN); - memcpy(MBUF_CTOP(bp), ptr, cnt); + bp = m_get(m_len, MB_IPIN); + memcpy(MBUF_CTOP(bp), ptr, m_len); vj_SendFrame(bp); - ipcp_AddOutOctets(cnt); + ipcp_AddOutOctets(m_len); } } #endif @@ -321,7 +323,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) struct icmp *icmph; char *ptop; int mask, len, n; - int pri = PRI_NORMAL; + int pri = 0; int logit, loglen; char logbuf[200]; @@ -348,9 +350,18 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) loglen += strlen(logbuf + loglen); } break; + case IPPROTO_UDP: + uh = (struct udphdr *) ptop; + if (pip->ip_tos == IPTOS_LOWDELAY) + pri++; + + if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 && + ipcp_IsUrgentUdpPort(&bundle->ncp.ipcp, ntohs(uh->uh_sport), + ntohs(uh->uh_dport))) + pri++; + if (logit && loglen < sizeof logbuf) { - uh = (struct udphdr *) ptop; snprintf(logbuf + loglen, sizeof logbuf - loglen, "UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); loglen += strlen(logbuf + loglen); @@ -359,6 +370,20 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) loglen += strlen(logbuf + loglen); } break; + +#ifdef IPPROTO_GRE + case IPPROTO_GRE: + if (logit && loglen < sizeof logbuf) { + snprintf(logbuf + loglen, sizeof logbuf - loglen, + "GRE: %s ---> ", inet_ntoa(pip->ip_src)); + loglen += strlen(logbuf + loglen); + snprintf(logbuf + loglen, sizeof logbuf - loglen, + "%s", inet_ntoa(pip->ip_dst)); + loglen += strlen(logbuf + loglen); + } + break; +#endif + #ifdef IPPROTO_OSPFIGP case IPPROTO_OSPFIGP: if (logit && loglen < sizeof logbuf) { @@ -371,6 +396,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) } break; #endif + case IPPROTO_IPIP: if (logit && loglen < sizeof logbuf) { uh = (struct udphdr *) ptop; @@ -382,6 +408,7 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) loglen += strlen(logbuf + loglen); } break; + case IPPROTO_IGMP: if (logit && loglen < sizeof logbuf) { uh = (struct udphdr *) ptop; @@ -393,14 +420,17 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) loglen += strlen(logbuf + loglen); } break; + case IPPROTO_TCP: th = (struct tcphdr *) ptop; if (pip->ip_tos == IPTOS_LOWDELAY) - pri = PRI_FAST; - else if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { - if (INTERACTIVE(ntohs(th->th_sport)) || INTERACTIVE(ntohs(th->th_dport))) - pri = PRI_FAST; - } + pri++; + + if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 && + ipcp_IsUrgentTcpPort(&bundle->ncp.ipcp, ntohs(th->th_sport), + ntohs(th->th_dport))) + pri++; + if (logit && loglen < sizeof logbuf) { len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - (th->th_off << 2); snprintf(logbuf + loglen, sizeof logbuf - loglen, @@ -465,17 +495,17 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (bundle->ncp.ipcp.fsm.state != ST_OPENED) { log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } - mbuf_SetType(bp, MB_IPIN); + m_settype(bp, MB_IPIN); tun_fill_header(tun, AF_INET); - nb = mbuf_Length(bp); + nb = m_length(bp); if (nb > sizeof tun.data) { log_Printf(LogWARN, "ip_Input: %s: Packet too large (got %d, max %d)\n", l->name, nb, (int)(sizeof tun.data)); - mbuf_Free(bp); + m_freem(bp); return NULL; } mbuf_Read(bp, tun.data, nb); @@ -507,20 +537,20 @@ ip_Enqueue(struct ipcp *ipcp, int pri, char *ptr, int count) { struct mbuf *bp; - if (pri < 0 || pri > sizeof ipcp->Queue / sizeof ipcp->Queue[0]) + if (pri < 0 || pri >= IPCP_QUEUES(ipcp)) log_Printf(LogERROR, "Can't store in ip queue %d\n", pri); else { /* * We allocate an extra 6 bytes, four at the front and two at the end. * This is an optimisation so that we need to do less work in - * mbuf_Prepend() in acf_LayerPush() and proto_LayerPush() and + * m_prepend() in acf_LayerPush() and proto_LayerPush() and * appending in hdlc_LayerPush(). */ - bp = mbuf_Alloc(count + 6, MB_IPOUT); - bp->offset += 4; - bp->cnt -= 6; + bp = m_get(count + 6, MB_IPOUT); + bp->m_offset += 4; + bp->m_len -= 6; memcpy(MBUF_CTOP(bp), ptr, count); - mbuf_Enqueue(&ipcp->Queue[pri], bp); + m_enqueue(ipcp->Queue + pri, bp); } } @@ -529,19 +559,20 @@ ip_DeleteQueue(struct ipcp *ipcp) { struct mqueue *queue; - for (queue = ipcp->Queue; queue < ipcp->Queue + PRI_MAX; queue++) + for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++) while (queue->top) - mbuf_Free(mbuf_Dequeue(queue)); + m_freem(m_dequeue(queue)); } -int +size_t ip_QueueLen(struct ipcp *ipcp) { struct mqueue *queue; - int result = 0; + size_t result; - for (queue = ipcp->Queue; queue < ipcp->Queue + PRI_MAX; queue++) - result += queue->qlen; + result = 0; + for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++) + result += queue->len; return result; } @@ -553,22 +584,24 @@ ip_PushPacket(struct link *l, struct bundle *bundle) struct mqueue *queue; struct mbuf *bp; struct ip *pip; - int cnt; + int m_len; if (ipcp->fsm.state != ST_OPENED) return 0; - for (queue = &ipcp->Queue[PRI_FAST]; queue >= ipcp->Queue; queue--) + queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1; + do { if (queue->top) { - bp = mbuf_Contiguous(mbuf_Dequeue(queue)); - cnt = mbuf_Length(bp); + bp = m_pullup(m_dequeue(queue)); + m_len = m_length(bp); pip = (struct ip *)MBUF_CTOP(bp); if (!FilterCheck(pip, &bundle->filter.alive)) bundle_StartIdleTimer(bundle); - link_PushPacket(l, bp, bundle, PRI_NORMAL, PROTO_IP); - ipcp_AddOutOctets(ipcp, cnt); + link_PushPacket(l, bp, bundle, 0, PROTO_IP); + ipcp_AddOutOctets(ipcp, m_len); return 1; } + } while (queue-- != ipcp->Queue); return 0; } diff --git a/usr.sbin/ppp/ppp/ip.h b/usr.sbin/ppp/ppp/ip.h index 9168b8aa5e5..2b5f054839b 100644 --- a/usr.sbin/ppp/ppp/ip.h +++ b/usr.sbin/ppp/ppp/ip.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ip.h,v 1.3 1999/05/08 11:06:35 brian Exp $ + * $Id: ip.h,v 1.4 2000/01/07 03:26:54 brian Exp $ * */ @@ -31,4 +31,4 @@ extern int PacketCheck(struct bundle *, char *, int, struct filter *); extern void ip_Enqueue(struct ipcp *, int, char *, int); extern struct mbuf *ip_Input(struct bundle *, struct link *, struct mbuf *); extern void ip_DeleteQueue(struct ipcp *); -extern int ip_QueueLen(struct ipcp *); +extern size_t ip_QueueLen(struct ipcp *); diff --git a/usr.sbin/ppp/ppp/ipcp.c b/usr.sbin/ppp/ppp/ipcp.c index 87b954a81ec..198203e31cf 100644 --- a/usr.sbin/ppp/ppp/ipcp.c +++ b/usr.sbin/ppp/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.18 1999/08/05 10:32:14 brian Exp $ + * $Id: ipcp.c,v 1.19 2000/01/07 03:26:54 brian Exp $ * * TODO: * o Support IPADDRS properly @@ -41,7 +41,7 @@ #include <termios.h> #include <unistd.h> -#ifndef NOALIAS +#ifndef NONAT #ifdef __FreeBSD__ #include <alias.h> #else @@ -82,12 +82,101 @@ #include "prompt.h" #include "route.h" #include "iface.h" +#include "ip.h" #undef REJECTED #define REJECTED(p, x) ((p)->peer_reject & (1<<(x))) #define issep(ch) ((ch) == ' ' || (ch) == '\t') #define isip(ch) (((ch) >= '0' && (ch) <= '9') || (ch) == '.') +static u_short default_urgent_tcp_ports[] = { + 21, /* ftp */ + 22, /* ssh */ + 23, /* telnet */ + 513, /* login */ + 514, /* shell */ + 543, /* klogin */ + 544 /* kshell */ +}; + +static u_short default_urgent_udp_ports[] = { }; + +#define NDEFTCPPORTS \ + (sizeof default_urgent_tcp_ports / sizeof default_urgent_tcp_ports[0]) +#define NDEFUDPPORTS \ + (sizeof default_urgent_udp_ports / sizeof default_urgent_udp_ports[0]) + +int +ipcp_IsUrgentPort(struct port_range *range, u_short src, u_short dst) +{ + int f; + + for (f = 0; f < range->nports; f++) + if (range->port[f] == src || range->port[f] == dst) + return 1; + + return 0; +} + +void +ipcp_AddUrgentPort(struct port_range *range, u_short port) +{ + u_short *newport; + int p; + + if (range->nports == range->maxports) { + range->maxports += 10; + newport = (u_short *)realloc(range->port, + range->maxports * sizeof(u_short)); + if (newport == NULL) { + log_Printf(LogERROR, "ipcp_AddUrgentPort: realloc: %s\n", + strerror(errno)); + range->maxports -= 10; + return; + } + range->port = newport; + } + + for (p = 0; p < range->nports; p++) + if (range->port[p] == port) { + log_Printf(LogWARN, "%u: Port already set to urgent\n", port); + break; + } else if (range->port[p] > port) { + memmove(range->port + p + 1, range->port + p, + (range->nports - p) * sizeof(u_short)); + range->port[p] = port; + range->nports++; + break; + } + + if (p == range->nports) + range->port[range->nports++] = port; +} + +void +ipcp_RemoveUrgentPort(struct port_range *range, u_short port) +{ + int p; + + for (p = 0; p < range->nports; p++) + if (range->port[p] == port) { + if (p != range->nports - 1) + memmove(range->port + p, range->port + p + 1, + (range->nports - p - 1) * sizeof(u_short)); + range->nports--; + return; + } + + if (p == range->nports) + log_Printf(LogWARN, "%u: Port not set to urgent\n", port); +} + +void +ipcp_ClearUrgentPorts(struct port_range *range) +{ + range->nports = 0; +} + struct compreq { u_short proto; u_char slots; @@ -119,7 +208,7 @@ static struct fsm_callbacks ipcp_Callbacks = { fsm_NullRecvResetAck }; -static const char *cftypes[] = { +static const char * const cftypes[] = { /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ "???", "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ @@ -129,7 +218,7 @@ static const char *cftypes[] = { #define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) -static const char *cftypes128[] = { +static const char * const cftypes128[] = { /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ "???", "PRIDNS", /* 129: Primary DNS Server Address */ @@ -268,6 +357,7 @@ int ipcp_Show(struct cmdargs const *arg) { struct ipcp *ipcp = &arg->bundle->ncp.ipcp; + int p; prompt_Printf(arg->prompt, "%s [%s]\n", ipcp->fsm.name, State2Nam(ipcp->fsm.state)); @@ -276,6 +366,7 @@ ipcp_Show(struct cmdargs const *arg) inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); prompt_Printf(arg->prompt, " My side: %s, %s\n", inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); + prompt_Printf(arg->prompt, " Queued packets: %d\n", ip_QueueLen(ipcp)); } if (ipcp->route) { @@ -315,7 +406,27 @@ ipcp_Show(struct cmdargs const *arg) inet_ntoa(ipcp->cfg.ns.nbns[0])); prompt_Printf(arg->prompt, "%s\n", inet_ntoa(ipcp->cfg.ns.nbns[1])); - prompt_Printf(arg->prompt, "\n"); + prompt_Printf(arg->prompt, " Urgent ports\n"); + prompt_Printf(arg->prompt, " TCP: "); + if (ipcp->cfg.urgent.tcp.nports == 0) + prompt_Printf(arg->prompt, "none"); + else + for (p = 0; p < ipcp->cfg.urgent.tcp.nports; p++) { + if (p) + prompt_Printf(arg->prompt, ", "); + prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.tcp.port[p]); + } + prompt_Printf(arg->prompt, "\n UDP: "); + if (ipcp->cfg.urgent.udp.nports == 0) + prompt_Printf(arg->prompt, "none"); + else + for (p = 0; p < ipcp->cfg.urgent.udp.nports; p++) { + if (p) + prompt_Printf(arg->prompt, ", "); + prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.udp.port[p]); + } + + prompt_Printf(arg->prompt, "\n\n"); throughput_disp(&ipcp->throughput, arg->prompt); return 0; @@ -352,7 +463,7 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l, { struct hostent *hp; char name[MAXHOSTNAMELEN]; - static const char *timer_names[] = + static const char * const timer_names[] = {"IPCP restart", "IPCP openmode", "IPCP stopped"}; fsm_Init(&ipcp->fsm, "IPCP", PROTO_IPCP, 1, IPCP_MAXCODE, LogIPCP, @@ -378,6 +489,16 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l, ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY; ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY; + ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = NDEFTCPPORTS; + ipcp->cfg.urgent.tcp.port = (u_short *)malloc(NDEFTCPPORTS * sizeof(u_short)); + memcpy(ipcp->cfg.urgent.tcp.port, default_urgent_tcp_ports, + NDEFTCPPORTS * sizeof(u_short)); + + ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = NDEFUDPPORTS; + ipcp->cfg.urgent.udp.port = (u_short *)malloc(NDEFUDPPORTS * sizeof(u_short)); + memcpy(ipcp->cfg.urgent.udp.port, default_urgent_udp_ports, + NDEFUDPPORTS * sizeof(u_short)); + ipcp->cfg.fsm.timeout = DEF_FSMRETRY; ipcp->cfg.fsm.maxreq = DEF_FSMTRIES; ipcp->cfg.fsm.maxtrm = DEF_FSMTRIES; @@ -391,6 +512,21 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l, } void +ipcp_Destroy(struct ipcp *ipcp) +{ + if (ipcp->cfg.urgent.tcp.maxports) { + ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = 0; + free(ipcp->cfg.urgent.tcp.port); + ipcp->cfg.urgent.tcp.port = NULL; + } + if (ipcp->cfg.urgent.udp.maxports) { + ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = 0; + free(ipcp->cfg.urgent.udp.port); + ipcp->cfg.urgent.udp.port = NULL; + } +} + +void ipcp_SetLink(struct ipcp *ipcp, struct link *l) { ipcp->fsm.link = l; @@ -745,8 +881,8 @@ ipcp_InterfaceUp(struct ipcp *ipcp) return 0; } -#ifndef NOALIAS - if (ipcp->fsm.bundle->AliasEnabled) +#ifndef NONAT + if (ipcp->fsm.bundle->NatEnabled) PacketAliasSetAddress(ipcp->my_ip); #endif @@ -1148,14 +1284,14 @@ extern struct mbuf * ipcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { /* Got PROTO_IPCP from link */ - mbuf_SetType(bp, MB_IPCPIN); + m_settype(bp, MB_IPCPIN); if (bundle_Phase(bundle) == PHASE_NETWORK) fsm_Input(&bundle->ncp.ipcp.fsm, bp); else { if (bundle_Phase(bundle) < PHASE_NETWORK) log_Printf(LogIPCP, "%s: Error: Unexpected IPCP in phase %s (ignored)\n", l->name, bundle_PhaseName(bundle)); - mbuf_Free(bp); + m_freem(bp); } return NULL; } diff --git a/usr.sbin/ppp/ppp/ipcp.h b/usr.sbin/ppp/ppp/ipcp.h index 455bdb6cd44..1beee7e966d 100644 --- a/usr.sbin/ppp/ppp/ipcp.h +++ b/usr.sbin/ppp/ppp/ipcp.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.h,v 1.6 1999/05/08 11:06:36 brian Exp $ + * $Id: ipcp.h,v 1.7 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -42,6 +42,12 @@ struct in_range { int width; }; +struct port_range { + unsigned nports; /* How many ports */ + unsigned maxports; /* How many allocated (malloc) ports */ + u_short *port; /* The actual ports */ +}; + struct ipcp { struct fsm fsm; /* The finite state machine */ @@ -69,6 +75,10 @@ struct ipcp { struct in_addr nbns[2]; /* NetBIOS NS addresses offered */ } ns; + struct { + struct port_range tcp, udp; /* The range of urgent ports */ + } urgent; + struct fsm_retry fsm; /* How often/frequently to resend requests */ } cfg; @@ -93,10 +103,11 @@ struct ipcp { u_int32_t my_reject; /* Request codes I have rejected */ struct pppThroughput throughput; /* throughput statistics */ - struct mqueue Queue[PRI_FAST + 1]; /* Output packet queues */ + struct mqueue Queue[3]; /* Output packet queues */ }; #define fsm2ipcp(fp) (fp->proto == PROTO_IPCP ? (struct ipcp *)fp : NULL) +#define IPCP_QUEUES(ipcp) (sizeof ipcp->Queue / sizeof ipcp->Queue[0]) struct bundle; struct link; @@ -104,6 +115,7 @@ struct cmdargs; extern void ipcp_Init(struct ipcp *, struct bundle *, struct link *, const struct fsm_parent *); +extern void ipcp_Destroy(struct ipcp *); extern void ipcp_Setup(struct ipcp *, u_int32_t); extern void ipcp_SetLink(struct ipcp *, struct link *); @@ -116,4 +128,25 @@ extern int ipcp_UseHisaddr(struct bundle *, const char *, int); extern int ipcp_vjset(struct cmdargs const *); extern void ipcp_CleanInterface(struct ipcp *); extern int ipcp_InterfaceUp(struct ipcp *); +extern int ipcp_IsUrgentPort(struct port_range *, u_short, u_short); +extern void ipcp_AddUrgentPort(struct port_range *, u_short); +extern void ipcp_RemoveUrgentPort(struct port_range *, u_short); +extern void ipcp_ClearUrgentPorts(struct port_range *); extern struct in_addr addr2mask(struct in_addr); + +#define ipcp_IsUrgentTcpPort(ipcp, p1, p2) \ + ipcp_IsUrgentPort(&(ipcp)->cfg.urgent.tcp, p1, p2) +#define ipcp_IsUrgentUdpPort(ipcp, p1, p2) \ + ipcp_IsUrgentPort(&(ipcp)->cfg.urgent.udp, p1, p2) +#define ipcp_AddUrgentTcpPort(ipcp, p) \ + ipcp_AddUrgentPort(&(ipcp)->cfg.urgent.tcp, p) +#define ipcp_AddUrgentUdpPort(ipcp, p) \ + ipcp_AddUrgentPort(&(ipcp)->cfg.urgent.udp, p) +#define ipcp_RemoveUrgentTcpPort(ipcp, p) \ + ipcp_RemoveUrgentPort(&(ipcp)->cfg.urgent.tcp, p) +#define ipcp_RemoveUrgentUdpPort(ipcp, p) \ + ipcp_RemoveUrgentPort(&(ipcp)->cfg.urgent.udp, p) +#define ipcp_ClearUrgentTcpPorts(ipcp) \ + ipcp_ClearUrgentPorts(&(ipcp)->cfg.urgent.tcp) +#define ipcp_ClearUrgentUdpPorts(ipcp) \ + ipcp_ClearUrgentPorts(&(ipcp)->cfg.urgent.udp) diff --git a/usr.sbin/ppp/ppp/layer.h b/usr.sbin/ppp/ppp/layer.h index a6459bcf0a2..041cb43e42b 100644 --- a/usr.sbin/ppp/ppp/layer.h +++ b/usr.sbin/ppp/ppp/layer.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: layer.h,v 1.1 1999/05/08 11:06:36 brian Exp $ + * $Id: layer.h,v 1.2 2000/01/07 03:26:54 brian Exp $ */ #define LAYER_ASYNC 2 @@ -34,7 +34,7 @@ #define LAYER_LQR 7 #define LAYER_CCP 8 #define LAYER_VJ 9 -#define LAYER_ALIAS 10 +#define LAYER_NAT 10 #define LAYER_MAX 10 /* How many layers we can handle on a link */ diff --git a/usr.sbin/ppp/ppp/lcp.c b/usr.sbin/ppp/ppp/lcp.c index 22e6c7821d4..c90289874d8 100644 --- a/usr.sbin/ppp/ppp/lcp.c +++ b/usr.sbin/ppp/ppp/lcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lcp.c,v 1.16 1999/06/09 20:32:37 brian Exp $ + * $Id: lcp.c,v 1.17 2000/01/07 03:26:54 brian Exp $ * */ @@ -101,10 +101,10 @@ static struct fsm_callbacks lcp_Callbacks = { fsm_NullRecvResetAck }; -static const char *lcp_TimerNames[] = +static const char * const lcp_TimerNames[] = {"LCP restart", "LCP openmode", "LCP stopped"}; -static const char *cftypes[] = { +static const char * const cftypes[] = { /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ "???", "MRU", /* 1: Maximum-Receive-Unit */ @@ -540,7 +540,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type, struct mp *mp; struct physical *p = link2physical(fp->link); - callback_req = 0; + sz = op = callback_req = 0; while (plen >= sizeof(struct fsmconfig)) { type = *cp; @@ -1154,7 +1154,7 @@ extern struct mbuf * lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { /* Got PROTO_LCP from link */ - mbuf_SetType(bp, MB_LCPIN); + m_settype(bp, MB_LCPIN); fsm_Input(&l->lcp.fsm, bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/link.c b/usr.sbin/ppp/ppp/link.c index f1071c8ce4c..331e6e485cc 100644 --- a/usr.sbin/ppp/ppp/link.c +++ b/usr.sbin/ppp/ppp/link.c @@ -23,13 +23,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link.c,v 1.9 1999/07/15 02:10:32 brian Exp $ + * $Id: link.c,v 1.10 2000/01/07 03:26:54 brian Exp $ * */ #include <sys/types.h> #include <netinet/in_systm.h> -#include <netdb.h> #include <sys/un.h> #include <netinet/in.h> #include <netinet/ip.h> @@ -83,45 +82,53 @@ link_AddOutOctets(struct link *l, int n) void link_SequenceQueue(struct link *l) { + struct mqueue *queue, *highest; + log_Printf(LogDEBUG, "link_SequenceQueue\n"); - while (l->Queue[PRI_NORMAL].qlen) - mbuf_Enqueue(l->Queue + PRI_LINK, mbuf_Dequeue(l->Queue + PRI_NORMAL)); + + highest = LINK_HIGHQ(l); + for (queue = l->Queue; queue < highest; queue++) + while (queue->len) + m_enqueue(highest, m_dequeue(queue)); } void link_DeleteQueue(struct link *l) { - struct mqueue *queue; + struct mqueue *queue, *highest; - for (queue = l->Queue; queue < l->Queue + LINK_QUEUES; queue++) + highest = LINK_HIGHQ(l); + for (queue = l->Queue; queue <= highest; queue++) while (queue->top) - mbuf_Free(mbuf_Dequeue(queue)); + m_freem(m_dequeue(queue)); } -int +size_t link_QueueLen(struct link *l) { - int i, len; + int i; + size_t len; - for (i = 0, len = 0; i < LINK_QUEUES; i++) - len += l->Queue[i].qlen; + for (i = 0, len = 0; i < LINK_QUEUES(l); i++) + len += l->Queue[i].len; return len; } -int +size_t link_QueueBytes(struct link *l) { - int i, len, bytes; + int i; + size_t len, bytes; struct mbuf *m; bytes = 0; - for (i = 0, len = 0; i < LINK_QUEUES; i++) { - len = l->Queue[i].qlen; + for (i = 0, len = 0; i < LINK_QUEUES(l); i++) { + len = l->Queue[i].len; m = l->Queue[i].top; while (len--) { - bytes += mbuf_Length(m); - m = m->pnext; + bytes += m_length(m); + m = m->m_nextpkt; } } @@ -134,11 +141,12 @@ link_Dequeue(struct link *l) int pri; struct mbuf *bp; - for (bp = (struct mbuf *)0, pri = LINK_QUEUES - 1; pri >= 0; pri--) - if (l->Queue[pri].qlen) { - bp = mbuf_Dequeue(l->Queue + pri); + for (bp = NULL, pri = LINK_QUEUES(l) - 1; pri >= 0; pri--) + if (l->Queue[pri].len) { + bp = m_dequeue(l->Queue + pri); log_Printf(LogDEBUG, "link_Dequeue: Dequeued from queue %d," - " containing %d more packets\n", pri, l->Queue[pri].qlen); + " containing %lu more packets\n", pri, + (u_long)l->Queue[pri].len); break; } @@ -209,7 +217,7 @@ link_PushPacket(struct link *l, struct mbuf *bp, struct bundle *b, int pri, * packet (as we do with ``pull''s). */ - if(pri < 0 || pri >= LINK_QUEUES) + if(pri < 0 || pri >= LINK_QUEUES(l)) pri = 0; for (layer = l->nlayers; layer && bp; layer--) @@ -217,9 +225,9 @@ link_PushPacket(struct link *l, struct mbuf *bp, struct bundle *b, int pri, bp = (*l->layer[layer - 1]->push)(b, l, bp, pri, &proto); if (bp) { - link_AddOutOctets(l, mbuf_Length(bp)); + link_AddOutOctets(l, m_length(bp)); log_Printf(LogDEBUG, "link_PushPacket: Transmit proto 0x%04x\n", proto); - mbuf_Enqueue(l->Queue + pri, mbuf_Contiguous(bp)); + m_enqueue(l->Queue + pri, m_pullup(bp)); } } @@ -234,7 +242,7 @@ link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b) * When we ``pull'' a packet from the link, it gets processed by the * ``pull'' function in each layer starting at the bottom. * Each ``pull'' may produce multiple packets, chained together using - * bp->pnext. + * bp->m_nextpkt. * Each packet that results from each pull has to be pulled through * all of the higher layers before the next resulting packet is pulled * through anything; this ensures that packets that depend on the @@ -245,7 +253,7 @@ link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b) link_AddInOctets(l, len); memset(lbp, '\0', sizeof lbp); - lbp[0] = mbuf_Alloc(len, MB_UNKNOWN); + lbp[0] = m_get(len, MB_UNKNOWN); memcpy(MBUF_CTOP(lbp[0]), buf, len); lproto[0] = 0; layer = 0; @@ -256,8 +264,8 @@ link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b) continue; } bp = lbp[layer]; - lbp[layer] = bp->pnext; - bp->pnext = NULL; + lbp[layer] = bp->m_nextpkt; + bp->m_nextpkt = NULL; proto = lproto[layer]; if (l->layer[layer]->pull != NULL) @@ -266,8 +274,8 @@ link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b) if (layer == l->nlayers - 1) { /* We've just done the top layer, despatch the packet(s) */ while (bp) { - next = bp->pnext; - bp->pnext = NULL; + next = bp->m_nextpkt; + bp->m_nextpkt = NULL; log_Printf(LogDEBUG, "link_PullPacket: Despatch proto 0x%04x\n", proto); Despatch(b, l, bp, proto); bp = next; @@ -331,13 +339,13 @@ Despatch(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short proto) log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n", f == DSIZE ? "Unknown" : "Unexpected", proto, hdlc_Protocol2Nam(proto)); - bp = mbuf_Contiguous(proto_Prepend(bp, proto, 0, 0)); - lcp_SendProtoRej(&l->lcp, MBUF_CTOP(bp), bp->cnt); + bp = m_pullup(proto_Prepend(bp, proto, 0, 0)); + lcp_SendProtoRej(&l->lcp, MBUF_CTOP(bp), bp->m_len); if (p) { p->hdlc.lqm.SaveInDiscards++; p->hdlc.stats.unknownproto++; } - mbuf_Free(bp); + m_freem(bp); } } diff --git a/usr.sbin/ppp/ppp/link.h b/usr.sbin/ppp/ppp/link.h index 5b71da1a445..b64fb74c775 100644 --- a/usr.sbin/ppp/ppp/link.h +++ b/usr.sbin/ppp/ppp/link.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link.h,v 1.4 1999/05/15 02:25:23 brian Exp $ + * $Id: link.h,v 1.5 2000/01/07 03:26:54 brian Exp $ * */ @@ -31,7 +31,6 @@ #define PHYSICAL_LINK 1 #define LOGICAL_LINK 2 -#define LINK_QUEUES (PRI_MAX + 1) #define NPROTOSTAT 13 struct bundle; @@ -43,7 +42,7 @@ struct link { const char *name; /* Points to datalink::name */ int len; /* full size of parent struct */ struct pppThroughput throughput; /* Link throughput statistics */ - struct mqueue Queue[LINK_QUEUES]; /* Our output queue of mbufs */ + struct mqueue Queue[2]; /* Our output queue of mbufs */ u_long proto_in[NPROTOSTAT]; /* outgoing protocol stats */ u_long proto_out[NPROTOSTAT]; /* incoming protocol stats */ @@ -55,13 +54,16 @@ struct link { int nlayers; }; +#define LINK_QUEUES(link) (sizeof (link)->Queue / sizeof (link)->Queue[0]) +#define LINK_HIGHQ(link) ((link)->Queue + LINK_QUEUES(link) - 1) + extern void link_AddInOctets(struct link *, int); extern void link_AddOutOctets(struct link *, int); extern void link_SequenceQueue(struct link *); extern void link_DeleteQueue(struct link *); -extern int link_QueueLen(struct link *); -extern int link_QueueBytes(struct link *); +extern size_t link_QueueLen(struct link *); +extern size_t link_QueueBytes(struct link *); extern struct mbuf *link_Dequeue(struct link *); extern void link_PushPacket(struct link *, struct mbuf *, struct bundle *, diff --git a/usr.sbin/ppp/ppp/log.c b/usr.sbin/ppp/ppp/log.c index 8fc332b956f..ce4d74627fd 100644 --- a/usr.sbin/ppp/ppp/log.c +++ b/usr.sbin/ppp/ppp/log.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: log.c,v 1.7 1999/08/08 15:19:54 brian Exp $ + * $Id: log.c,v 1.8 2000/01/07 03:26:54 brian Exp $ */ #include <sys/types.h> @@ -42,7 +42,7 @@ #include "descriptor.h" #include "prompt.h" -static const char *LogNames[] = { +static const char * const LogNames[] = { "Async", "CBCP", "CCP", @@ -72,6 +72,7 @@ static u_long LogMask = MSK(LogPHASE); static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); static int LogTunno = -1; static struct prompt *promptlist; /* Where to log local stuff */ +struct prompt *log_PromptContext; int log_PromptListChanged; struct prompt * @@ -307,20 +308,23 @@ log_Printf(int lev, const char *fmt,...) if (log_IsKept(lev)) { char nfmt[200]; - if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) { + if (promptlist && (log_IsKept(lev) & LOG_KEPT_LOCAL)) { if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, LogTunno, log_Name(lev), fmt); else snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); - for (prompt = promptlist; prompt; prompt = prompt->next) + if (log_PromptContext && lev == LogWARN) + /* Warnings just go to the current prompt */ + prompt_vPrintf(log_PromptContext, nfmt, ap); + else for (prompt = promptlist; prompt; prompt = prompt->next) if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) prompt_vPrintf(prompt, nfmt, ap); } if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && - (lev != LogWARN || !promptlist)) { + (lev != LogWARN || !log_PromptContext)) { if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, LogTunno, log_Name(lev), fmt); @@ -347,7 +351,7 @@ log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) b = buf; c = b + 50; do { - f = bp->cnt; + f = bp->m_len; ptr = CONST_MBUF_CTOP(bp); while (f--) { sprintf(b, " %02x", (int) *ptr); @@ -362,7 +366,7 @@ log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) c = b + 50; } } - } while ((bp = bp->next) != NULL); + } while ((bp = bp->m_next) != NULL); if (b > buf) { memset(b, ' ', 50 - (b - buf)); diff --git a/usr.sbin/ppp/ppp/log.h b/usr.sbin/ppp/ppp/log.h index 46d4ad47853..f2c3915f165 100644 --- a/usr.sbin/ppp/ppp/log.h +++ b/usr.sbin/ppp/ppp/log.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: log.h,v 1.3 1999/05/12 10:03:52 brian Exp $ + * $Id: log.h,v 1.4 2000/01/07 03:26:54 brian Exp $ */ #define LogMIN (1) @@ -87,6 +87,7 @@ extern int log_ShowLevel(struct cmdargs const *); extern int log_SetLevel(struct cmdargs const *); extern int log_ShowWho(struct cmdargs const *); +extern struct prompt *log_PromptContext; extern int log_PromptListChanged; extern void log_RegisterPrompt(struct prompt *); extern void log_UnRegisterPrompt(struct prompt *); diff --git a/usr.sbin/ppp/ppp/lqr.c b/usr.sbin/ppp/ppp/lqr.c index 813f9828fd2..38e17ad338a 100644 --- a/usr.sbin/ppp/ppp/lqr.c +++ b/usr.sbin/ppp/ppp/lqr.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lqr.c,v 1.7 1999/06/02 15:58:41 brian Exp $ + * $Id: lqr.c,v 1.8 2000/01/07 03:26:54 brian Exp $ * * o LQR based on RFC1333 * @@ -85,7 +85,7 @@ lqr_RecvEcho(struct fsm *fp, struct mbuf *bp) struct lcp *lcp = fsm2lcp(fp); struct echolqr lqr; - if (mbuf_Length(bp) == sizeof lqr) { + if (m_length(bp) == sizeof lqr) { bp = mbuf_Read(bp, &lqr, sizeof lqr); lqr.magic = ntohl(lqr.magic); lqr.signature = ntohl(lqr.signature); @@ -109,10 +109,10 @@ lqr_RecvEcho(struct fsm *fp, struct mbuf *bp) hdlc->lqm.echo.seq_recv = lqr.sequence; } else log_Printf(LogWARN, "lqr_RecvEcho: Got sig 0x%08lx, not 0x%08lx !\n", - (u_long)ntohl(lqr.signature), (u_long)SIGNATURE); + (u_long)lqr.signature, (u_long)SIGNATURE); } else log_Printf(LogWARN, "lqr_RecvEcho: Got packet size %d, expecting %ld !\n", - mbuf_Length(bp), (long)sizeof(struct echolqr)); + m_length(bp), (long)sizeof(struct echolqr)); return bp; } @@ -136,10 +136,11 @@ SendLqrData(struct lcp *lcp) extra = proto_WrapperOctets(lcp, PROTO_LQR) + acf_WrapperOctets(lcp, PROTO_LQR); - bp = mbuf_Alloc(sizeof(struct lqrdata) + extra, MB_LQROUT); - bp->cnt -= extra; - bp->offset += extra; - link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle, PRI_LINK, PROTO_LQR); + bp = m_get(sizeof(struct lqrdata) + extra, MB_LQROUT); + bp->m_len -= extra; + bp->m_offset += extra; + link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle, + LINK_QUEUES(lcp->fsm.link) - 1, PROTO_LQR); } static void @@ -190,24 +191,24 @@ lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p == NULL) { log_Printf(LogERROR, "lqr_Input: Not a physical link - dropped\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } p->hdlc.lqm.lqr.SaveInLQRs++; - len = mbuf_Length(bp); + len = m_length(bp); if (len != sizeof(struct lqrdata)) log_Printf(LogWARN, "lqr_Input: Got packet size %d, expecting %ld !\n", len, (long)sizeof(struct lqrdata)); else if (!IsAccepted(l->lcp.cfg.lqr) && !(p->hdlc.lqm.method & LQM_LQR)) { - bp = mbuf_Contiguous(proto_Prepend(bp, PROTO_LQR, 0, 0)); - lcp_SendProtoRej(lcp, MBUF_CTOP(bp), bp->cnt); + bp = m_pullup(proto_Prepend(bp, PROTO_LQR, 0, 0)); + lcp_SendProtoRej(lcp, MBUF_CTOP(bp), bp->m_len); } else { struct lqrdata *lqr; u_int32_t lastLQR; - bp = mbuf_Contiguous(bp); + bp = m_pullup(bp); lqr = (struct lqrdata *)MBUF_CTOP(bp); if (ntohl(lqr->MagicNumber) != lcp->his_magic) log_Printf(LogWARN, "lqr_Input: magic 0x%08lx is wrong," @@ -238,7 +239,7 @@ lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) SendLqrData(lcp); } } - mbuf_Free(bp); + m_freem(bp); return NULL; } @@ -356,7 +357,7 @@ lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, if (!p) { /* Oops - can't happen :-] */ - mbuf_Free(bp); + m_freem(bp); return NULL; } @@ -378,8 +379,8 @@ lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, * don't do LQR without these layers. */ - bp = mbuf_Contiguous(bp); - len = mbuf_Length(bp); + bp = m_pullup(bp); + len = m_length(bp); if (!physical_IsSync(p)) p->hdlc.lqm.OutOctets += hdlc_WrapperOctets(&l->lcp, *proto); @@ -427,7 +428,7 @@ lqr_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) * to lqr_Input() */ if (*proto == PROTO_LQR) - mbuf_SetType(bp, MB_LQRIN); + m_settype(bp, MB_LQRIN); return bp; } diff --git a/usr.sbin/ppp/ppp/main.c b/usr.sbin/ppp/ppp/main.c index 9493a3cdfed..e45d2382203 100644 --- a/usr.sbin/ppp/ppp/main.c +++ b/usr.sbin/ppp/ppp/main.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: main.c,v 1.14 1999/08/09 23:01:36 brian Exp $ + * $Id: main.c,v 1.15 2000/01/07 03:26:54 brian Exp $ * * TODO: */ @@ -33,13 +33,14 @@ #include <paths.h> #include <signal.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/time.h> #include <termios.h> #include <unistd.h> #include <sys/stat.h> -#ifndef NOALIAS +#ifndef NONAT #ifdef __FreeBSD__ #include <alias.h> #else @@ -166,7 +167,7 @@ static const char * ex_desc(int ex) { static char num[12]; /* Used immediately if returned */ - static const char *desc[] = { + static const char * const desc[] = { "normal", "start", "sock", "modem", "dial", "dead", "done", "reboot", "errdead", "hangup", "term", "nodial", "nologin" }; @@ -181,35 +182,69 @@ static void Usage(void) { fprintf(stderr, - "Usage: ppp [-auto | -background | -direct | -dedicated | -ddial ]" + "Usage: ppp [-auto | -foreground | -background | -direct | -dedicated | -ddial | -interactive]" #ifndef NOALIAS - " [ -alias ]" + " [-nat]" #endif - " [system ...]\n"); + " [-quiet] [-unit N] [system ...]\n"); exit(EX_START); } +struct switches { + unsigned nat : 1; + unsigned fg : 1; + unsigned quiet : 1; + int mode; + int unit; +}; + static int -ProcessArgs(int argc, char **argv, int *mode, int *alias) +ProcessArgs(int argc, char **argv, struct switches *sw) { int optc, newmode, arg; char *cp; optc = 0; - *mode = PHYS_INTERACTIVE; - *alias = 0; + memset(sw, '\0', sizeof *sw); + sw->mode = PHYS_INTERACTIVE; + sw->unit = -1; + for (arg = 1; arg < argc && *argv[arg] == '-'; arg++, optc++) { cp = argv[arg] + 1; newmode = Nam2mode(cp); switch (newmode) { case PHYS_NONE: - if (strcmp(cp, "alias") == 0) { -#ifdef NOALIAS - log_Printf(LogWARN, "Cannot load alias library (compiled out)\n"); + if (strcmp(cp, "nat") == 0) { +#ifdef NONAT + log_Printf(LogWARN, "%s ignored: NAT is compiled out\n", argv[arg]); #else - *alias = 1; + sw->nat = 1; #endif optc--; /* this option isn't exclusive */ + } else if (strcmp(cp, "alias") == 0) { +#ifdef NONAT + log_Printf(LogWARN, "%s ignored: NAT is compiled out\n", argv[arg]); + fprintf(stderr, "%s ignored: NAT is compiled out\n", argv[arg]); +#else + log_Printf(LogWARN, "%s is deprecated\n", argv[arg]); + fprintf(stderr, "%s is deprecated\n", argv[arg]); + sw->nat = 1; +#endif + optc--; /* this option isn't exclusive */ + } else if (strncmp(cp, "unit", 4) == 0) { + optc--; /* this option isn't exclusive */ + if (cp[4] == '\0') { + optc--; /* nor is the argument */ + if (++arg == argc) { + fprintf(stderr, "-unit: Expected unit number\n"); + Usage(); + } else + sw->unit = atoi(argv[arg]); + } else + sw->unit = atoi(cp + 4); + } else if (strcmp(cp, "quiet") == 0) { + sw->quiet = 1; + optc--; /* this option isn't exclusive */ } else Usage(); break; @@ -219,7 +254,9 @@ ProcessArgs(int argc, char **argv, int *mode, int *alias) break; default: - *mode = newmode; + sw->mode = newmode; + if (newmode == PHYS_FOREGROUND) + sw->fg = 1; } } @@ -228,7 +265,7 @@ ProcessArgs(int argc, char **argv, int *mode, int *alias) exit(EX_START); } - if (*mode == PHYS_AUTO && arg == argc) { + if (sw->mode == PHYS_AUTO && arg == argc) { fprintf(stderr, "A system must be specified in auto mode.\n"); exit(EX_START); } @@ -257,9 +294,10 @@ main(int argc, char **argv) { char *name; const char *lastlabel; - int nfds, mode, alias, label, arg; + int nfds, label, arg; struct bundle *bundle; struct prompt *prompt; + struct switches sw; nfds = getdtablesize(); if (nfds >= FD_SETSIZE) @@ -274,10 +312,10 @@ main(int argc, char **argv) name = strrchr(argv[0], '/'); log_Open(name ? name + 1 : argv[0]); -#ifndef NOALIAS +#ifndef NONAT PacketAliasInit(); #endif - label = ProcessArgs(argc, argv, &mode, &alias); + label = ProcessArgs(argc, argv, &sw); /* * A FreeBSD & OpenBSD hack to dodge a bug in the tty driver that drops @@ -286,7 +324,7 @@ main(int argc, char **argv) * routing table and then run ppp in interactive mode. The `show route' * command will drop chunks of data !!! */ - if (mode == PHYS_INTERACTIVE) { + if (sw.mode == PHYS_INTERACTIVE) { close(STDIN_FILENO); if (open(_PATH_TTY, O_RDONLY) != STDIN_FILENO) { fprintf(stderr, "Cannot open %s for input !\n", _PATH_TTY); @@ -295,7 +333,7 @@ main(int argc, char **argv) } /* Allow output for the moment (except in direct mode) */ - if (mode == PHYS_DIRECT) + if (sw.mode == PHYS_DIRECT) prompt = NULL; else SignalPrompt = prompt = prompt_Create(NULL, NULL, PROMPT_STD); @@ -321,26 +359,26 @@ main(int argc, char **argv) if (label < argc) for (arg = label; arg < argc; arg++) - CheckLabel(argv[arg], prompt, mode); + CheckLabel(argv[arg], prompt, sw.mode); else - CheckLabel("default", prompt, mode); + CheckLabel("default", prompt, sw.mode); - prompt_Printf(prompt, "Working in %s mode\n", mode2Nam(mode)); + if (!sw.quiet) + prompt_Printf(prompt, "Working in %s mode\n", mode2Nam(sw.mode)); - if ((bundle = bundle_Create(TUN_PREFIX, mode, (const char **)argv)) == NULL) { - log_Printf(LogWARN, "bundle_Create: %s\n", strerror(errno)); + if ((bundle = bundle_Create(TUN_PREFIX, sw.mode, sw.unit)) == NULL) return EX_START; - } /* NOTE: We may now have changed argv[1] via a ``set proctitle'' */ if (prompt) { prompt->bundle = bundle; /* couldn't do it earlier */ - prompt_Printf(prompt, "Using interface: %s\n", bundle->iface->name); + if (!sw.quiet) + prompt_Printf(prompt, "Using interface: %s\n", bundle->iface->name); } SignalBundle = bundle; - bundle->AliasEnabled = alias; - if (alias) + bundle->NatEnabled = sw.nat; + if (sw.nat) bundle->cfg.opt |= OPT_IFACEALIAS; if (system_Select(bundle, "default", CONFFILE, prompt, NULL) < 0) @@ -353,101 +391,103 @@ main(int argc, char **argv) sig_signal(SIGALRM, SIG_IGN); signal(SIGPIPE, SIG_IGN); - if (mode == PHYS_INTERACTIVE) + if (sw.mode == PHYS_INTERACTIVE) sig_signal(SIGTSTP, TerminalStop); sig_signal(SIGUSR2, BringDownServer); - lastlabel = argc == 2 ? bundle->argv1 : argv[argc - 1]; + lastlabel = argv[argc - 1]; for (arg = label; arg < argc; arg++) { /* In case we use LABEL or ``set enddisc label'' */ bundle_SetLabel(bundle, lastlabel); - system_Select(bundle, arg == 1 ? bundle->argv1 : argv[arg], - CONFFILE, prompt, NULL); + system_Select(bundle, argv[arg], CONFFILE, prompt, NULL); } if (label < argc) /* In case the last label did a ``load'' */ bundle_SetLabel(bundle, lastlabel); - if (mode == PHYS_AUTO && + if (sw.mode == PHYS_AUTO && bundle->ncp.ipcp.cfg.peer_range.ipaddr.s_addr == INADDR_ANY) { prompt_Printf(prompt, "You must ``set ifaddr'' with a peer address " "in auto mode.\n"); AbortProgram(EX_START); } - if (mode != PHYS_INTERACTIVE) { - if (mode != PHYS_DIRECT) { - int bgpipe[2]; - pid_t bgpid; + if (sw.mode != PHYS_INTERACTIVE) { + if (sw.mode != PHYS_DIRECT) { + if (!sw.fg) { + int bgpipe[2]; + pid_t bgpid; - if (mode == PHYS_BACKGROUND && pipe(bgpipe)) { - log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); - AbortProgram(EX_SOCK); - } + if (sw.mode == PHYS_BACKGROUND && pipe(bgpipe)) { + log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); + AbortProgram(EX_SOCK); + } - bgpid = fork(); - if (bgpid == -1) { - log_Printf(LogERROR, "fork: %s\n", strerror(errno)); - AbortProgram(EX_SOCK); - } + bgpid = fork(); + if (bgpid == -1) { + log_Printf(LogERROR, "fork: %s\n", strerror(errno)); + AbortProgram(EX_SOCK); + } - if (bgpid) { - char c = EX_NORMAL; - - if (mode == PHYS_BACKGROUND) { - close(bgpipe[1]); - BGPid = bgpid; - /* If we get a signal, kill the child */ - signal(SIGHUP, KillChild); - signal(SIGTERM, KillChild); - signal(SIGINT, KillChild); - signal(SIGQUIT, KillChild); - - /* Wait for our child to close its pipe before we exit */ - if (read(bgpipe[0], &c, 1) != 1) { - prompt_Printf(prompt, "Child exit, no status.\n"); - log_Printf(LogPHASE, "Parent: Child exit, no status.\n"); - } else if (c == EX_NORMAL) { - prompt_Printf(prompt, "PPP enabled.\n"); - log_Printf(LogPHASE, "Parent: PPP enabled.\n"); - } else { - prompt_Printf(prompt, "Child failed (%s).\n", ex_desc((int) c)); - log_Printf(LogPHASE, "Parent: Child failed (%s).\n", - ex_desc((int) c)); + if (bgpid) { + char c = EX_NORMAL; + + if (sw.mode == PHYS_BACKGROUND) { + close(bgpipe[1]); + BGPid = bgpid; + /* If we get a signal, kill the child */ + signal(SIGHUP, KillChild); + signal(SIGTERM, KillChild); + signal(SIGINT, KillChild); + signal(SIGQUIT, KillChild); + + /* Wait for our child to close its pipe before we exit */ + if (read(bgpipe[0], &c, 1) != 1) { + prompt_Printf(prompt, "Child exit, no status.\n"); + log_Printf(LogPHASE, "Parent: Child exit, no status.\n"); + } else if (c == EX_NORMAL) { + prompt_Printf(prompt, "PPP enabled.\n"); + log_Printf(LogPHASE, "Parent: PPP enabled.\n"); + } else { + prompt_Printf(prompt, "Child failed (%s).\n", ex_desc((int) c)); + log_Printf(LogPHASE, "Parent: Child failed (%s).\n", + ex_desc((int) c)); + } + close(bgpipe[0]); } + return c; + } else if (sw.mode == PHYS_BACKGROUND) { close(bgpipe[0]); - } - return c; - } else if (mode == PHYS_BACKGROUND) { - close(bgpipe[0]); - bundle->notify.fd = bgpipe[1]; - } + bundle->notify.fd = bgpipe[1]; + } - bundle_LockTun(bundle); /* we have a new pid */ + bundle_LockTun(bundle); /* we have a new pid */ + } - /* -auto, -dedicated, -ddial & -background */ + /* -auto, -dedicated, -ddial, -foreground & -background */ prompt_Destroy(prompt, 0); close(STDOUT_FILENO); close(STDERR_FILENO); close(STDIN_FILENO); - setsid(); + if (!sw.fg) + setsid(); } else { - /* -direct: STDIN_FILENO gets used by modem_Open */ + /* -direct - STDIN_FILENO gets used by physical_Open */ prompt_TtyInit(NULL); close(STDOUT_FILENO); close(STDERR_FILENO); } } else { - /* Interactive mode */ + /* -interactive */ close(STDERR_FILENO); prompt_TtyInit(prompt); prompt_TtyCommandMode(prompt); prompt_Required(prompt); } - log_Printf(LogPHASE, "PPP Started (%s mode).\n", mode2Nam(mode)); + log_Printf(LogPHASE, "PPP Started (%s mode).\n", mode2Nam(sw.mode)); DoLoop(bundle); AbortProgram(EX_NORMAL); @@ -463,7 +503,7 @@ DoLoop(struct bundle *bundle) probe_Init(&probe); - do { + for (; !bundle_IsDead(bundle); bundle_CleanDatalinks(bundle)) { nfds = 0; FD_ZERO(&rfds); FD_ZERO(&wfds); @@ -576,7 +616,7 @@ DoLoop(struct bundle *bundle) t.tv_usec = 100000; select(0, NULL, NULL, NULL, &t); } - } while (bundle_CleanDatalinks(bundle), !bundle_IsDead(bundle)); + } log_Printf(LogDEBUG, "DoLoop done.\n"); } diff --git a/usr.sbin/ppp/ppp/mbuf.c b/usr.sbin/ppp/ppp/mbuf.c index 853a60a42b1..00de826a466 100644 --- a/usr.sbin/ppp/ppp/mbuf.c +++ b/usr.sbin/ppp/ppp/mbuf.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: mbuf.c,v 1.8 1999/08/26 06:39:19 brian Exp $ + * $Id: mbuf.c,v 1.9 2000/01/07 03:26:55 brian Exp $ * */ #include <sys/types.h> @@ -36,60 +36,121 @@ #include "prompt.h" #include "main.h" +#define BUCKET_CHUNK 20 +#define BUCKET_HASH 256 + +struct mbucket; + +struct mfree { + struct mbucket *next; + size_t count; +}; + +static struct mbucket { + union { + struct mbuf m; + struct mfree f; + } u; +} *bucket[(M_MAXLEN + sizeof(struct mbuf)) / BUCKET_HASH]; + +#define M_BINDEX(sz) (((sz) + sizeof(struct mbuf) - 1) / BUCKET_HASH) +#define M_BUCKET(sz) (bucket + M_BINDEX(sz)) +#define M_ROUNDUP(sz) ((M_BINDEX(sz) + 1) * BUCKET_HASH) + static struct memmap { struct mbuf *queue; - int fragments, octets; + size_t fragments; + size_t octets; } MemMap[MB_MAX + 1]; -static int totalalloced; static unsigned long long mbuf_Mallocs, mbuf_Frees; int -mbuf_Length(struct mbuf *bp) +m_length(struct mbuf *bp) { int len; - for (len = 0; bp; bp = bp->next) - len += bp->cnt; + for (len = 0; bp; bp = bp->m_next) + len += bp->m_len; return len; } struct mbuf * -mbuf_Alloc(int cnt, int type) +m_get(size_t m_len, int type) { + struct mbucket **mb; struct mbuf *bp; + size_t size; if (type > MB_MAX) { log_Printf(LogERROR, "Bad mbuf type %d\n", type); type = MB_UNKNOWN; } - bp = malloc(sizeof(struct mbuf) + cnt); - if (bp == NULL) { - log_Printf(LogALERT, "failed to allocate memory: %ld\n", - (long)sizeof(struct mbuf)); + + if (m_len > M_MAXLEN || m_len == 0) { + log_Printf(LogERROR, "Request for mbuf size %lu denied\n", (u_long)m_len); AbortProgram(EX_OSERR); } + + mb = M_BUCKET(m_len); + size = M_ROUNDUP(m_len); + + if (*mb) { + /* We've got some free blocks of the right size */ + bp = &(*mb)->u.m; + if (--(*mb)->u.f.count == 0) + *mb = (*mb)->u.f.next; + else { + ((struct mbucket *)((char *)*mb + size))->u.f.count = (*mb)->u.f.count; + *mb = (struct mbucket *)((char *)*mb + size); + (*mb)->u.f.next = NULL; + } + } else { + /* + * Allocate another chunk of mbufs, use the first and put the rest on + * the free list + */ + *mb = (struct mbucket *)malloc(BUCKET_CHUNK * size); + if (*mb == NULL) { + log_Printf(LogALERT, "Failed to allocate memory (%u)\n", + BUCKET_CHUNK * size); + AbortProgram(EX_OSERR); + } + bp = &(*mb)->u.m; + *mb = (struct mbucket *)((char *)*mb + size); + (*mb)->u.f.count = BUCKET_CHUNK - 1; + (*mb)->u.f.next = NULL; + } + mbuf_Mallocs++; + memset(bp, '\0', sizeof(struct mbuf)); + bp->m_size = size - sizeof *bp; + bp->m_len = m_len; + bp->m_type = type; + MemMap[type].fragments++; - MemMap[type].octets += cnt; - totalalloced += cnt; - bp->size = bp->cnt = cnt; - bp->type = type; + MemMap[type].octets += bp->m_size; + return bp; } struct mbuf * -mbuf_FreeSeg(struct mbuf *bp) +m_free(struct mbuf *bp) { + struct mbucket **mb, *f; struct mbuf *nbp; - if (bp) { - nbp = bp->next; - MemMap[bp->type].fragments--; - MemMap[bp->type].octets -= bp->size; - totalalloced -= bp->size; - free(bp); + if ((f = (struct mbucket *)bp) != NULL) { + MemMap[bp->m_type].fragments--; + MemMap[bp->m_type].octets -= bp->m_size; + + nbp = bp->m_next; + mb = M_BUCKET(bp->m_size); + f->u.f.next = *mb; + f->u.f.count = 1; + *mb = f; + mbuf_Frees++; bp = nbp; } @@ -98,10 +159,10 @@ mbuf_FreeSeg(struct mbuf *bp) } void -mbuf_Free(struct mbuf *bp) +m_freem(struct mbuf *bp) { while (bp) - bp = mbuf_FreeSeg(bp); + bp = m_free(bp); } struct mbuf * @@ -111,23 +172,23 @@ mbuf_Read(struct mbuf *bp, void *v, size_t len) u_char *ptr = v; while (bp && len > 0) { - if (len > bp->cnt) - nb = bp->cnt; + if (len > bp->m_len) + nb = bp->m_len; else nb = len; if (nb) { memcpy(ptr, MBUF_CTOP(bp), nb); ptr += nb; - bp->cnt -= nb; + bp->m_len -= nb; len -= nb; - bp->offset += nb; + bp->m_offset += nb; } - if (bp->cnt == 0) - bp = mbuf_FreeSeg(bp); + if (bp->m_len == 0) + bp = m_free(bp); } - while (bp && bp->cnt == 0) - bp = mbuf_FreeSeg(bp); + while (bp && bp->m_len == 0) + bp = m_free(bp); return bp; } @@ -139,80 +200,92 @@ mbuf_View(struct mbuf *bp, void *v, size_t len) u_char *ptr = v; while (bp && l > 0) { - if (l > bp->cnt) - nb = bp->cnt; + if (l > bp->m_len) + nb = bp->m_len; else nb = l; memcpy(ptr, MBUF_CTOP(bp), nb); ptr += nb; l -= nb; - bp = bp->next; + bp = bp->m_next; } return len - l; } struct mbuf * -mbuf_Prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra) +m_prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra) { struct mbuf *head; - if (bp && bp->offset) { - if (bp->offset >= len) { - bp->offset -= len; - bp->cnt += len; + if (bp && bp->m_offset) { + if (bp->m_offset >= len) { + bp->m_offset -= len; + bp->m_len += len; memcpy(MBUF_CTOP(bp), ptr, len); return bp; } - len -= bp->offset; - memcpy(bp + sizeof *bp, (const char *)ptr + len, bp->offset); - bp->cnt += bp->offset; - bp->offset = 0; + len -= bp->m_offset; + memcpy(bp + 1, (const char *)ptr + len, bp->m_offset); + bp->m_len += bp->m_offset; + bp->m_offset = 0; } - head = mbuf_Alloc(len + extra, bp ? bp->type : MB_UNKNOWN); - head->offset = extra; - head->cnt -= extra; - memcpy(MBUF_CTOP(head), ptr, len); - head->next = bp; + head = m_get(len + extra, bp ? bp->m_type : MB_UNKNOWN); + head->m_offset = extra; + head->m_len -= extra; + if (ptr) + memcpy(MBUF_CTOP(head), ptr, len); + head->m_next = bp; return head; } struct mbuf * -mbuf_Truncate(struct mbuf *bp, size_t n) +m_adj(struct mbuf *bp, ssize_t n) { - if (n == 0) { - mbuf_Free(bp); - return NULL; - } - - for (; bp; bp = bp->next, n -= bp->cnt) - if (n < bp->cnt) { - bp->cnt = n; - mbuf_Free(bp->next); - bp->next = NULL; - break; + if (n > 0) { + while (bp) { + if (n < bp->m_len) { + bp->m_len = n; + bp->m_offset += n; + return bp; + } + n -= bp->m_len; + bp = m_free(bp); + } + } else { + if ((n = m_length(bp) + n) <= 0) { + m_freem(bp); + return NULL; } + for (; bp; bp = bp->m_next, n -= bp->m_len) + if (n < bp->m_len) { + bp->m_len = n; + m_freem(bp->m_next); + bp->m_next = NULL; + break; + } + } return bp; } void -mbuf_Write(struct mbuf *bp, const void *ptr, size_t cnt) +mbuf_Write(struct mbuf *bp, const void *ptr, size_t m_len) { int plen; int nb; - plen = mbuf_Length(bp); - if (plen < cnt) - cnt = plen; + plen = m_length(bp); + if (plen < m_len) + m_len = plen; - while (cnt > 0) { - nb = (cnt < bp->cnt) ? cnt : bp->cnt; + while (m_len > 0) { + nb = (m_len < bp->m_len) ? m_len : bp->m_len; memcpy(MBUF_CTOP(bp), ptr, nb); - cnt -= bp->cnt; - bp = bp->next; + m_len -= bp->m_len; + bp = bp->m_next; } } @@ -220,8 +293,8 @@ int mbuf_Show(struct cmdargs const *arg) { int i; - static const char *mbuftype[] = { - "ip in", "ip out", "alias in", "alias out", "mp in", "mp out", + static const char * const mbuftype[] = { + "ip in", "ip out", "nat in", "nat out", "mp in", "mp out", "vj in", "vj out", "icompd in", "icompd out", "compd in", "compd out", "lqr in", "lqr out", "echo in", "echo out", "proto in", "proto out", "acf in", "acf out", "sync in", "sync out", "hdlc in", "hdlc out", @@ -232,13 +305,16 @@ mbuf_Show(struct cmdargs const *arg) prompt_Printf(arg->prompt, "Fragments (octets) in use:\n"); for (i = 0; i < MB_MAX; i += 2) - prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\t%10.10s: %04d (%06d)\n", - mbuftype[i], MemMap[i].fragments, MemMap[i].octets, - mbuftype[i+1], MemMap[i+1].fragments, MemMap[i+1].octets); + prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\t" + "%10.10s: %04lu (%06lu)\n", + mbuftype[i], (u_long)MemMap[i].fragments, + (u_long)MemMap[i].octets, mbuftype[i+1], + (u_long)MemMap[i+1].fragments, (u_long)MemMap[i+1].octets); if (i == MB_MAX) - prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n", - mbuftype[i], MemMap[i].fragments, MemMap[i].octets); + prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\n", + mbuftype[i], (u_long)MemMap[i].fragments, + (u_long)MemMap[i].octets); prompt_Printf(arg->prompt, "Mallocs: %llu, Frees: %llu\n", mbuf_Mallocs, mbuf_Frees); @@ -247,62 +323,63 @@ mbuf_Show(struct cmdargs const *arg) } struct mbuf * -mbuf_Dequeue(struct mqueue *q) +m_dequeue(struct mqueue *q) { struct mbuf *bp; - log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen); + log_Printf(LogDEBUG, "m_dequeue: queue len = %lu\n", (u_long)q->len); bp = q->top; if (bp) { - q->top = q->top->pnext; - q->qlen--; + q->top = q->top->m_nextpkt; + q->len--; if (q->top == NULL) { q->last = q->top; - if (q->qlen) - log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen); + if (q->len) + log_Printf(LogERROR, "m_dequeue: Not zero (%lu)!!!\n", + (u_long)q->len); } - bp->pnext = NULL; + bp->m_nextpkt = NULL; } return bp; } void -mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp) +m_enqueue(struct mqueue *queue, struct mbuf *bp) { if (bp != NULL) { if (queue->last) { - queue->last->pnext = bp; + queue->last->m_nextpkt = bp; queue->last = bp; } else queue->last = queue->top = bp; - queue->qlen++; - log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen); + queue->len++; + log_Printf(LogDEBUG, "m_enqueue: len = %d\n", queue->len); } } struct mbuf * -mbuf_Contiguous(struct mbuf *bp) +m_pullup(struct mbuf *bp) { /* Put it all in one contigous (aligned) mbuf */ if (bp != NULL) { - if (bp->next != NULL) { + if (bp->m_next != NULL) { struct mbuf *nbp; u_char *cp; - nbp = mbuf_Alloc(mbuf_Length(bp), bp->type); + nbp = m_get(m_length(bp), bp->m_type); - for (cp = MBUF_CTOP(nbp); bp; bp = mbuf_FreeSeg(bp)) { - memcpy(cp, MBUF_CTOP(bp), bp->cnt); - cp += bp->cnt; + for (cp = MBUF_CTOP(nbp); bp; bp = m_free(bp)) { + memcpy(cp, MBUF_CTOP(bp), bp->m_len); + cp += bp->m_len; } bp = nbp; } #ifndef __i386__ /* Do any other archs not care about alignment ? */ - else if ((bp->offset & (sizeof(long) - 1)) != 0) { - bcopy(MBUF_CTOP(bp), bp + 1, bp->cnt); - bp->offset = 0; + else if ((bp->m_offset & (sizeof(long) - 1)) != 0) { + bcopy(MBUF_CTOP(bp), bp + 1, bp->m_len); + bp->m_offset = 0; } #endif } @@ -311,14 +388,30 @@ mbuf_Contiguous(struct mbuf *bp) } void -mbuf_SetType(struct mbuf *bp, int type) +m_settype(struct mbuf *bp, int type) { - for (; bp; bp = bp->next) - if (type != bp->type) { - MemMap[bp->type].fragments--; - MemMap[bp->type].octets -= bp->size; - bp->type = type; + for (; bp; bp = bp->m_next) + if (type != bp->m_type) { + MemMap[bp->m_type].fragments--; + MemMap[bp->m_type].octets -= bp->m_size; + bp->m_type = type; MemMap[type].fragments++; - MemMap[type].octets += bp->size; + MemMap[type].octets += bp->m_size; } } + +struct mbuf * +m_append(struct mbuf *m, const void *v, size_t sz) +{ + if (m) { + while (m->m_next) + m = m->m_next; + if (m->m_size - m->m_len > sz) + m->m_len += sz; + else + m->m_next = m_prepend(NULL, v, sz, 0); + } else + m = m_prepend(NULL, v, sz, 0); + + return m; +} diff --git a/usr.sbin/ppp/ppp/mbuf.h b/usr.sbin/ppp/ppp/mbuf.h index 095a9b2a9ed..f85357e0e14 100644 --- a/usr.sbin/ppp/ppp/mbuf.h +++ b/usr.sbin/ppp/ppp/mbuf.h @@ -15,37 +15,37 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: mbuf.h,v 1.6 1999/06/02 15:58:41 brian Exp $ + * $Id: mbuf.h,v 1.7 2000/01/07 03:26:55 brian Exp $ * * TODO: */ struct mbuf { - short size; /* size allocated (excluding header) */ - short offset; /* offset from header end to start position */ - short cnt; /* available byte count in buffer */ - short type; /* MB_* below */ - struct mbuf *next; /* link to next mbuf */ - struct mbuf *pnext; /* link to next packet */ + size_t m_size; /* size allocated (excluding header) */ + short m_offset; /* offset from header end to start position */ + size_t m_len; /* available byte count in buffer */ + short m_type; /* MB_* below */ + struct mbuf *m_next; /* link to next mbuf */ + struct mbuf *m_nextpkt; /* link to next packet */ /* buffer space is malloc()d directly after the header */ }; struct mqueue { struct mbuf *top; struct mbuf *last; - int qlen; + size_t len; }; #define MBUF_CTOP(bp) \ - ((bp) ? (u_char *)((bp)+1) + (bp)->offset : NULL) + ((bp) ? (u_char *)((bp)+1) + (bp)->m_offset : NULL) #define CONST_MBUF_CTOP(bp) \ - ((bp) ? (const u_char *)((bp)+1) + (bp)->offset : NULL) + ((bp) ? (const u_char *)((bp)+1) + (bp)->m_offset : NULL) #define MB_IPIN 0 #define MB_IPOUT 1 -#define MB_ALIASIN 2 -#define MB_ALIASOUT 3 +#define MB_NATIN 2 +#define MB_NATOUT 3 #define MB_MPIN 4 #define MB_MPOUT 5 #define MB_VJIN 6 @@ -83,19 +83,24 @@ struct mqueue { #define MB_UNKNOWN 38 #define MB_MAX MB_UNKNOWN +#define M_MAXLEN (4096 - sizeof(struct mbuf)) + struct cmdargs; -extern int mbuf_Length(struct mbuf *); -extern struct mbuf *mbuf_Alloc(int, int); -extern struct mbuf *mbuf_FreeSeg(struct mbuf *); -extern void mbuf_Free(struct mbuf *); +extern int m_length(struct mbuf *); +extern struct mbuf *m_get(size_t, int); +extern struct mbuf *m_free(struct mbuf *); +extern void m_freem(struct mbuf *); extern void mbuf_Write(struct mbuf *, const void *, size_t); extern struct mbuf *mbuf_Read(struct mbuf *, void *, size_t); extern size_t mbuf_View(struct mbuf *, void *, size_t); -extern struct mbuf *mbuf_Prepend(struct mbuf *, const void *, size_t, size_t); -extern struct mbuf *mbuf_Truncate(struct mbuf *, size_t); +extern struct mbuf *m_prepend(struct mbuf *, const void *, size_t, size_t); +extern struct mbuf *m_adj(struct mbuf *, ssize_t); +extern struct mbuf *m_pullup(struct mbuf *); +extern void m_settype(struct mbuf *, int); +extern struct mbuf *m_append(struct mbuf *, const void *, size_t); + extern int mbuf_Show(struct cmdargs const *); -extern void mbuf_Enqueue(struct mqueue *, struct mbuf *); -extern struct mbuf *mbuf_Dequeue(struct mqueue *); -extern struct mbuf *mbuf_Contiguous(struct mbuf *); -extern void mbuf_SetType(struct mbuf *, int); + +extern void m_enqueue(struct mqueue *, struct mbuf *); +extern struct mbuf *m_dequeue(struct mqueue *); diff --git a/usr.sbin/ppp/ppp/mp.c b/usr.sbin/ppp/ppp/mp.c index c2f75acc810..65cf338a5b6 100644 --- a/usr.sbin/ppp/ppp/mp.c +++ b/usr.sbin/ppp/ppp/mp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp.c,v 1.12 1999/08/05 10:32:14 brian Exp $ + * $Id: mp.c,v 1.13 2000/01/07 03:26:55 brian Exp $ */ #include <sys/param.h> @@ -45,8 +45,8 @@ #include <unistd.h> #include "layer.h" -#ifndef NOALIAS -#include "alias_cmd.h" +#ifndef NONAT +#include "nat_cmd.h" #endif #include "vjcomp.h" #include "ua.h" @@ -278,8 +278,8 @@ mp_Init(struct mp *mp, struct bundle *bundle) link_Stack(&mp->link, &protolayer); link_Stack(&mp->link, &ccplayer); link_Stack(&mp->link, &vjlayer); -#ifndef NOALIAS - link_Stack(&mp->link, &aliaslayer); +#ifndef NONAT + link_Stack(&mp->link, &natlayer); #endif } @@ -374,8 +374,8 @@ mp_Down(struct mp *mp) /* Received fragments go in the bit-bucket */ while (mp->inbufs) { - next = mp->inbufs->pnext; - mbuf_Free(mp->inbufs); + next = mp->inbufs->m_nextpkt; + m_freem(mp->inbufs); mp->inbufs = next; } @@ -405,7 +405,7 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) */ if (m && mp_ReadHeader(mp, m, &mh) == 0) { - mbuf_Free(m); + m_freem(m); return; } @@ -449,10 +449,10 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) if (m && isbefore(mp->local_is12bit, mh.seq, h.seq)) { /* Our received fragment fits in before this one, so link it in */ if (last) - last->pnext = m; + last->m_nextpkt = m; else mp->inbufs = m; - m->pnext = q; + m->m_nextpkt = q; q = m; h = mh; m = NULL; @@ -467,8 +467,8 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) /* Zap all older fragments */ while (mp->inbufs != q) { log_Printf(LogDEBUG, "Drop frag\n"); - next = mp->inbufs->pnext; - mbuf_Free(mp->inbufs); + next = mp->inbufs->m_nextpkt; + m_freem(mp->inbufs); mp->inbufs = next; } @@ -484,9 +484,9 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) h.seq--; /* We're gonna look for fragment with h.seq+1 */ break; } - next = mp->inbufs->pnext; + next = mp->inbufs->m_nextpkt; log_Printf(LogDEBUG, "Drop frag %u\n", h.seq); - mbuf_Free(mp->inbufs); + m_freem(mp->inbufs); mp->inbufs = next; } while (mp->inbufs && (isbefore(mp->local_is12bit, mp->seq.min_in, h.seq) || h.end)); @@ -513,17 +513,17 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) do { *frag = mp->inbufs; - mp->inbufs = mp->inbufs->pnext; + mp->inbufs = mp->inbufs->m_nextpkt; len = mp_ReadHeader(mp, *frag, &h); if (first == -1) first = h.seq; - (*frag)->offset += len; - (*frag)->cnt -= len; - (*frag)->pnext = NULL; + (*frag)->m_offset += len; + (*frag)->m_len -= len; + (*frag)->m_nextpkt = NULL; if (frag == &q && !h.begin) { log_Printf(LogWARN, "Oops - MP frag %lu should have a begin flag\n", (u_long)h.seq); - mbuf_Free(q); + m_freem(q); q = NULL; } else if (frag != &q && h.begin) { log_Printf(LogWARN, "Oops - MP frag %lu should have an end flag\n", @@ -532,25 +532,25 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) * Stuff our fragment back at the front of the queue and zap * our half-assembed packet. */ - (*frag)->pnext = mp->inbufs; + (*frag)->m_nextpkt = mp->inbufs; mp->inbufs = *frag; *frag = NULL; - mbuf_Free(q); + m_freem(q); q = NULL; frag = &q; h.end = 0; /* just in case it's a whole packet */ } else do - frag = &(*frag)->next; + frag = &(*frag)->m_next; while (*frag != NULL); } while (!h.end); if (q) { - q = mbuf_Contiguous(q); + q = m_pullup(q); log_Printf(LogDEBUG, "MP: Reassembled frags %ld-%lu, length %d\n", - first, (u_long)h.seq, mbuf_Length(q)); - link_PullPacket(&mp->link, MBUF_CTOP(q), q->cnt, mp->bundle); - mbuf_Free(q); + first, (u_long)h.seq, m_length(q)); + link_PullPacket(&mp->link, MBUF_CTOP(q), q->m_len, mp->bundle); + m_freem(q); } mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq); @@ -560,24 +560,24 @@ mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) /* Look for the next fragment */ seq = inc_seq(mp->local_is12bit, seq); last = q; - q = q->pnext; + q = q->m_nextpkt; } } if (m) { /* We still have to find a home for our new fragment */ last = NULL; - for (q = mp->inbufs; q; last = q, q = q->pnext) { + for (q = mp->inbufs; q; last = q, q = q->m_nextpkt) { mp_ReadHeader(mp, q, &h); if (isbefore(mp->local_is12bit, mh.seq, h.seq)) break; } /* Our received fragment fits in here */ if (last) - last->pnext = m; + last->m_nextpkt = m; else mp->inbufs = m; - m->pnext = q; + m->m_nextpkt = q; } } @@ -592,9 +592,9 @@ mp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (p == NULL) { log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n"); - mbuf_Free(bp); + m_freem(bp); } else { - mbuf_SetType(bp, MB_MPIN); + m_settype(bp, MB_MPIN); mp_Assemble(&bundle->ncp.mp, bp, p); } @@ -605,30 +605,29 @@ static void mp_Output(struct mp *mp, struct bundle *bundle, struct link *l, struct mbuf *m, u_int32_t begin, u_int32_t end) { - struct mbuf *mo; + char prepend[4]; /* Stuff an MP header on the front of our packet and send it */ - mo = mbuf_Alloc(4, MB_MPOUT); - mo->next = m; + if (mp->peer_is12bit) { u_int16_t val; val = (begin << 15) | (end << 14) | (u_int16_t)mp->out.seq; - ua_htons(&val, MBUF_CTOP(mo)); - mo->cnt = 2; + ua_htons(&val, prepend); + m = m_prepend(m, prepend, 2, 0); } else { u_int32_t val; val = (begin << 31) | (end << 30) | (u_int32_t)mp->out.seq; - ua_htonl(&val, MBUF_CTOP(mo)); - mo->cnt = 4; + ua_htonl(&val, prepend); + m = m_prepend(m, prepend, 4, 0); } if (log_IsKept(LogDEBUG)) log_Printf(LogDEBUG, "MP[frag %d]: Send %d bytes on link `%s'\n", - mp->out.seq, mbuf_Length(mo), l->name); + mp->out.seq, m_length(m), l->name); mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq); - link_PushPacket(l, mo, bundle, PRI_NORMAL, PROTO_MP); + link_PushPacket(l, m, bundle, LINK_QUEUES(l) - 1, PROTO_MP); } int @@ -636,7 +635,8 @@ mp_FillQueues(struct bundle *bundle) { struct mp *mp = &bundle->ncp.mp; struct datalink *dl, *fdl; - int total, add, len, thislink, nlinks; + size_t total, add, len; + int thislink, nlinks; u_int32_t begin, end; struct mbuf *m, *mo; @@ -684,7 +684,7 @@ mp_FillQueues(struct bundle *bundle) break; m = link_Dequeue(&mp->link); - len = mbuf_Length(m); + len = m_length(m); begin = 1; end = 0; @@ -694,12 +694,12 @@ mp_FillQueues(struct bundle *bundle) if (len <= dl->physical->link.lcp.his_mru) { mo = m; end = 1; - mbuf_SetType(mo, MB_MPOUT); + m_settype(mo, MB_MPOUT); } else { /* It's > his_mru, chop the packet (`m') into bits */ - mo = mbuf_Alloc(dl->physical->link.lcp.his_mru, MB_MPOUT); - len -= mo->cnt; - m = mbuf_Read(m, MBUF_CTOP(mo), mo->cnt); + mo = m_get(dl->physical->link.lcp.his_mru, MB_MPOUT); + len -= mo->m_len; + m = mbuf_Read(m, MBUF_CTOP(mo), mo->m_len); } mp_Output(mp, bundle, &dl->physical->link, mo, begin, end); begin = 0; @@ -755,7 +755,7 @@ mp_ShowStatus(struct cmdargs const *arg) lm = NULL; prompt_Printf(arg->prompt, "Socket: %s\n", mp->server.socket.sun_path); - for (m = mp->inbufs; m; m = m->pnext) { + for (m = mp->inbufs; m; m = m->m_nextpkt) { bufs++; lm = m; } @@ -1006,20 +1006,8 @@ static void mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) { struct mpserver *s = descriptor2mpserver(d); - struct sockaddr in; - int fd, size; - - size = sizeof in; - fd = accept(s->fd, &in, &size); - if (fd < 0) { - log_Printf(LogERROR, "mpserver_Read: accept(): %s\n", strerror(errno)); - return; - } - if (in.sa_family == AF_LOCAL) - bundle_ReceiveDatalink(bundle, fd, (struct sockaddr_un *)&in); - else - close(fd); + bundle_ReceiveDatalink(bundle, s->fd); } static int @@ -1065,15 +1053,21 @@ mpserver_Open(struct mpserver *s, struct peerid *peer) s->socket.sun_family = AF_LOCAL; s->socket.sun_len = sizeof s->socket; - s->fd = ID0socket(PF_LOCAL, SOCK_STREAM, 0); + s->fd = ID0socket(PF_LOCAL, SOCK_DGRAM, 0); if (s->fd < 0) { - log_Printf(LogERROR, "mpserver: socket: %s\n", strerror(errno)); + log_Printf(LogERROR, "mpserver: socket(): %s\n", strerror(errno)); return MPSERVER_FAILED; } setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *)&s->socket, sizeof s->socket); mask = umask(0177); + + /* + * Try to bind the socket. If we succeed we play server, if we fail + * we connect() and hand the link off. + */ + if (ID0bind_un(s->fd, &s->socket) < 0) { if (errno != EADDRINUSE) { log_Printf(LogPHASE, "mpserver: can't create bundle socket %s (%s)\n", @@ -1083,12 +1077,14 @@ mpserver_Open(struct mpserver *s, struct peerid *peer) s->fd = -1; return MPSERVER_FAILED; } + + /* So we're the sender */ umask(mask); if (ID0connect_un(s->fd, &s->socket) < 0) { log_Printf(LogPHASE, "mpserver: can't connect to bundle socket %s (%s)\n", s->socket.sun_path, strerror(errno)); if (errno == ECONNREFUSED) - log_Printf(LogPHASE, " Has the previous server died badly ?\n"); + log_Printf(LogPHASE, " The previous server died badly !\n"); close(s->fd); s->fd = -1; return MPSERVER_FAILED; @@ -1098,13 +1094,6 @@ mpserver_Open(struct mpserver *s, struct peerid *peer) return MPSERVER_CONNECTED; } - /* Listen for other ppp invocations that want to donate links */ - if (listen(s->fd, 5) != 0) { - log_Printf(LogERROR, "mpserver: Unable to listen to socket" - " - BUNDLE overload?\n"); - mpserver_Close(s); - } - return MPSERVER_LISTENING; } diff --git a/usr.sbin/ppp/ppp/alias_cmd.c b/usr.sbin/ppp/ppp/nat_cmd.c index f072a199b53..e5e8f9afdb4 100644 --- a/usr.sbin/ppp/ppp/alias_cmd.c +++ b/usr.sbin/ppp/ppp/nat_cmd.c @@ -2,7 +2,7 @@ * The code in this file was written by Eivind Eklund <perhaps@yes.no>, * who places it in the public domain without restriction. * - * $Id: alias_cmd.c,v 1.12 1999/07/28 19:39:17 brian Exp $ + * $Id: nat_cmd.c,v 1.1 2000/01/07 03:26:55 brian Exp $ */ #include <sys/param.h> @@ -29,7 +29,7 @@ #include "defs.h" #include "command.h" #include "log.h" -#include "alias_cmd.h" +#include "nat_cmd.h" #include "descriptor.h" #include "prompt.h" #include "timer.h" @@ -52,6 +52,8 @@ #include "bundle.h" +#define NAT_EXTRABUF (13) + static int StrToAddr(const char *, struct in_addr *); static int StrToPortRange(const char *, u_short *, u_short *, const char *); static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, @@ -70,9 +72,9 @@ lowhigh(u_short *a, u_short *b) } int -alias_RedirectPort(struct cmdargs const *arg) +nat_RedirectPort(struct cmdargs const *arg) { - if (!arg->bundle->AliasEnabled) { + if (!arg->bundle->NatEnabled) { prompt_Printf(arg->prompt, "Alias not enabled\n"); return 1; } else if (arg->argc == arg->argn + 3 || arg->argc == arg->argn + 4) { @@ -101,14 +103,14 @@ alias_RedirectPort(struct cmdargs const *arg) error = StrToAddrAndPort(arg->argv[arg->argn+1], &localaddr, &llocalport, &hlocalport, proto); if (error) { - prompt_Printf(arg->prompt, "alias port: error reading localaddr:port\n"); + prompt_Printf(arg->prompt, "nat port: error reading localaddr:port\n"); return -1; } error = StrToPortRange(arg->argv[arg->argn+2], &laliasport, &haliasport, proto); if (error) { - prompt_Printf(arg->prompt, "alias port: error reading alias port\n"); + prompt_Printf(arg->prompt, "nat port: error reading alias port\n"); return -1; } aliasaddr.s_addr = INADDR_ANY; @@ -117,7 +119,7 @@ alias_RedirectPort(struct cmdargs const *arg) error = StrToAddrAndPort(arg->argv[arg->argn+3], &remoteaddr, &lremoteport, &hremoteport, proto); if (error) { - prompt_Printf(arg->prompt, "alias port: error reading " + prompt_Printf(arg->prompt, "nat port: error reading " "remoteaddr:port\n"); return -1; } @@ -131,13 +133,13 @@ alias_RedirectPort(struct cmdargs const *arg) lowhigh(&lremoteport, &hremoteport); if (haliasport - laliasport != hlocalport - llocalport) { - prompt_Printf(arg->prompt, "alias port: local & alias port ranges " + prompt_Printf(arg->prompt, "nat port: local & alias port ranges " "are not equal\n"); return -1; } if (hremoteport && hremoteport - lremoteport != hlocalport - llocalport) { - prompt_Printf(arg->prompt, "alias port: local & remote port ranges " + prompt_Printf(arg->prompt, "nat port: local & remote port ranges " "are not equal\n"); return -1; } @@ -149,7 +151,7 @@ alias_RedirectPort(struct cmdargs const *arg) proto_constant); if (link == NULL) { - prompt_Printf(arg->prompt, "alias port: %d: error %d\n", laliasport, + prompt_Printf(arg->prompt, "nat port: %d: error %d\n", laliasport, error); return 1; } @@ -167,10 +169,10 @@ alias_RedirectPort(struct cmdargs const *arg) int -alias_RedirectAddr(struct cmdargs const *arg) +nat_RedirectAddr(struct cmdargs const *arg) { - if (!arg->bundle->AliasEnabled) { - prompt_Printf(arg->prompt, "alias not enabled\n"); + if (!arg->bundle->NatEnabled) { + prompt_Printf(arg->prompt, "nat not enabled\n"); return 1; } else if (arg->argc == arg->argn+2) { int error; @@ -185,7 +187,7 @@ alias_RedirectAddr(struct cmdargs const *arg) error = StrToAddr(arg->argv[arg->argn+1], &aliasaddr); if (error) { prompt_Printf(arg->prompt, "address redirect: invalid alias address\n"); - prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, + prompt_Printf(arg->prompt, "Usage: nat %s %s\n", arg->cmd->name, arg->cmd->syntax); return 1; } @@ -193,7 +195,7 @@ alias_RedirectAddr(struct cmdargs const *arg) if (link == NULL) { prompt_Printf(arg->prompt, "address redirect: packet aliasing" " engine error\n"); - prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, + prompt_Printf(arg->prompt, "Usage: nat %s %s\n", arg->cmd->name, arg->cmd->syntax); } } else @@ -289,7 +291,7 @@ StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *low, } int -alias_ProxyRule(struct cmdargs const *arg) +nat_ProxyRule(struct cmdargs const *arg) { char cmd[LINE_LEN]; int f, pos; @@ -312,7 +314,7 @@ alias_ProxyRule(struct cmdargs const *arg) } int -alias_Pptp(struct cmdargs const *arg) +nat_Pptp(struct cmdargs const *arg) { struct in_addr addr; @@ -336,38 +338,24 @@ alias_Pptp(struct cmdargs const *arg) } static struct mbuf * -alias_PadMbuf(struct mbuf *bp, int type) -{ - struct mbuf **last; - int len; - - mbuf_SetType(bp, type); - for (last = &bp, len = 0; *last != NULL; last = &(*last)->next) - len += (*last)->cnt; - - len = MAX_MRU - len; - *last = mbuf_Alloc(len, type); - - return bp; -} - -static struct mbuf * -alias_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, +nat_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, u_short *proto) { - if (!bundle->AliasEnabled || *proto != PROTO_IP) + if (!bundle->NatEnabled || *proto != PROTO_IP) return bp; - log_Printf(LogDEBUG, "alias_LayerPush: PROTO_IP -> PROTO_IP\n"); - bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_ALIASOUT)); - PacketAliasOut(MBUF_CTOP(bp), bp->cnt); - bp->cnt = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len); + log_Printf(LogDEBUG, "nat_LayerPush: PROTO_IP -> PROTO_IP\n"); + m_settype(bp, MB_NATOUT); + /* Ensure there's a bit of extra buffer for the NAT code... */ + bp = m_pullup(m_append(bp, NULL, NAT_EXTRABUF)); + PacketAliasOut(MBUF_CTOP(bp), bp->m_len); + bp->m_len = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len); return bp; } static struct mbuf * -alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, +nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short *proto) { struct ip *pip, *piip; @@ -375,11 +363,12 @@ alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, struct mbuf **last; char *fptr; - if (!bundle->AliasEnabled || *proto != PROTO_IP) + if (!bundle->NatEnabled || *proto != PROTO_IP) return bp; - log_Printf(LogDEBUG, "alias_LayerPull: PROTO_IP -> PROTO_IP\n"); - bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_ALIASIN)); + log_Printf(LogDEBUG, "nat_LayerPull: PROTO_IP -> PROTO_IP\n"); + m_settype(bp, MB_NATIN); + bp = m_pullup(bp); pip = (struct ip *)MBUF_CTOP(bp); piip = (struct ip *)((char *)pip + (pip->ip_hl << 2)); @@ -387,12 +376,15 @@ alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, (pip->ip_p == IPPROTO_IPIP && IN_CLASSD(ntohl(piip->ip_dst.s_addr)))) return bp; - ret = PacketAliasIn(MBUF_CTOP(bp), bp->cnt); + /* Ensure there's a bit of extra buffer for the NAT code... */ + bp = m_pullup(m_append(bp, NULL, NAT_EXTRABUF)); + ret = PacketAliasIn(MBUF_CTOP(bp), bp->m_len); - bp->cnt = ntohs(pip->ip_len); - if (bp->cnt > MAX_MRU) { - log_Printf(LogWARN, "alias_LayerPull: Problem with IP header length\n"); - mbuf_Free(bp); + bp->m_len = ntohs(pip->ip_len); + if (bp->m_len > MAX_MRU) { + log_Printf(LogWARN, "nat_LayerPull: Problem with IP header length (%d)\n", + bp->m_len); + m_freem(bp); return NULL; } @@ -402,26 +394,26 @@ alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, case PKT_ALIAS_UNRESOLVED_FRAGMENT: /* Save the data for later */ - fptr = malloc(bp->cnt); - bp = mbuf_Read(bp, fptr, bp->cnt); + fptr = malloc(bp->m_len); + bp = mbuf_Read(bp, fptr, bp->m_len); PacketAliasSaveFragment(fptr); break; case PKT_ALIAS_FOUND_HEADER_FRAGMENT: /* Fetch all the saved fragments and chain them on the end of `bp' */ - last = &bp->pnext; + last = &bp->m_nextpkt; while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) { PacketAliasFragmentIn(MBUF_CTOP(bp), fptr); len = ntohs(((struct ip *)fptr)->ip_len); - *last = mbuf_Alloc(len, MB_ALIASIN); + *last = m_get(len, MB_NATIN); memcpy(MBUF_CTOP(*last), fptr, len); free(fptr); - last = &(*last)->pnext; + last = &(*last)->m_nextpkt; } break; default: - mbuf_Free(bp); + m_freem(bp); bp = NULL; break; } @@ -429,5 +421,5 @@ alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp, return bp; } -struct layer aliaslayer = - { LAYER_ALIAS, "alias", alias_LayerPush, alias_LayerPull }; +struct layer natlayer = + { LAYER_NAT, "nat", nat_LayerPush, nat_LayerPull }; diff --git a/usr.sbin/ppp/ppp/nat_cmd.h b/usr.sbin/ppp/ppp/nat_cmd.h new file mode 100644 index 00000000000..4c260592462 --- /dev/null +++ b/usr.sbin/ppp/ppp/nat_cmd.h @@ -0,0 +1,15 @@ +/*- + * The code in this file was written by Eivind Eklund <perhaps@yes.no>, + * who places it in the public domain without restriction. + * + * $Id: nat_cmd.h,v 1.1 2000/01/07 03:26:55 brian Exp $ + */ + +struct cmdargs; + +extern int nat_RedirectPort(struct cmdargs const *); +extern int nat_RedirectAddr(struct cmdargs const *); +extern int nat_ProxyRule(struct cmdargs const *); +extern int nat_Pptp(struct cmdargs const *); + +extern struct layer natlayer; diff --git a/usr.sbin/ppp/ppp/pap.c b/usr.sbin/ppp/ppp/pap.c index 64ec86308a1..eaea60e713a 100644 --- a/usr.sbin/ppp/ppp/pap.c +++ b/usr.sbin/ppp/ppp/pap.c @@ -18,7 +18,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: pap.c,v 1.11 1999/07/15 02:10:32 brian Exp $ + * $Id: pap.c,v 1.12 2000/01/07 03:26:55 brian Exp $ * * TODO: */ @@ -29,7 +29,7 @@ #include <sys/un.h> #include <stdlib.h> -#include <string.h> +#include <string.h> /* strlen/memcpy */ #include <termios.h> #include "layer.h" @@ -64,7 +64,9 @@ #include "cbcp.h" #include "datalink.h" -static const char *papcodes[] = { "???", "REQUEST", "SUCCESS", "FAILURE" }; +static const char * const papcodes[] = { + "???", "REQUEST", "SUCCESS", "FAILURE" +}; #define MAXPAPCODE (sizeof papcodes / sizeof papcodes[0] - 1) static void @@ -86,7 +88,7 @@ pap_Req(struct authinfo *authp) lh.code = PAP_REQUEST; lh.id = authp->id; lh.length = htons(plen + sizeof(struct fsmheader)); - bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_PAPOUT); + bp = m_get(plen + sizeof(struct fsmheader), MB_PAPOUT); memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); *cp++ = namelen; @@ -94,7 +96,8 @@ pap_Req(struct authinfo *authp) cp += namelen; *cp++ = keylen; memcpy(cp, bundle->cfg.auth.key, keylen); - link_PushPacket(&authp->physical->link, bp, bundle, PRI_LINK, PROTO_PAP); + link_PushPacket(&authp->physical->link, bp, bundle, + LINK_QUEUES(&authp->physical->link) - 1, PROTO_PAP); } static void @@ -110,15 +113,20 @@ SendPapCode(struct authinfo *authp, int code, const char *message) mlen = strlen(message); plen = mlen + 1; lh.length = htons(plen + sizeof(struct fsmheader)); - bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_PAPOUT); + bp = m_get(plen + sizeof(struct fsmheader), MB_PAPOUT); memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); - *cp++ = mlen; + /* + * If our message is longer than 255 bytes, truncate the length to + * 255 and send the entire message anyway. Maybe the other end will + * display it... (see pap_Input() !) + */ + *cp++ = mlen > 255 ? 255 : mlen; memcpy(cp, message, mlen); log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]); link_PushPacket(&authp->physical->link, bp, authp->physical->dl->bundle, - PRI_LINK, PROTO_PAP); + LINK_QUEUES(&authp->physical->link) - 1, PROTO_PAP); } static void @@ -157,17 +165,19 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) struct physical *p = link2physical(l); struct authinfo *authp = &p->dl->pap; u_char nlen, klen, *key; + const char *txt; + int txtlen; if (p == NULL) { log_Printf(LogERROR, "pap_Input: Not a physical link - dropped\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } if (bundle_Phase(bundle) != PHASE_NETWORK && bundle_Phase(bundle) != PHASE_AUTHENTICATE) { log_Printf(LogPHASE, "Unexpected pap input - dropped !\n"); - mbuf_Free(bp); + m_freem(bp); return NULL; } @@ -179,7 +189,7 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) { log_Printf(LogPHASE, "Pap Input: %d: Bad PAP code !\n", authp->in.hdr.code); - mbuf_Free(bp); + m_freem(bp); return NULL; } @@ -188,19 +198,35 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) /* Wrong conversation dude ! */ log_Printf(LogPHASE, "Pap Input: %s dropped (got id %d, not %d)\n", papcodes[authp->in.hdr.code], authp->in.hdr.id, authp->id); - mbuf_Free(bp); + m_freem(bp); return NULL; } - mbuf_SetType(bp, MB_PAPIN); + m_settype(bp, MB_PAPIN); authp->id = authp->in.hdr.id; /* We respond with this id */ if (bp) { bp = mbuf_Read(bp, &nlen, 1); - bp = auth_ReadName(authp, bp, nlen); + if (authp->in.hdr.code == PAP_ACK) { + /* + * Don't restrict the length of our acknowledgement freetext to + * nlen (a one-byte length). Show the rest of the ack packet + * instead. This isn't really part of the protocol..... + */ + bp = m_pullup(bp); + txt = MBUF_CTOP(bp); + txtlen = m_length(bp); + } else { + bp = auth_ReadName(authp, bp, nlen); + txt = authp->in.name; + txtlen = strlen(authp->in.name); + } + } else { + txt = ""; + txtlen = 0; } - log_Printf(LogPHASE, "Pap Input: %s (%s)\n", - papcodes[authp->in.hdr.code], authp->in.name); + log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n", + papcodes[authp->in.hdr.code], txtlen, txt); switch (authp->in.hdr.code) { case PAP_REQUEST: @@ -209,7 +235,7 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) break; } bp = mbuf_Read(bp, &klen, 1); - if (mbuf_Length(bp) < klen) { + if (m_length(bp) < klen) { log_Printf(LogERROR, "Pap Input: Truncated key !\n"); break; } @@ -254,6 +280,6 @@ pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) break; } - mbuf_Free(bp); + m_freem(bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/physical.c b/usr.sbin/ppp/ppp/physical.c index 1025f4460ed..e573929dbdb 100644 --- a/usr.sbin/ppp/ppp/physical.c +++ b/usr.sbin/ppp/ppp/physical.c @@ -16,15 +16,12 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: physical.c,v 1.17 1999/08/05 10:32:14 brian Exp $ + * $Id: physical.c,v 1.18 2000/01/07 03:26:55 brian Exp $ * */ #include <sys/param.h> -#include <sys/socket.h> #include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <sys/un.h> @@ -37,7 +34,6 @@ #include <string.h> #include <sys/tty.h> /* TIOCOUTQ */ #include <sys/uio.h> -#include <sys/wait.h> #include <time.h> #include <unistd.h> #include <utmp.h> @@ -49,8 +45,8 @@ #endif #include "layer.h" -#ifndef NOALIAS -#include "alias_cmd.h" +#ifndef NONAT +#include "nat_cmd.h" #endif #include "proto.h" #include "acf.h" @@ -91,12 +87,18 @@ #include "udp.h" #include "exec.h" #include "tty.h" +#ifndef NOI4B +#include "i4b.h" +#endif +#ifndef NONETGRAPH +#include "ether.h" +#endif +#define PPPOTCPLINE "ppp" + static int physical_DescriptorWrite(struct descriptor *, struct bundle *, const fd_set *); -static void physical_DescriptorRead(struct descriptor *, struct bundle *, - const fd_set *); static int physical_DeviceSize(void) @@ -106,11 +108,18 @@ physical_DeviceSize(void) struct { struct device *(*create)(struct physical *); - struct device *(*iov2device)(int, struct physical *, struct iovec *iov, - int *niov, int maxiov); + struct device *(*iov2device)(int, struct physical *, struct iovec *, + int *, int, int *, int *); int (*DeviceSize)(void); } devices[] = { +#ifndef NOI4B + { i4b_Create, i4b_iov2device, i4b_DeviceSize }, +#endif { tty_Create, tty_iov2device, tty_DeviceSize }, +#ifndef NONETGRAPH + /* This must come before ``udp'' & ``tcp'' */ + { ether_Create, ether_iov2device, ether_DeviceSize }, +#endif { tcp_Create, tcp_iov2device, tcp_DeviceSize }, { udp_Create, udp_iov2device, udp_DeviceSize }, { exec_Create, exec_iov2device, exec_DeviceSize } @@ -125,6 +134,16 @@ physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, return physical_doUpdateSet(d, r, w, e, n, 0); } +void +physical_SetDescriptor(struct physical *p) +{ + p->desc.type = PHYSICAL_DESCRIPTOR; + p->desc.UpdateSet = physical_UpdateSet; + p->desc.IsSet = physical_IsSet; + p->desc.Read = physical_DescriptorRead; + p->desc.Write = physical_DescriptorWrite; +} + struct physical * physical_Create(struct datalink *dl, int type) { @@ -147,11 +166,7 @@ physical_Create(struct datalink *dl, int type) link_EmptyStack(&p->link); p->handler = NULL; - p->desc.type = PHYSICAL_DESCRIPTOR; - p->desc.UpdateSet = physical_UpdateSet; - p->desc.IsSet = physical_IsSet; - p->desc.Read = physical_DescriptorRead; - p->desc.Write = physical_DescriptorWrite; + physical_SetDescriptor(p); p->type = type; hdlc_Init(&p->hdlc, &p->link.lcp); @@ -173,8 +188,8 @@ physical_Create(struct datalink *dl, int type) p->cfg.parity = CS8; memcpy(p->cfg.devlist, MODEM_LIST, sizeof MODEM_LIST); p->cfg.ndev = NMODEMS; - p->cfg.cd.required = 0; - p->cfg.cd.delay = DEF_CDDELAY; + p->cfg.cd.necessity = CD_DEFAULT; + p->cfg.cd.delay = 0; /* reconfigured or device specific default */ lcp_Init(&p->link.lcp, dl->bundle, &p->link, &dl->fsmp); ccp_Init(&p->link.ccp, dl->bundle, &p->link, &dl->fsmp); @@ -308,7 +323,12 @@ physical_Close(struct physical *p) physical_StopDeviceTimer(p); if (p->Utmp) { - ID0logout(p->name.base); + if (p->handler && (p->handler->type == TCP_DEVICE || + p->handler->type == UDP_DEVICE)) + /* Careful - we logged in on line ``ppp'' with IP as our host */ + ID0logout(PPPOTCPLINE, 1); + else + ID0logout(p->name.base, 0); p->Utmp = 0; } newsid = tcgetpgrp(p->fd) == getpgrp(); @@ -364,14 +384,14 @@ physical_DescriptorWrite(struct descriptor *d, struct bundle *bundle, p->out = link_Dequeue(&p->link); if (p->out) { - nw = physical_Write(p, MBUF_CTOP(p->out), p->out->cnt); + nw = physical_Write(p, MBUF_CTOP(p->out), p->out->m_len); log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%d) to %d\n", - p->link.name, nw, p->out->cnt, p->fd); + p->link.name, nw, p->out->m_len, p->fd); if (nw > 0) { - p->out->cnt -= nw; - p->out->offset += nw; - if (p->out->cnt == 0) - p->out = mbuf_FreeSeg(p->out); + p->out->m_len -= nw; + p->out->m_offset += nw; + if (p->out->m_len == 0) + p->out = m_free(p->out); result = 1; } else if (nw < 0) { if (errno != EAGAIN) { @@ -391,6 +411,7 @@ int physical_ShowStatus(struct cmdargs const *arg) { struct physical *p = arg->cx->physical; + struct cd *cd; const char *dev; int n; @@ -416,8 +437,8 @@ physical_ShowStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, " Physical outq: %d\n", n); #endif - prompt_Printf(arg->prompt, " Queued Packets: %d\n", - link_QueueLen(&p->link)); + prompt_Printf(arg->prompt, " Queued Packets: %lu\n", + (u_long)link_QueueLen(&p->link)); prompt_Printf(arg->prompt, " Phone Number: %s\n", arg->cx->phone.chosen); prompt_Printf(arg->prompt, "\nDefaults:\n"); @@ -455,19 +476,26 @@ physical_ShowStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, ", CTS/RTS %s\n", (p->cfg.rts_cts ? "on" : "off")); - prompt_Printf(arg->prompt, " CD check delay: %d second%s", - p->cfg.cd.delay, p->cfg.cd.delay == 1 ? "" : "s"); - if (p->cfg.cd.required) - prompt_Printf(arg->prompt, " (required!)\n\n"); - else - prompt_Printf(arg->prompt, "\n\n"); + prompt_Printf(arg->prompt, " CD check delay: "); + cd = p->handler ? &p->handler->cd : &p->cfg.cd; + if (cd->necessity == CD_NOTREQUIRED) + prompt_Printf(arg->prompt, "no cd"); + else if (p->cfg.cd.necessity == CD_DEFAULT) { + prompt_Printf(arg->prompt, "device specific"); + } else { + prompt_Printf(arg->prompt, "%d second%s", p->cfg.cd.delay, + p->cfg.cd.delay == 1 ? "" : "s"); + if (p->cfg.cd.necessity == CD_REQUIRED) + prompt_Printf(arg->prompt, " (required!)"); + } + prompt_Printf(arg->prompt, "\n\n"); throughput_disp(&p->link.throughput, arg->prompt); return 0; } -static void +void physical_DescriptorRead(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) { @@ -522,7 +550,7 @@ physical_DescriptorRead(struct descriptor *d, struct bundle *bundle, struct physical * iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, - int fd) + int fd, int *auxfd, int *nauxfd) { struct physical *p; int len, h, type; @@ -572,11 +600,10 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, type = (long)p->handler; p->handler = NULL; for (h = 0; h < NDEVICES && p->handler == NULL; h++) - p->handler = (*devices[h].iov2device)(type, p, iov, niov, maxiov); - + p->handler = (*devices[h].iov2device)(type, p, iov, niov, maxiov, + auxfd, nauxfd); if (p->handler == NULL) { - log_Printf(LogPHASE, "%s: Device %s, unknown link type\n", - p->link.name, p->name.full); + log_Printf(LogPHASE, "%s: Unknown link type\n", p->link.name); free(iov[(*niov)++].iov_base); physical_SetupStack(p, "unknown", PHYSICAL_NOFORCE); } else @@ -611,7 +638,7 @@ physical_MaxDeviceSize() int physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, - pid_t newpid) + int *auxfd, int *nauxfd) { struct device *h; int sz; @@ -627,8 +654,7 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, timer_Stop(&p->link.lcp.fsm.StoppedTimer); timer_Stop(&p->link.ccp.fsm.StoppedTimer); if (p->handler) { - if (p->handler->device2iov) - h = p->handler; + h = p->handler; p->handler = (struct device *)(long)p->handler->type; } @@ -638,7 +664,6 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, else p->session_owner = (pid_t)-1; timer_Stop(&p->link.throughput.Timer); - physical_ChangedPid(p, newpid); } if (*niov + 2 >= maxiov) { @@ -649,28 +674,27 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, return -1; } - iov[*niov].iov_base = p ? (void *)p : malloc(sizeof *p); + iov[*niov].iov_base = (void *)p; iov[*niov].iov_len = sizeof *p; (*niov)++; - iov[*niov].iov_base = p ? (void *)p->link.throughput.SampleOctets : - malloc(SAMPLE_PERIOD * sizeof(long long)); + iov[*niov].iov_base = p ? (void *)p->link.throughput.SampleOctets : NULL; iov[*niov].iov_len = SAMPLE_PERIOD * sizeof(long long); (*niov)++; sz = physical_MaxDeviceSize(); if (p) { - if (h) - (*h->device2iov)(h, iov, niov, maxiov, newpid); + if (h && h->device2iov) + (*h->device2iov)(h, iov, niov, maxiov, auxfd, nauxfd); else { iov[*niov].iov_base = malloc(sz); - if (p->handler) - memcpy(iov[*niov].iov_base, p->handler, sizeof *p->handler); + if (h) + memcpy(iov[*niov].iov_base, h, sizeof *h); iov[*niov].iov_len = sz; (*niov)++; } } else { - iov[*niov].iov_base = malloc(sz); + iov[*niov].iov_base = NULL; iov[*niov].iov_len = sz; (*niov)++; } @@ -678,10 +702,19 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, return p ? p->fd : 0; } +const char * +physical_LockedDevice(struct physical *p) +{ + if (p->fd >= 0 && *p->name.full == '/' && p->type != PHYS_DIRECT) + return p->name.base; + + return NULL; +} + void physical_ChangedPid(struct physical *p, pid_t newpid) { - if (p->fd >= 0 && *p->name.full == '/' && p->type != PHYS_DIRECT) { + if (physical_LockedDevice(p)) { int res; if ((res = ID0uu_lock_txfr(p->name.base, newpid)) != UU_LOCK_OK) @@ -788,28 +821,32 @@ physical_doUpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) { - int sets; + if (p->handler && p->handler->removefromset) + return (*p->handler->removefromset)(p, r, w, e); + else { + int sets; - sets = 0; - if (p->fd >= 0) { - if (r && FD_ISSET(p->fd, r)) { - FD_CLR(p->fd, r); - log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd); - sets++; - } - if (e && FD_ISSET(p->fd, e)) { - FD_CLR(p->fd, e); - log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd); - sets++; - } - if (w && FD_ISSET(p->fd, w)) { - FD_CLR(p->fd, w); - log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd); - sets++; + sets = 0; + if (p->fd >= 0) { + if (r && FD_ISSET(p->fd, r)) { + FD_CLR(p->fd, r); + log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd); + sets++; + } + if (e && FD_ISSET(p->fd, e)) { + FD_CLR(p->fd, e); + log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd); + sets++; + } + if (w && FD_ISSET(p->fd, w)) { + FD_CLR(p->fd, w); + log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd); + sets++; + } } + + return sets; } - - return sets; } int @@ -825,16 +862,25 @@ physical_Login(struct physical *p, const char *name) if (p->type == PHYS_DIRECT && *p->name.base && !p->Utmp) { struct utmp ut; const char *connstr; + char *colon; memset(&ut, 0, sizeof ut); time(&ut.ut_time); strncpy(ut.ut_name, name, sizeof ut.ut_name); - strncpy(ut.ut_line, p->name.base, sizeof ut.ut_line); + if (p->handler && (p->handler->type == TCP_DEVICE || + p->handler->type == UDP_DEVICE)) { + strncpy(ut.ut_line, PPPOTCPLINE, sizeof ut.ut_line); + strncpy(ut.ut_host, p->name.base, sizeof ut.ut_host); + colon = memchr(ut.ut_host, ':', sizeof ut.ut_host); + if (colon) + *colon = '\0'; + } else + strncpy(ut.ut_line, p->name.base, sizeof ut.ut_line); if ((connstr = getenv("CONNECT"))) /* mgetty sets this to the connection speed */ strncpy(ut.ut_host, connstr, sizeof ut.ut_host); ID0login(&ut); - p->Utmp = 1; + p->Utmp = ut.ut_time; } } @@ -844,6 +890,7 @@ physical_SetMode(struct physical *p, int mode) if ((p->type & (PHYS_DIRECT|PHYS_DEDICATED) || mode & (PHYS_DIRECT|PHYS_DEDICATED)) && (!(p->type & PHYS_DIRECT) || !(mode & PHYS_BACKGROUND))) { + /* Note: The -direct -> -background is for callback ! */ log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name, mode2Nam(p->type), mode2Nam(mode)); return 0; @@ -856,7 +903,7 @@ void physical_DeleteQueue(struct physical *p) { if (p->out) { - mbuf_Free(p->out); + m_freem(p->out); p->out = NULL; } link_DeleteQueue(&p->link); @@ -907,7 +954,7 @@ physical_Found(struct physical *p) int physical_Open(struct physical *p, struct bundle *bundle) { - int devno, h, wasopen, err; + int devno, h, wasfd, err; char *dev; if (p->fd >= 0) @@ -917,7 +964,7 @@ physical_Open(struct physical *p, struct bundle *bundle) physical_SetDevice(p, ""); p->fd = STDIN_FILENO; for (h = 0; h < NDEVICES && p->handler == NULL && p->fd >= 0; h++) - p->handler = (*devices[h].create)(p); + p->handler = (*devices[h].create)(p); if (p->fd >= 0) { if (p->handler == NULL) { physical_SetupStack(p, "unknown", PHYSICAL_NOFORCE); @@ -939,10 +986,9 @@ physical_Open(struct physical *p, struct bundle *bundle) err = errno; } - wasopen = p->fd >= 0; + wasfd = p->fd; for (h = 0; h < NDEVICES && p->handler == NULL; h++) - if ((p->handler = (*devices[h].create)(p)) == NULL && - wasopen && p->fd == -1) + if ((p->handler = (*devices[h].create)(p)) == NULL && wasfd != p->fd) break; if (p->fd < 0) { @@ -952,7 +998,7 @@ physical_Open(struct physical *p, struct bundle *bundle) strerror(errno)); else log_Printf(LogWARN, "%s: Device (%s) must begin with a '/'," - " a '!' or be a host:port pair\n", p->link.name, + " a '!' or contain at least one ':'\n", p->link.name, p->name.full); } physical_Unlock(p); @@ -971,20 +1017,21 @@ void physical_SetupStack(struct physical *p, const char *who, int how) { link_EmptyStack(&p->link); - if (how == PHYSICAL_FORCE_SYNC || + if (how == PHYSICAL_FORCE_SYNC || how == PHYSICAL_FORCE_SYNCNOACF || (how == PHYSICAL_NOFORCE && physical_IsSync(p))) link_Stack(&p->link, &synclayer); else { link_Stack(&p->link, &asynclayer); link_Stack(&p->link, &hdlclayer); } - link_Stack(&p->link, &acflayer); + if (how != PHYSICAL_FORCE_SYNCNOACF) + link_Stack(&p->link, &acflayer); link_Stack(&p->link, &protolayer); link_Stack(&p->link, &lqrlayer); link_Stack(&p->link, &ccplayer); link_Stack(&p->link, &vjlayer); -#ifndef NOALIAS - link_Stack(&p->link, &aliaslayer); +#ifndef NONAT + link_Stack(&p->link, &natlayer); #endif if (how == PHYSICAL_FORCE_ASYNC && physical_IsSync(p)) { log_Printf(LogWARN, "Sync device setting ignored for ``%s'' device\n", who); @@ -1002,3 +1049,12 @@ physical_StopDeviceTimer(struct physical *p) if (p->handler && p->handler->stoptimer) (*p->handler->stoptimer)(p); } + +int +physical_AwaitCarrier(struct physical *p) +{ + if (p->handler && p->handler->awaitcarrier) + return (*p->handler->awaitcarrier)(p); + + return CARRIER_OK; +} diff --git a/usr.sbin/ppp/ppp/physical.h b/usr.sbin/ppp/ppp/physical.h index 0accbd6af58..fd4063c1c1a 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. * - * $Id: physical.h,v 1.13 1999/07/15 02:10:32 brian Exp $ + * $Id: physical.h,v 1.14 2000/01/07 03:26:55 brian Exp $ * */ @@ -28,15 +28,37 @@ struct bundle; struct ccp; struct cmdargs; -#define TTY_DEVICE 1 -#define TCP_DEVICE 2 -#define UDP_DEVICE 3 -#define EXEC_DEVICE 4 +/* Device types (don't use zero, it'll be confused with NULL in physical2iov */ +#define I4B_DEVICE 1 +#define TTY_DEVICE 2 +#define TCP_DEVICE 3 +#define UDP_DEVICE 4 +#define ETHER_DEVICE 5 +#define EXEC_DEVICE 6 + +/* Returns from awaitcarrier() */ +#define CARRIER_PENDING 1 +#define CARRIER_OK 2 +#define CARRIER_LOST 3 + +/* A cd ``necessity'' value */ +#define CD_VARIABLE 0 +#define CD_REQUIRED 1 +#define CD_NOTREQUIRED 2 +#define CD_DEFAULT 3 + +struct cd { + unsigned necessity : 2; /* A CD_ value */ + int delay; /* Wait this many seconds after login script */ +}; struct device { int type; const char *name; + struct cd cd; + int (*awaitcarrier)(struct physical *); + int (*removefromset)(struct physical *, fd_set *, fd_set *, fd_set *); int (*raw)(struct physical *); void (*offline)(struct physical *); void (*cooked)(struct physical *); @@ -44,7 +66,7 @@ struct device { void (*destroy)(struct physical *); ssize_t (*read)(struct physical *, void *, size_t); ssize_t (*write)(struct physical *, const void *, size_t); - void (*device2iov)(struct device *, struct iovec *, int *, int, pid_t); + void (*device2iov)(struct device *, struct iovec *, int *, int, int *, int *); int (*speed)(struct physical *); const char *(*openinfo)(struct physical *); }; @@ -70,7 +92,7 @@ struct physical { char *base; } name; - unsigned Utmp : 1; /* Are we in utmp ? (move to ttydevice ?) */ + time_t Utmp; /* Are we in utmp ? */ pid_t session_owner; /* HUP this when closing the link */ struct device *handler; /* device specific handler */ @@ -82,10 +104,7 @@ struct physical { char devlist[LINE_LEN]; /* NUL separated list of devices */ int ndev; /* number of devices in list */ - struct { - unsigned required : 1; /* Is cd *REQUIRED* on this device */ - int delay; /* Wait this many seconds after login script */ - } cd; + struct cd cd; } cfg; }; @@ -98,9 +117,10 @@ struct physical { #define descriptor2physical(d) \ ((d)->type == PHYSICAL_DESCRIPTOR ? field2phys(d, desc) : NULL) -#define PHYSICAL_NOFORCE 1 -#define PHYSICAL_FORCE_ASYNC 2 -#define PHYSICAL_FORCE_SYNC 3 +#define PHYSICAL_NOFORCE 1 +#define PHYSICAL_FORCE_ASYNC 2 +#define PHYSICAL_FORCE_SYNC 3 +#define PHYSICAL_FORCE_SYNCNOACF 4 extern struct physical *physical_Create(struct datalink *, int); extern int physical_Open(struct physical *, struct bundle *); @@ -115,8 +135,10 @@ extern void physical_Offline(struct physical *); extern void physical_Close(struct physical *); extern void physical_Destroy(struct physical *); extern struct physical *iov2physical(struct datalink *, struct iovec *, int *, - int, int); -extern int physical2iov(struct physical *, struct iovec *, int *, int, pid_t); + int, int, int *, int *); +extern int physical2iov(struct physical *, struct iovec *, int *, int, int *, + int *); +extern const char *physical_LockedDevice(struct physical *); extern void physical_ChangedPid(struct physical *, pid_t); extern int physical_IsSync(struct physical *); @@ -129,6 +151,8 @@ extern ssize_t physical_Write(struct physical *, const void *, size_t); extern int physical_doUpdateSet(struct descriptor *, fd_set *, fd_set *, fd_set *, int *, int); extern int physical_IsSet(struct descriptor *, const fd_set *); +extern void physical_DescriptorRead(struct descriptor *, struct bundle *, + const fd_set *); extern void physical_Login(struct physical *, const char *); extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *, fd_set *); @@ -137,3 +161,5 @@ extern void physical_DeleteQueue(struct physical *); extern void physical_SetupStack(struct physical *, const char *, int); extern void physical_StopDeviceTimer(struct physical *); extern int physical_MaxDeviceSize(void); +extern int physical_AwaitCarrier(struct physical *); +extern void physical_SetDescriptor(struct physical *); diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index c43f7c54df1..04388838b4e 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,15 +1,17 @@ -.\" $Id: ppp.8,v 1.71 1999/10/05 20:53:10 aaron Exp $ +.\" $Id: ppp.8,v 1.72 2000/01/07 03:26:55 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Dt PPP 8 .Os .Sh NAME .Nm ppp -.Nd Point to Point Protocol (a.k.a. user-ppp) +.Nd Point to Point Protocol (a.k.a. user-ppp) .Sh SYNOPSIS -.Nm ppp -.Op Fl alias +.Nm .Op Fl Va mode +.Op Fl nat +.Op Fl quiet +.Op Fl unit Ns Ar N .Op Ar system Ns .No ... .Sh DESCRIPTION @@ -26,18 +28,42 @@ is done as a user process with the help of the tunnel device driver (tun). .Pp The +.Fl nat +flag (or .Fl alias -flag does the equivalent of an -.Dq alias enable yes , +flag for backwards compatability) does the equivalent of a +.Dq nat enable yes , enabling .Nm ppp Ns No s -packet aliasing features. This allows +network address translation features. This allows .Nm ppp to act as a NAT or masquerading engine for all machines on an internal LAN. Refer to .Xr libalias 3 for details. .Pp +The +.Fl quiet +flag tells +.Nm +to be silent at startup rather than displaying the mode and interface +to standard output. +.Pp +The +.Fl unit +flag tells +.Nm +to only attempt to open +.Pa /dev/tun Ns Ar N . +Normally, +.Nm +will start with a value of 0 for +.Ar N , +and keep trying to open a tunnel device by incrementing the value of +.Ar N +by one each time until it succeeds. If it fails three times in a row +because the device file is missing, it gives up. +.Pp The following .Va mode Ns No s are understood by @@ -81,6 +107,14 @@ goes into the background and the parent process returns an exit code of 0. If it fails, .Nm exits with a non-zero result. +.It Fl foreground +In foreground mode, +.Nm +attempts to establish a connection with the peer immediately, but never +becomes a daemon. The link is created in background mode. This is useful +if you wish to control +.Nm ppp Ns No s +invocation from another process. .It Fl direct This is used for receiving incoming connections. .Nm @@ -172,7 +206,7 @@ will force it to exit. .Nm can use either the standard LCP callback protocol or the Microsoft CallBack Control Protocol (ftp://ftp.microsoft.com/developr/rfc/cbcp.txt). -.It Supports packet aliasing. +.It Supports NAT or packet aliasing. Packet aliasing (a.k.a. IP masquerading) allows computers on a private, unregistered network to access the Internet. The .Em PPP @@ -243,12 +277,39 @@ link. .It Supports PPP over TCP and PPP over UDP. If a device name is specified as .Em host Ns No : Ns Em port Ns -.Op / Ns Em tcp Ns No | Ns Em udp , +.Xo +.Op / Ns tcp|udp , +.Xc .Nm will open a TCP or UDP connection for transporting data rather than using a conventional serial device. UDP connections force .Nm into synchronous mode. +.It Supports PPP over ISDN. +If +.Nm +is given a raw B-channel i4b device to open as a link, it's able to talk +to the +.Xr isdnd 8 +daemon to establish an ISDN connection. +.It Supports PPP over Ethernet (rfc 2516). +If +.Nm +is given a device specification of the format +.No PPPoE: Ns Ar iface Ns Xo +.Op \&: Ns Ar provider Ns +.Xc +and if +.Xr netgraph 4 +is available, +.Nm +will attempt talk +.Em PPP +over Ethernet to +.Ar provider +using the +.Ar iface +network interface. .It "Supports IETF draft Predictor-1 (rfc 1978) and DEFLATE (rfc 1979) compression." .Nm supports not only VJ-compression but also Predictor-1 and DEFLATE compression. @@ -281,23 +342,24 @@ and group .Dv network , with permissions .Dv 04554 . -By default, +By default, .Nm -will not run if the invoking user ID is not 0. This may be overridden +will not run if the invoking user id is not zero. This may be overridden by using the .Dq allow users command in .Pa /etc/ppp/ppp.conf . When running as a normal user, .Nm -switches to user ID 0 in order to alter the system routing table, set up +switches to user id 0 in order to alter the system routing table, set up system lock files and read the ppp configuration files. All external commands (executed via the "shell" or "!bg" commands) are executed -as the user ID that invoked +as the user id that invoked .Nm ppp . Refer to the .Sq ID0 -logging facility if you're interested in what exactly is done as user ID 0. +logging facility if you're interested in what exactly is done as user id +zero. .Sh GETTING STARTED When you first run .Nm @@ -344,7 +406,7 @@ command in .It Create a log file. .Nm -uses +uses .Xr syslog 3 to log information. A common log file name is .Pa /var/log/ppp.log . @@ -484,7 +546,7 @@ Defaults: Connect time: 0 secs 0 octets in, 0 octets out Overall 0 bytes/sec -ppp ON awfulhak> +ppp ON awfulhak> .Ed .Pp The term command can now be used to talk directly to the device: @@ -1066,6 +1128,7 @@ and .Dq set nbns commands. Refer to their descriptions below. .El +.Pp .Sh RECEIVING INCOMING PPP CONNECTIONS (Method 2) This method differs in that we use .Nm ppp @@ -1317,10 +1380,13 @@ from "tcp" to "udp". When using UDP as a transport, .Nm will operate in synchronous mode. This is another gain as the incoming data does not have to be rearranged into packets. -.Sh PACKET ALIASING +.Pp +.Sh NETWORK ADDRESS TRANSLATION (PACKET ALIASING) The -.Fl alias -command line option enables packet aliasing. This allows the +.Fl nat +.Pq \&or Fl alias +command line option enables network address translation (a.k.a. packet +aliasing). This allows the .Nm host to act as a masquerading gateway for other computers over a local area network. Outgoing IP packets are aliased so that @@ -1333,9 +1399,9 @@ subnets to have Internet access, although they are invisible from the outside world. In general, correct .Nm -operation should first be verified with packet aliasing disabled. -Then, the -.Fl alias +operation should first be verified with network address translation disabled. +Then, the +.Fl nat option should be switched on, and network applications (web browser, .Xr telnet 1 , .Xr ftp 1 , @@ -1675,6 +1741,7 @@ is established. 192.244.177.2/0 means that I'll accept/permit any IP address but I'll try to insist that 192.244.177.2 be used first. .El +.Pp .Sh CONNECTING WITH YOUR INTERNET SERVICE PROVIDER The following steps should be taken when connecting to your ISP: .Bl -enum @@ -1935,7 +2002,8 @@ Generate a CCP packet trace. .It Li Chat Generate .Sq dial , -.Sq login +.Sq login , +.Sq logout and .Sq hangup chat script trace logs. @@ -1949,7 +2017,7 @@ Log debug information. .It Li HDLC Dump HDLC packet in hex. .It Li ID0 -Log all function calls specifically made as user ID 0. +Log all function calls specifically made as user id 0. .It Li IPCP Generate an IPCP packet trace. .It Li LCP @@ -2047,6 +2115,7 @@ This signal, tells to close any existing server socket, dropping all existing diagnostic connections. .El +.Pp .Sh MULTI-LINK PPP If you wish to use more than one physical link to connect to a .Em PPP @@ -2057,7 +2126,7 @@ protocol. Refer to RFC 1990 for specification details. The peer is identified using a combination of his .Dq endpoint discriminator and his -.Dq authentication ID . +.Dq authentication id . Either or both of these may be specified. It is recommended that at least one is specified, otherwise there is no way of ensuring that all links are actually connected to the same peer program, and some @@ -2609,7 +2678,7 @@ layer shuts down, and is also available using the .Dq show command. Throughput statistics are available at the .Dq IPCP -and +and .Dq physical levels. .It utmp @@ -2625,24 +2694,24 @@ not to make any utmp or wtmp entries. This is usually only necessary if you require the user to both login and authenticate themselves. .It iface-alias Default: Enabled if -.Fl alias +.Fl nat is specified. This option simply tells .Nm to add new interface addresses to the interface rather than replacing them. -The option can only be enabled if IP aliasing is enabled -.Pq Dq alias enable yes . +The option can only be enabled if network address translation is enabled +.Pq Dq nat enable yes . .Pp With this option enabled, .Nm -will pass traffic for old interface addresses through the IP alias engine +will pass traffic for old interface addresses through the NAT engine .Pq see Xr libalias 5 , resulting in the ability (in .Fl auto mode) to properly connect the process that caused the PPP link to come up in the first place. .Pp -Disabling IP aliasing with -.Dq alias enable no +Disabling NAT with +.Dq nat enable no will also disable .Sq iface-alias . .El @@ -2728,13 +2797,13 @@ in .Fl background mode. .Pp -User ID 0 is immune to these commands. +User id 0 is immune to these commands. .Bl -tag -width XX .It allow user Ns Xo .Op s .Ar logname Ns No ... .Xc -By default, only user ID 0 is allowed access to +By default, only user id 0 is allowed access to .Nm ppp . If this command is used, all of the listed users are allowed access to the section in which the @@ -2784,36 +2853,46 @@ When running in multi-link mode, a section can be loaded if it allows of the currently existing line modes. .El .Pp -.It alias Ar command Op Ar args -This command allows the control of the aliasing (or masquerading) -facilities that are built into +.It nat Ar command Op Ar args +This command allows the control of the network address translation (also +known as masquerading or IP aliasing) facilities that are built into .Nm ppp . -If aliasing is enabled on your system (it may be omitted at compile time), +NAT is done on the external interface only, and is unlikely to make sense +if used with the +.Fl direct +flag. +.Pp +For backwards compatibility, the word +.Dq alias +may be used in place of +.Dq nat . +If nat is enabled on your system (it may be omitted at compile time), the following commands are possible: .Bl -tag -width XX -.It alias enable Op yes|no -This command either switches aliasing on or turns it off. +.It nat enable yes|no +This command either switches network address translation on or turns it off. The -.Fl alias +.Fl nat command line flag is synonymous with -.Dq alias enable yes . -.It alias addr Op Ar addr_local addr_alias +.Dq nat enable yes . +.It nat addr Op Ar addr_local addr_alias This command allows data for .Ar addr_alias to be redirected to .Ar addr_local . It is useful if you own a small number of real IP numbers that you wish to map to specific machines behind your gateway. -.It alias deny_incoming Op yes|no +.It nat deny_incoming yes|no If set to yes, this command will refuse all incoming connections by dropping the packets in much the same way as a firewall would. -.It alias help|? -This command gives a summary of available alias commands. -.It alias log Op yes|no -This option causes various aliasing statistics and information to +.It nat help|? +This command gives a summary of available nat commands. +.It nat log yes|no +This option causes various NAT statistics and information to be logged to the file .Pa /var/log/alias.log . -.It alias port Ar proto Ar targetIP Ns Xo +This file name is likely to change in the near future. +.It nat port Ar proto Ar targetIP Ns Xo .No : Ns Ar targetPort Ns .Oo .No - Ns Ar targetPort @@ -2855,10 +2934,10 @@ or a range of ports the same size as the other ranges. This option is useful if you wish to run things like Internet phone on machines behind your gateway, but is limited in that connections to only one interior machine per source machine and target port are possible. -.It alias pptp Op Ar addr +.It nat pptp Op Ar addr This tells .Nm -to alias any +to translate any .Em G Ns No eneral .Em R Ns No outing .Em E Ns No encapsulated @@ -2877,8 +2956,8 @@ If .Ar addr is not specified, .Dv PPTP -aliasing is disabled. -.It "alias proxy cmd" Ar arg Ns No ... +address translation is disabled. +.It "nat proxy cmd" Ar arg Ns No ... This command tells .Nm to proxy certain connections, redirecting them to a given server. Refer @@ -2887,16 +2966,16 @@ to the description of in .Xr libalias 3 for details of the available commands. -.It alias same_ports Op yes|no -When enabled, this command will tell the alias library attempt to -avoid changing the port number on outgoing packets. This is useful +.It nat same_ports yes|no +When enabled, this command will tell the network address translation engine to + attempt to avoid changing the port number on outgoing packets. This is useful if you want to support protocols such as RPC and LPD which require connections to come from a well known port. -.It alias use_sockets Op yes|no -When enabled, this option tells the alias library to create a -socket so that it can guarantee a correct incoming ftp data or +.It nat use_sockets yes|no +When enabled, this option tells the network address translation engine to +create a socket so that it can guarantee a correct incoming ftp data or IRC connection. -.It alias unregistered_only Op yes|no +.It nat unregistered_only yes|no Only alter outgoing packets with an unregistered source ad- dress. According to RFC 1918, unregistered source addresses are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. @@ -2943,7 +3022,7 @@ This is replaced with the IP number assigned to the local interface. .It Li PEER_ENDDISC This is replaced with the value of the peers endpoint discriminator. .It Li PROCESSID -This is replaced with the current process ID. +This is replaced with the current process id. .It Li USER This is replaced with the username that has been authenticated with PAP or CHAP. Normally, this variable is assigned only in -direct mode. This value @@ -3342,17 +3421,17 @@ to be sent with the CHAP response. .It The .Dq authkey , -which is encrypted with the challenge and request ID, the answer being sent +which is encrypted with the challenge and request id, the answer being sent in the CHAP response packet. .El .Pp When configuring .Nm -in this manner, it's expected that the host challenge is a series of ascii +in this manner, it's expected that the host challenge is a series of ASCII digits or characters. An encryption device or Secure ID card is usually required to calculate the secret appropriate for the given challenge. .It set authname Ar id -This sets the authentication ID used in client mode PAP or CHAP negotiation. +This sets the authentication id used in client mode PAP or CHAP negotiation. .Pp If used in .Fl direct @@ -3519,23 +3598,70 @@ be agreeable with the peer), or if is specified, .Nm will expect the peer to specify the number. -.It set cd Ar seconds Ns Op \&! +.It set cd Oo +.No off| Ns Ar seconds Ns Op \&! +.Oc Normally, .Nm -checks for the existence of carrier one second after the login script is -complete. If it's not set, +checks for the existence of carrier depending on the type of device +that has been opened: +.Bl -tag -width XXX -offset XXX +.It Terminal Devices +Carrier is checked one second after the login script is complete. If it's +not set, .Nm assumes that this is because the device doesn't support carrier (which -is true for most NULL-modem cables), logs the fact and stops checking -for carrier. However, some modems take some time to assert the carrier -signal, resulting in +is true for most +.Dq laplink +NULL-modem cables), logs the fact and stops checking +for carrier. +.Pp +As ptys don't support the TIOCMGET ioctl, the tty device will switch all +carrier detection off when it detects that the device is a pty. +.It ISDN (i4b) Devices +Carrier is checked once per second for 6 seconds. If it's not set after +the sixth second, the connection attempt is considered to have failed and +the device is closed. Carrier is always required for i4b devices. +.It PPPoE (netgraph) Devices +Carrier is checked once per second for 5 seconds. If it's not set after +the fifth second, the connection attempt is considered to have failed and +the device is closed. Carrier is always required for PPPoE devices. +.El +.Pp +All other device types don't support carrier. Setting a carrier value will +result in a warning when the device is opened. +.Pp +Some modems take more than one second after connecting to assert the carrier +signal. If this delay isn't increased, this will result in .Nm ppp Ns No s -inability to detect when the link is dropped. -.Ar Seconds -specifies the number of seconds that +inability to detect when the link is dropped, as .Nm -should wait after the login script has finished before first checking for -carrier. +assumes that the device isn't asserting carrier. +.Pp +The +.Dq set cd +command overrides the default carrier behaviour. +.Ar seconds +specifies the maximum number of seconds that +.Nm +should wait after the dial script has finished before deciding if +carrier is available or not. +.Pp +If +.Dq off +is specified, +.Nm +will not check for carrier on the device, otherwise +.Nm +will not proceed to the login script until either carrier is detected +or until +.Ar seconds +has elapsed, at which point +.Nm +assumes that the device will not set carrier. +.Pp +If no arguments are given, carrier settings will go back to their default +values. .Pp If .Ar seconds @@ -3544,12 +3670,9 @@ is followed immediately by an exclaimation mark .Nm will .Em require -carrier. If carrier is not detected at the first check, the link will -be considered disconnected. -.Pp -Carrier -.Em require Ns No ment -is ignored when the link is not a tty device. +carrier. If carrier is not detected after +.Ar seconds +seconds, the link will be disconnected. .It set choked Op Ar timeout This sets the number of seconds that .Nm @@ -3567,9 +3690,9 @@ has read a certain number of packets from the local network for transmission, but cannot send the data due to link failure (the peer is busy etc.). .Nm will not read packets indefinitely. Instead, it reads up to -.Em 20 +.Em 30 packets (or -.Em 20 No + +.Em 30 No + .Em nlinks No * .Em 2 packets in multi-link mode), then stops reading the network interface @@ -3615,16 +3738,28 @@ This sets the device(s) to which .Nm will talk to the given .Dq value . -All serial device names are expected to begin with +.Pp +All ISDN and serial device names are expected to begin with .Pa /dev/ . +ISDN devices are usually called +.Pa i4brbchX +and serial devices are usually called +.Pa cuaXX . +.Pp If .Dq value does not begin with .Pa /dev/ , it must either begin with an exclamation mark -.Pq Dq \&! +.Pq Dq \&! , +be of the format +.No PPPoE: Ns Ar iface Ns Xo +.Op \&: Ns Ar provider Ns +.Xc or be of the format -.Dq host:port . +.Ar host Ns No : Ns Ar port Ns Oo +.No /tcp|udp +.Oc . .Pp If it begins with an exclamation mark, the rest of the device name is treated as a program name, and that program is executed when the device @@ -3633,15 +3768,41 @@ is opened. Standard input, output and error are fed back to and are read and written as if they were a regular device. .Pp If a -.Dq host:port Ns Op /tcp|/udp +.No PPPoE: Ns Ar iface Ns Xo +.Op \&: Ns Ar provider Ns +.Xc +specification is given, +.Nm +will attempt to create a +.Em PPP +over Ethernet connection using the given +.Ar iface +interface. The given +.Ar provider +is passed as the service name in the PPPoE Discovery Initiation (PADI) +packet. If no provider is given, an empty value will be used. Refer to +.Xr netgraph 4 +and +.Xr ng_pppoe 8 +for further details. +.Pp +If a +.Ar host Ns No : Ns Ar port Ns Oo +.No /tcp|udp +.Oc specification is given, .Nm will attempt to connect to the given -.Dq host +.Ar host on the given -.Dq port . -If a tcp or udp specification is not given, the default is tcp. Refer to -the section on +.Ar port . +If a +.Dq /tcp +or +.Dq /udp +suffix is not provided, the default is +.Dq /tcp . +Refer to the section on .Em PPP OVER TCP and UDP above for further details. .Pp @@ -3725,7 +3886,7 @@ is running in interactive mode, file descriptor 3 is attached to For example (wrapped for readability); .Bd -literal -offset indent set login "TIMEOUT 5 \\"\\" \\"\\" login:--login: ppp \e -word: ppp \\"!sh \\\\\\\\-c \\\\\\"echo \\\\\\\\-n label: >&2\\\\\\"\\" \e +word: ppp \\"!sh \\\\-c \\\\\\"echo \\\\-n label: >&2\\\\\\"\\" \e \\"!/bin/echo in\\" HELLO" .Ed .Pp @@ -3735,8 +3896,8 @@ command before dialing): .Bd -literal -offset indent Dial attempt 1 of 1 dial OK! -Chat: Expecting: -Chat: Sending: +Chat: Expecting: +Chat: Sending: Chat: Expecting: login:--login: Chat: Wait for (5): login: Chat: Sending: ppp @@ -3747,7 +3908,7 @@ Chat: Expecting: !sh \\-c "echo \\-n label: >&2" Chat: Exec: sh -c "echo -n label: >&2" Chat: Wait for (5): !sh \\-c "echo \\-n label: >&2" --> label: Chat: Exec: /bin/echo in -Chat: Sending: +Chat: Sending: Chat: Expecting: HELLO Chat: Wait for (5): HELLO login OK! @@ -3870,8 +4031,8 @@ into the machine and the filter specifies packets that are allowed out of the machine. .Pp Filtering is done prior to any IP alterations that might be done by the -alias engine on outgoing packets and after any IP alterations that might -be done by the alias engine on incoming packets. By default all filter +NAT engine on outgoing packets and after any IP alterations that might +be done by the NAT engine on incoming packets. By default all filter sets allow all packets to pass. Rules are processed in order according to .Ar rule-no (unless skipped by specifying a rule number as the @@ -4046,6 +4207,9 @@ This compliments the dial-script. If both are specified, the login script will be executed after the dial script. Escape sequences available in the dial script are also available here. +.It set logout Ar chat-script +This specifies the chat script that will be used to logout +before the hangup script is called. It should not normally be necessary. .It set lqrperiod Ar frequency This command sets the .Ar frequency @@ -4069,7 +4233,7 @@ or .Pp Note: If you issue the command .Dq set mode auto , -and have IP aliasing enabled, it may be useful to +and have network address translation enabled, it may be useful to .Dq enable iface-alias afterwards. This will allow .Nm @@ -4354,10 +4518,7 @@ If you wish to specify a local domain socket, .Ar LocalName must be specified as an absolute file name, otherwise it is assumed to be the name or number of a TCP port. You must specify the octal umask -that should be used with local domain sockets as a four character octal -number beginning with -.Sq 0 . -Refer to +to be used with a local domain socket. Refer to .Xr umask 2 for umask details. Refer to .Xr services 5 @@ -4434,6 +4595,46 @@ is specified, .Nm will never idle out before the link has been up for at least that number of seconds. +.It set urgent Xo +.Op tcp|udp +.Oo Op +|- Ns +.Ar port +.Oc No ... +.Xc +This command controls the ports that +.Nm +prioritizes when transmitting data. The default priority TCP ports +are ports 21 (ftp control), 22 (ssh), 23 (telnet), 513 (login), 514 (shell), +543 (klogin) and 544 (kshell). There are no priority UDP ports by default. +See +.Xr services 5 +for details. +.Pp +If neither +.Dq tcp +or +.Dq udp +are specified, +.Dq tcp +is assumed. +.Pp +If no +.Ar port Ns No s +are given, the priority port lists are cleared (although if +.Dq tcp +or +.Dq udp +is specified, only that list is cleared). If the first +.Ar port +argument is prefixed with a plus +.Pq Dq \&+ +or a minus +.Pq Dq \&- , +the current list is adjusted, otherwise the list is reassigned. +.Ar port Ns No s +prefixed with a plus or not prefixed at all are added to the list and +.Ar port Ns No s +prefixed with a minus are removed from the list. .It set vj slotcomp on|off This command tells .Nm @@ -4536,6 +4737,7 @@ peer is detected, .Nm automatically enables Packet Mode and goes back into command mode. .El +.Pp .Sh MORE DETAILS .Bl -bullet .It @@ -4543,7 +4745,7 @@ Read the example configuration files. They are a good source of information. .It Use .Dq help , -.Dq alias ? , +.Dq nat ? , .Dq enable ? , .Dq set ? and @@ -4559,6 +4761,7 @@ http://www.FreeBSD.org/handbook/userppp.html .El .Pp .El +.Pp .Sh FILES .Nm refers to four files: @@ -4589,12 +4792,12 @@ Logging and debugging information file. Note, this name is specified in See .Xr syslog.conf 5 for further details. -.It Pa /var/spool/lock/LCK..* +.It Pa /var/spool/lock/LCK..* tty port locking file. Refer to .Xr uucplock 3 for further details. .It Pa /var/run/tunN.pid -The process ID (PID) of the +The process id (pid) of the .Nm program connected to the tunN device, where .Sq N @@ -4622,6 +4825,7 @@ to HEX to determine the actual file name. This socket is used to pass links between different instances of .Nm ppp . .El +.Pp .Sh SEE ALSO .Xr at 1 , .Xr ftp 1 , @@ -4633,6 +4837,7 @@ This socket is used to pass links between different instances of .Xr libalias 3 , .Xr syslog 3 , .Xr uucplock 3 , +.Xr netgraph 4 , .Xr crontab 5 , .Xr group 5 , .Xr passwd 5 , @@ -4644,7 +4849,9 @@ This socket is used to pass links between different instances of .Xr getty 8 , .Xr inetd 8 , .Xr init 8 , +.Xr isdn 8 , .Xr named 8 , +.Xr ng_pppoe 8 , .Xr ping 8 , .Xr pppctl 8 , .Xr pppd 8 , @@ -4654,12 +4861,20 @@ This socket is used to pass links between different instances of .Xr traceroute 8 , .Xr vipw 8 .Sh HISTORY -This program was originally written by Toshiharu OHNO (tony-o@iij.ad.jp), -and was submitted to FreeBSD-2.0.5 by Atsushi Murai (amurai@spec.co.jp). -.Pp -It was substantially modified during 1997 by Brian Somers -(brian@Awfulhak.org), and was ported to OpenBSD in November that year +This program was originally written by +.An Toshiharu OHNO Aq tony-o@iij.ad.jp , +and was submitted to +.Fx 2.0.5 +by +.An Atsushi Murai Aq amurai@spec.co.jp . +.Pp +It was substantially modified during 1997 by +.An Brian Somers Aq brian@Awfulhak.org , +and was ported to +.Ox +in November that year (just after the 2.2 release). .Pp -Most of the code was rewritten by Brian Somers in early 1998 when -multi-link ppp support was added. +Most of the code was rewritten by +.An Brian Somers +in early 1998 when multi-link ppp support was added. diff --git a/usr.sbin/ppp/ppp/pred.c b/usr.sbin/ppp/ppp/pred.c index adf391a4042..53e88291736 100644 --- a/usr.sbin/ppp/ppp/pred.c +++ b/usr.sbin/ppp/ppp/pred.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pred.c,v 1.7 1999/06/02 15:58:41 brian Exp $ + * $Id: pred.c,v 1.8 2000/01/07 03:26:55 brian Exp $ */ #include <sys/types.h> @@ -179,8 +179,8 @@ Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, u_char bufp[MAX_MTU + 2]; u_short fcs; - orglen = mbuf_Length(bp) + 2; /* add count of proto */ - mwp = mbuf_Alloc((orglen + 2) / 8 * 9 + 12, MB_CCPOUT); + orglen = m_length(bp) + 2; /* add count of proto */ + mwp = m_get((orglen + 2) / 8 * 9 + 12, MB_CCPOUT); hp = wp = MBUF_CTOP(mwp); cp = bufp; *wp++ = *cp++ = orglen >> 8; @@ -206,7 +206,7 @@ Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, *wp++ = fcs & 0377; *wp++ = fcs >> 8; - mwp->cnt = wp - MBUF_CTOP(mwp); + mwp->m_len = wp - MBUF_CTOP(mwp); *proto = ccp_Proto(ccp); return mwp; } @@ -221,9 +221,9 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp) u_char *bufp; u_short fcs; - wp = mbuf_Alloc(MAX_MRU + 2, MB_CCPIN); + wp = m_get(MAX_MRU + 2, MB_CCPIN); cp = MBUF_CTOP(bp); - olen = mbuf_Length(bp); + olen = m_length(bp); pp = bufp = MBUF_CTOP(wp); *pp++ = *cp & 0177; len = *cp++ << 8; @@ -237,8 +237,8 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp) if (len != len1) { /* Error is detected. Send reset request */ log_Printf(LogCCP, "Pred1: Length error (got %d, not %d)\n", len1, len); fsm_Reopen(&ccp->fsm); - mbuf_Free(bp); - mbuf_Free(wp); + m_freem(bp); + m_freem(wp); return NULL; } cp += olen - 4; @@ -246,8 +246,8 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp) } else if (len + 4 != olen) { log_Printf(LogCCP, "Pred1: Length error (got %d, not %d)\n", len + 4, olen); fsm_Reopen(&ccp->fsm); - mbuf_Free(wp); - mbuf_Free(bp); + m_freem(wp); + m_freem(bp); return NULL; } else { ccp->compin += len; @@ -257,21 +257,21 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp) } *pp++ = *cp++; /* CRC */ *pp++ = *cp++; - fcs = hdlc_Fcs(bufp, wp->cnt = pp - bufp); + fcs = hdlc_Fcs(bufp, wp->m_len = pp - bufp); if (fcs == GOODFCS) { - wp->offset += 2; /* skip length */ - wp->cnt -= 4; /* skip length & CRC */ + wp->m_offset += 2; /* skip length */ + wp->m_len -= 4; /* skip length & CRC */ pp = MBUF_CTOP(wp); *proto = *pp++; if (*proto & 1) { - wp->offset++; - wp->cnt--; + wp->m_offset++; + wp->m_len--; } else { - wp->offset += 2; - wp->cnt -= 2; + wp->m_offset += 2; + wp->m_len -= 2; *proto = (*proto << 8) | *pp++; } - mbuf_Free(bp); + m_freem(bp); return wp; } else { const char *pre = *MBUF_CTOP(bp) & 0x80 ? "" : "un"; @@ -280,9 +280,9 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp) log_Printf(LogCCP, "%s: Bad %scompressed CRC-16\n", ccp->fsm.link->name, pre); fsm_Reopen(&ccp->fsm); - mbuf_Free(wp); + m_freem(wp); } - mbuf_Free(bp); + m_freem(bp); return NULL; } diff --git a/usr.sbin/ppp/ppp/prompt.c b/usr.sbin/ppp/ppp/prompt.c index 0b60ba6a294..5edc1aba8d9 100644 --- a/usr.sbin/ppp/ppp/prompt.c +++ b/usr.sbin/ppp/ppp/prompt.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: prompt.c,v 1.4 1999/05/08 11:06:39 brian Exp $ + * $Id: prompt.c,v 1.5 2000/01/07 03:26:55 brian Exp $ */ #include <sys/param.h> @@ -173,6 +173,7 @@ static void prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) { struct prompt *p = descriptor2prompt(d); + struct prompt *op; int n; char ch; char linebuff[LINE_LEN]; @@ -186,8 +187,13 @@ prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) linebuff[n] = '\0'; p->nonewline = 1; /* Maybe command_Decode does a prompt */ prompt_Required(p); - if (n) - command_Decode(bundle, linebuff, n, p, p->src.from); + if (n) { + if ((op = log_PromptContext) == NULL) + log_PromptContext = p; + if (!command_Decode(bundle, linebuff, n, p, p->src.from)) + prompt_Printf(p, "Syntax error\n"); + log_PromptContext = op; + } } else if (n <= 0) { log_Printf(LogPHASE, "%s: Client connection closed.\n", p->src.from); if (!p->owner) diff --git a/usr.sbin/ppp/ppp/proto.c b/usr.sbin/ppp/ppp/proto.c index cdf43bd5906..ab01f14199e 100644 --- a/usr.sbin/ppp/ppp/proto.c +++ b/usr.sbin/ppp/ppp/proto.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: proto.c,v 1.3 1999/06/02 15:58:41 brian Exp $ + * $Id: proto.c,v 1.4 2000/01/07 03:26:55 brian Exp $ */ #include <sys/types.h> @@ -61,9 +61,9 @@ proto_Prepend(struct mbuf *bp, u_short proto, unsigned comp, int extra) cp[1] = proto & 0xff; if (comp && cp[0] == 0) - bp = mbuf_Prepend(bp, cp + 1, 1, extra); + bp = m_prepend(bp, cp + 1, 1, extra); else - bp = mbuf_Prepend(bp, cp, 2, extra); + bp = m_prepend(bp, cp, 2, extra); return bp; } @@ -75,7 +75,7 @@ proto_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, log_Printf(LogDEBUG, "proto_LayerPush: Using 0x%04x\n", *proto); bp = proto_Prepend(bp, *proto, l->lcp.his_protocomp, acf_WrapperOctets(&l->lcp, *proto)); - mbuf_SetType(bp, MB_PROTOOUT); + m_settype(bp, MB_PROTOOUT); link_ProtocolRecord(l, *proto, PROTO_OUT); return bp; @@ -89,14 +89,14 @@ proto_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, size_t got; if ((got = mbuf_View(bp, cp, 2)) == 0) { - mbuf_Free(bp); + m_freem(bp); return NULL; } *proto = cp[0]; if (!(*proto & 1)) { if (got == 1) { - mbuf_Free(bp); + m_freem(bp); return NULL; } bp = mbuf_Read(bp, cp, 2); @@ -105,7 +105,7 @@ proto_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, bp = mbuf_Read(bp, cp, 1); log_Printf(LogDEBUG, "proto_LayerPull: unknown -> 0x%04x\n", *proto); - mbuf_SetType(bp, MB_PROTOIN); + m_settype(bp, MB_PROTOIN); link_ProtocolRecord(l, *proto, PROTO_IN); return bp; diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index e8d5f5fbb33..e987ebbddad 100644 --- a/usr.sbin/ppp/ppp/radius.c +++ b/usr.sbin/ppp/ppp/radius.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: radius.c,v 1.4 1999/05/08 11:06:39 brian Exp $ + * $Id: radius.c,v 1.5 2000/01/07 03:26:55 brian Exp $ * */ @@ -41,6 +41,9 @@ #include <string.h> #include <sys/time.h> #include <termios.h> +#include <ttyent.h> +#include <unistd.h> +#include <netdb.h> #include "layer.h" #include "defs.h" @@ -173,7 +176,10 @@ radius_Process(struct radius *r, int got) dest.ipaddr.s_addr = dest.mask.s_addr = INADDR_ANY; dest.width = 0; argc = command_Interpret(nuke, strlen(nuke), argv); - if (argc < 2) + if (argc < 0) + log_Printf(LogWARN, "radius: %s: Syntax error\n", + argc == 1 ? argv[0] : "\"\""); + else if (argc < 2) log_Printf(LogWARN, "radius: %s: Invalid route\n", argc == 1 ? argv[0] : "\"\""); else if ((strcasecmp(argv[0], "default") != 0 && @@ -336,8 +342,12 @@ void radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, const char *key, const char *challenge) { + struct ttyent *ttyp; struct timeval tv; - int got; + int got, slot; + char hostname[MAXHOSTNAMELEN]; + struct hostent *hp; + struct in_addr hostaddr; if (!*r->cfg.file) return; @@ -392,6 +402,44 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, return; } + if (gethostname(hostname, sizeof hostname) != 0) + log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); + else { + if ((hp = gethostbyname(hostname)) != NULL) { + hostaddr.s_addr = *(u_long *)hp->h_addr; + if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + } + if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + } + + if (authp->physical->handler && + authp->physical->handler->type == TTY_DEVICE) { + setttyent(); + for (slot = 1; (ttyp = getttyent()); ++slot) + if (!strcmp(ttyp->ty_name, authp->physical->name.base)) { + if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + endttyent(); + return; + } + break; + } + endttyent(); + } + + if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) radius_Process(r, got); else { diff --git a/usr.sbin/ppp/ppp/route.c b/usr.sbin/ppp/ppp/route.c index 514fc6c6d61..1d5d9b8abd5 100644 --- a/usr.sbin/ppp/ppp/route.c +++ b/usr.sbin/ppp/ppp/route.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: route.c,v 1.4 1999/05/08 11:06:39 brian Exp $ + * $Id: route.c,v 1.5 2000/01/07 03:26:55 brian Exp $ * */ @@ -208,13 +208,20 @@ Index2Nam(int idx) static char **ifs; /* Figure these out once */ static int nifs, debug_done; /* Figure out how many once, and debug once */ - if (!nifs) { + if (idx > nifs || (idx > 0 && ifs[idx-1] == NULL)) { int mib[6], have, had; size_t needed; char *buf, *ptr, *end; struct sockaddr_dl *dl; struct if_msghdr *ifm; + if (ifs) { + free(ifs); + ifs = NULL; + nifs = 0; + } + debug_done = 0; + mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; @@ -252,8 +259,11 @@ Index2Nam(int idx) if (!newifs) { log_Printf(LogDEBUG, "Index2Nam: %s\n", strerror(errno)); nifs = 0; - if (ifs) + if (ifs) { free(ifs); + ifs = NULL; + } + free(buf); return "???"; } ifs = newifs; diff --git a/usr.sbin/ppp/ppp/slcompress.c b/usr.sbin/ppp/ppp/slcompress.c index 01ab030fb97..3109b4794a5 100644 --- a/usr.sbin/ppp/ppp/slcompress.c +++ b/usr.sbin/ppp/ppp/slcompress.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: slcompress.c,v 1.9 1999/10/13 07:51:38 brian Exp $ + * $Id: slcompress.c,v 1.10 2000/01/07 03:26:55 brian Exp $ * * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: * - Initial distribution. @@ -153,9 +153,9 @@ sl_compress_tcp(struct mbuf * m, * (i.e., ACK isn't set or some other control bit is set). (We assume that * the caller has already made sure the packet is IP proto TCP). */ - if ((ip->ip_off & htons(0x3fff)) || m->cnt < 40) { - log_Printf(LogDEBUG, "??? 1 ip_off = %x, cnt = %d\n", - ip->ip_off, m->cnt); + if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40) { + log_Printf(LogDEBUG, "??? 1 ip_off = %x, m_len = %d\n", + ip->ip_off, m->m_len); log_DumpBp(LogDEBUG, "", m); return (TYPE_IP); } @@ -213,7 +213,7 @@ sl_compress_tcp(struct mbuf * m, #define THOFFSET(th) (th->th_off) hlen += th->th_off; hlen <<= 2; - if (hlen > m->cnt) + if (hlen > m->m_len) return (TYPE_IP); goto uncompressed; @@ -245,7 +245,7 @@ found: deltaS = hlen; hlen += th->th_off; hlen <<= 2; - if (hlen > m->cnt) + if (hlen > m->m_len) return (TYPE_IP); if (((u_short *) ip)[0] != ((u_short *) & cs->cs_ip)[0] || @@ -384,8 +384,8 @@ found: *cp++ = changes | NEW_C; *cp++ = cs->cs_id; } - m->cnt -= hlen; - m->offset += hlen; + m->m_len -= hlen; + m->m_offset += hlen; *cp++ = deltaA >> 8; *cp++ = deltaA; memcpy(cp, new_seq, deltaS); diff --git a/usr.sbin/ppp/ppp/sync.c b/usr.sbin/ppp/ppp/sync.c index de3a57fd470..2102f0194cc 100644 --- a/usr.sbin/ppp/ppp/sync.c +++ b/usr.sbin/ppp/ppp/sync.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sync.c,v 1.3 1999/06/02 15:58:41 brian Exp $ + * $Id: sync.c,v 1.4 2000/01/07 03:26:55 brian Exp $ */ #include <sys/types.h> @@ -53,7 +53,7 @@ sync_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, u_short *proto) { log_DumpBp(LogSYNC, "Write", bp); - mbuf_SetType(bp, MB_SYNCOUT); + m_settype(bp, MB_SYNCOUT); return bp; } @@ -69,9 +69,9 @@ sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, log_DumpBp(LogSYNC, "Read", bp); /* Either done here or by the HDLC layer */ - p->hdlc.lqm.SaveInOctets += mbuf_Length(bp) + 1; + p->hdlc.lqm.SaveInOctets += m_length(bp) + 1; p->hdlc.lqm.SaveInPackets++; - mbuf_SetType(bp, MB_SYNCIN); + m_settype(bp, MB_SYNCIN); } return bp; diff --git a/usr.sbin/ppp/ppp/systems.c b/usr.sbin/ppp/ppp/systems.c index 1605f065b75..5b85de3b2da 100644 --- a/usr.sbin/ppp/ppp/systems.c +++ b/usr.sbin/ppp/ppp/systems.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: systems.c,v 1.9 1999/05/24 09:05:39 brian Exp $ + * $Id: systems.c,v 1.10 2000/01/07 03:26:55 brian Exp $ * * TODO: */ @@ -59,8 +59,8 @@ CloseSecret(FILE *fp) } /* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */ -static void -InterpretArg(char *from, char *to) +static const char * +InterpretArg(const char *from, char *to) { const char *env; char *ptr, *startto, *endto; @@ -71,31 +71,28 @@ InterpretArg(char *from, char *to) while(issep(*from)) from++; + if (*from == '~') { + struct passwd *pwd; + ptr = strchr(++from, '/'); len = ptr ? ptr - from : strlen(from); if (len == 0) { - if ((env = getenv("HOME")) == NULL) - env = _PATH_PPP; - strncpy(to, env, endto - to); + pwd = getpwuid(ID0realuid()); } else { - struct passwd *pwd; - strncpy(to, from, len); to[len] = '\0'; pwd = getpwnam(to); - if (pwd) - strncpy(to, pwd->pw_dir, endto-to); - else - strncpy(to, _PATH_PPP, endto - to); - endpwent(); } + strncpy(to, pwd ? pwd->pw_dir : _PATH_PPP, endto - to); + endpwent(); + *endto = '\0'; to += strlen(to); from += len; } - while (to < endto && *from != '\0') { + while (to < endto && !issep(*from) && *from != '#' && *from != '\0') { if (*from == '$') { if (from[1] == '$') { *to = '\0'; /* For an empty var name below */ @@ -131,9 +128,13 @@ InterpretArg(char *from, char *to) *endto = '\0'; to += strlen(to); } - } else + } else { + if (*from == '\\') + from++; *to++ = *from++; + } } + while (to > startto) { to--; if (!issep(*to)) { @@ -142,6 +143,11 @@ InterpretArg(char *from, char *to) } } *to = '\0'; + + while (issep(*from)) + from++; + + return from; } #define CTRL_UNKNOWN (0) @@ -150,9 +156,14 @@ InterpretArg(char *from, char *to) static int DecodeCtrlCommand(char *line, char *arg) { + const char *end; + if (!strncasecmp(line, "include", 7) && issep(line[7])) { - InterpretArg(line+8, arg); - return CTRL_INCLUDE; + end = InterpretArg(line+8, arg); + if (*end && *end != '#') + log_Printf(LogWARN, "Usage: !include filename\n"); + else + return CTRL_INCLUDE; } return CTRL_UNKNOWN; } @@ -170,16 +181,17 @@ AllowUsers(struct cmdargs const *arg) { /* arg->bundle may be NULL (see system_IsValid()) ! */ int f; - char *user; + struct passwd *pwd; userok = 0; - user = getlogin(); - if (user && *user) + pwd = getpwuid(ID0realuid()); + if (pwd != NULL) for (f = arg->argn; f < arg->argc; f++) - if (!strcmp("*", arg->argv[f]) || !strcmp(user, arg->argv[f])) { + if (!strcmp("*", arg->argv[f]) || !strcmp(pwd->pw_name, arg->argv[f])) { userok = 1; break; } + endpwent(); return 0; } @@ -250,6 +262,27 @@ xgets(char *buf, int buflen, FILE *fp) #define SYSTEM_VALIDATE 2 #define SYSTEM_EXEC 3 +static char * +GetLabel(char *line, const char *filename, int linenum) +{ + char *argv[MAXARGS]; + int argc, len; + + argc = MakeArgs(line, argv, MAXARGS, PARSE_REDUCE); + + if (argc == 2 && !strcmp(argv[1], ":")) + return argv[0]; + + if (argc != 1 || (len = strlen(argv[0])) < 2 || argv[0][len-1] != ':') { + log_Printf(LogWARN, "Bad label in %s (line %d) - missing colon\n", + filename, linenum); + return NULL; + } + argv[0][len-1] = '\0'; /* Lose the ':' */ + + return argv[0]; +} + /* Returns -2 for ``file not found'' and -1 for ``label not found'' */ static int @@ -257,7 +290,7 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file, struct prompt *prompt, struct datalink *cx, int how) { FILE *fp; - char *cp, *wp; + char *cp; int n, len; char line[LINE_LEN]; char filename[MAXPATHLEN]; @@ -267,6 +300,7 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file, int allowcmd; int indent; char arg[LINE_LEN]; + struct prompt *op; if (*file == '/') snprintf(filename, sizeof filename, "%s", file); @@ -307,14 +341,8 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file, break; default: - wp = strchr(cp, ':'); - if (wp == NULL || wp[1] != '\0') { - log_Printf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n", - filename, linenum); - continue; - } - *wp = '\0'; - cp = strip(cp); /* lose any spaces between the label and the ':' */ + if ((cp = GetLabel(cp, filename, linenum)) == NULL) + continue; if (strcmp(cp, name) == 0) { /* We're in business */ @@ -325,26 +353,33 @@ ReadSystem(struct bundle *bundle, const char *name, const char *file, indent = issep(*line); cp = strip(line); - if (*cp == '\0') /* empty / comment */ + if (*cp == '\0') /* empty / comment */ continue; - if (!indent) { /* start of next section */ - if (*cp != '!') { - wp = strchr(cp, ':'); - if ((how == SYSTEM_EXEC) && (wp == NULL || wp[1] != '\0')) - log_Printf(LogWARN, "Unindented command (%s line %d) -" - " ignored\n", filename, linenum); - } + if (!indent) { /* start of next section */ + if (*cp != '!' && how == SYSTEM_EXEC) + cp = GetLabel(cp, filename, linenum); break; } len = strlen(cp); - argc = command_Interpret(cp, len, argv); - allowcmd = argc > 0 && !strcasecmp(argv[0], "allow"); - if ((!(how == SYSTEM_EXEC) && allowcmd) || - ((how == SYSTEM_EXEC) && !allowcmd)) - command_Run(bundle, argc, (char const *const *)argv, prompt, - name, cx); + if ((argc = command_Interpret(cp, len, argv)) < 0) + log_Printf(LogWARN, "%s: %d: Syntax error\n", filename, linenum); + else { + allowcmd = argc > 0 && !strcasecmp(argv[0], "allow"); + if ((how != SYSTEM_EXEC && allowcmd) || + (how == SYSTEM_EXEC && !allowcmd)) { + /* + * Disable any context so that warnings are given to everyone, + * including syslog. + */ + op = log_PromptContext; + log_PromptContext = NULL; + command_Run(bundle, argc, (char const *const *)argv, prompt, + name, cx); + log_PromptContext = op; + } + } } fclose(fp); /* everything read - get out */ diff --git a/usr.sbin/ppp/ppp/tcp.c b/usr.sbin/ppp/ppp/tcp.c index 09e7525be98..83da94fa20a 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. * - * $Id: tcp.c,v 1.6 1999/07/15 02:10:32 brian Exp $ + * $Id: tcp.c,v 1.7 2000/01/07 03:26:55 brian Exp $ */ #include <sys/types.h> @@ -44,7 +44,6 @@ #include "defs.h" #include "mbuf.h" #include "log.h" -#include "sync.h" #include "timer.h" #include "lqr.h" #include "hdlc.h" @@ -100,6 +99,9 @@ tcp_OpenConnection(const char *name, char *host, char *port) static struct device tcpdevice = { TCP_DEVICE, "tcp", + { CD_NOTREQUIRED, 0 }, + NULL, + NULL, NULL, NULL, NULL, @@ -114,7 +116,7 @@ static struct device tcpdevice = { struct device * tcp_iov2device(int type, struct physical *p, struct iovec *iov, - int *niov, int maxiov) + int *niov, int maxiov, int *auxfd, int *nauxfd) { if (type == TCP_DEVICE) { free(iov[(*niov)++].iov_base); @@ -131,7 +133,7 @@ tcp_Create(struct physical *p) char *cp, *host, *port, *svc; if (p->fd < 0) { - if ((cp = strchr(p->name.full, ':')) != NULL) { + if ((cp = strchr(p->name.full, ':')) != NULL && !strchr(cp + 1, ':')) { *cp = '\0'; host = p->name.full; port = cp + 1; @@ -140,8 +142,10 @@ tcp_Create(struct physical *p) *cp = ':'; return 0; } - if (svc) + if (svc) { + p->fd--; /* We own the device but maybe can't use it - change fd */ *svc = '\0'; + } if (*host && *port) { p->fd = tcp_OpenConnection(p->link.name, host, port); *cp = ':'; @@ -184,6 +188,8 @@ tcp_Create(struct physical *p) p->name.base = p->name.full; } physical_SetupStack(p, tcpdevice.name, PHYSICAL_FORCE_ASYNC); + if (p->cfg.cd.necessity != CD_DEFAULT) + log_Printf(LogWARN, "Carrier settings ignored\n"); return &tcpdevice; } } diff --git a/usr.sbin/ppp/ppp/tcp.h b/usr.sbin/ppp/ppp/tcp.h index 140e4e0e097..5b7285655b0 100644 --- a/usr.sbin/ppp/ppp/tcp.h +++ b/usr.sbin/ppp/ppp/tcp.h @@ -23,12 +23,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: tcp.h,v 1.3 1999/06/05 21:36:02 brian Exp $ + * $Id: tcp.h,v 1.4 2000/01/07 03:26:56 brian Exp $ */ struct physical; extern struct device *tcp_Create(struct physical *); extern struct device *tcp_iov2device(int, struct physical *, - struct iovec *, int *, int); + struct iovec *, int *, int, int *, int *); #define tcp_DeviceSize physical_DeviceSize diff --git a/usr.sbin/ppp/ppp/timer.c b/usr.sbin/ppp/ppp/timer.c index f631ac2a42a..e4b3171e0c2 100644 --- a/usr.sbin/ppp/ppp/timer.c +++ b/usr.sbin/ppp/ppp/timer.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: timer.c,v 1.5 1999/05/12 19:11:06 brian Exp $ + * $Id: timer.c,v 1.6 2000/01/07 03:26:56 brian Exp $ * * TODO: */ @@ -35,14 +35,14 @@ #include "descriptor.h" #include "prompt.h" -static struct pppTimer *TimerList = NULL; +static struct pppTimer *TimerList = NULL, *ExpiredList = NULL; static void StopTimerNoBlock(struct pppTimer *); static const char * tState2Nam(u_int state) { - static const char *StateNames[] = { "stopped", "running", "expired" }; + static const char * const StateNames[] = { "stopped", "running", "expired" }; if (state >= sizeof StateNames / sizeof StateNames[0]) return "unknown"; @@ -62,6 +62,7 @@ timer_Stop(struct pppTimer *tp) void timer_Start(struct pppTimer *tp) { + struct itimerval itimer; struct pppTimer *t, *pt; u_long ticks = 0; int omask; @@ -76,6 +77,12 @@ timer_Start(struct pppTimer *tp) sigsetmask(omask); return; } + + /* Adjust our first delta so that it reflects what's really happening */ + if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) + TimerList->rest = itimer.it_value.tv_sec * SECTICKS + + itimer.it_value.tv_usec / TICKUNIT; + pt = NULL; for (t = TimerList; t; t = t->next) { if (ticks + t->rest >= tp->load) @@ -99,7 +106,7 @@ timer_Start(struct pppTimer *tp) pt->next = tp; } else { TimerList = tp; - timer_InitService(0); /* Start the Timer Service */ + timer_InitService(t != NULL); /* [re]Start the Timer Service */ } if (t) t->rest -= tp->rest; @@ -117,14 +124,14 @@ StopTimerNoBlock(struct pppTimer *tp) * A STOPPED timer isn't in any list, but may have a bogus [e]next field. * An EXPIRED timer is in the ->enext list. */ - if (tp->state != TIMER_RUNNING) { - tp->next = NULL; - tp->state = TIMER_STOPPED; + + if (tp->state == TIMER_STOPPED) return; - } + pt = NULL; for (t = TimerList; t != tp && t != NULL; t = t->next) pt = t; + if (t) { if (pt) { pt->next = t->next; @@ -135,10 +142,22 @@ StopTimerNoBlock(struct pppTimer *tp) } if (t->next) t->next->rest += tp->rest; - } else - log_Printf(LogERROR, "Oops, %s timer not found!!\n", tp->name); + } else { + /* Search for any pending expired timers */ + pt = NULL; + for (t = ExpiredList; t != tp && t != NULL; t = t->enext) + pt = t; + + if (t) { + if (pt) + pt->enext = t->enext; + else + ExpiredList = t->enext; + } else if (tp->state == TIMER_RUNNING) + log_Printf(LogERROR, "Oops, %s timer not found!!\n", tp->name); + } - tp->next = NULL; + tp->next = tp->enext = NULL; tp->state = TIMER_STOPPED; } @@ -178,11 +197,11 @@ TimerService(void) /* Process all expired timers */ while (exp) { - next = exp->enext; + ExpiredList = exp->enext; exp->enext = NULL; if (exp->func) (*exp->func)(exp->arg); - exp = next; + exp = ExpiredList; } } } diff --git a/usr.sbin/ppp/ppp/tty.c b/usr.sbin/ppp/ppp/tty.c index 411a1499fc0..f0522fb644e 100644 --- a/usr.sbin/ppp/ppp/tty.c +++ b/usr.sbin/ppp/ppp/tty.c @@ -23,32 +23,20 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: tty.c,v 1.12 1999/08/10 10:50:44 brian Exp $ + * $Id: tty.c,v 1.13 2000/01/07 03:26:56 brian Exp $ */ #include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> #include <sys/un.h> #if defined(__OpenBSD__) || defined(__NetBSD__) #include <sys/ioctl.h> -#include <util.h> -#else -#include <libutil.h> #endif #include <errno.h> #include <fcntl.h> -#include <paths.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> -#include <sys/wait.h> #include <sys/uio.h> #include <termios.h> #include <unistd.h> @@ -57,8 +45,6 @@ #include "defs.h" #include "mbuf.h" #include "log.h" -#include "id.h" -#include "sync.h" #include "timer.h" #include "lqr.h" #include "hdlc.h" @@ -68,20 +54,10 @@ #include "ccp.h" #include "link.h" #include "async.h" -#include "slcompress.h" -#include "iplist.h" -#include "ipcp.h" -#include "filter.h" #include "descriptor.h" #include "physical.h" #include "mp.h" -#ifndef NORADIUS -#include "radius.h" -#endif #include "chat.h" -#include "command.h" -#include "bundle.h" -#include "prompt.h" #include "auth.h" #include "chap.h" #include "cbcp.h" @@ -89,12 +65,20 @@ #include "main.h" #include "tty.h" +#if defined(__mac68k__) || defined(__macppc__) +#undef CRTS_IFLOW +#undef CCTS_OFLOW +#define CRTS_IFLOW CDTRCTS +#define CCTS_OFLOW CDTRCTS +#endif + #define Online(dev) ((dev)->mbits & TIOCM_CD) struct ttydevice { struct device dev; /* What struct physical knows about */ struct pppTimer Timer; /* CD checks */ int mbits; /* Current DCD status */ + int carrier_seconds; /* seconds before CD is *required* */ struct termios ios; /* To be able to reset from raw mode */ }; @@ -124,10 +108,12 @@ tty_Timeout(void *data) if (p->fd >= 0) { if (ioctl(p->fd, TIOCMGET, &dev->mbits) < 0) { - log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name, - strerror(errno)); - datalink_Down(p->dl, CLOSE_NORMAL); + /* we must be a pty ? */ + if (p->cfg.cd.necessity != CD_DEFAULT) + log_Printf(LogWARN, "%s: Carrier ioctl not supported, " + "using ``set cd off''\n", p->link.name); timer_Stop(&dev->Timer); + dev->mbits = TIOCM_CD; return; } } else @@ -136,16 +122,24 @@ tty_Timeout(void *data) if (ombits == -1) { /* First time looking for carrier */ if (Online(dev)) - log_Printf(LogDEBUG, "%s: %s: CD detected\n", p->link.name, p->name.full); - else if (p->cfg.cd.required) { - log_Printf(LogPHASE, "%s: %s: Required CD not detected\n", - p->link.name, p->name.full); - datalink_Down(p->dl, CLOSE_NORMAL); - } else { - log_Printf(LogPHASE, "%s: %s doesn't support CD\n", - p->link.name, p->name.full); + log_Printf(LogPHASE, "%s: %s: CD detected\n", p->link.name, p->name.full); + else if (++dev->carrier_seconds >= dev->dev.cd.delay) { + if (dev->dev.cd.necessity == CD_REQUIRED) + log_Printf(LogPHASE, "%s: %s: Required CD not detected\n", + p->link.name, p->name.full); + else { + log_Printf(LogPHASE, "%s: %s doesn't support CD\n", + p->link.name, p->name.full); + dev->mbits = TIOCM_CD; /* Dodgy null-modem cable ? */ + } timer_Stop(&dev->Timer); - dev->mbits = TIOCM_CD; + /* tty_AwaitCarrier() will notice */ + } else { + /* Keep waiting */ + log_Printf(LogDEBUG, "%s: %s: Still no carrier (%d/%d)\n", + p->link.name, p->name.full, dev->carrier_seconds, + dev->dev.cd.delay); + dev->mbits = -1; } } else { change = ombits ^ dev->mbits; @@ -170,52 +164,66 @@ tty_StartTimer(struct physical *p) struct ttydevice *dev = device2tty(p->handler); timer_Stop(&dev->Timer); - dev->Timer.load = SECTICKS * p->cfg.cd.delay; + dev->Timer.load = SECTICKS; dev->Timer.func = tty_Timeout; dev->Timer.name = "tty CD"; dev->Timer.arg = p; log_Printf(LogDEBUG, "%s: Using tty_Timeout [%p]\n", p->link.name, tty_Timeout); - dev->mbits = -1; /* So we know it's the first time */ timer_Start(&dev->Timer); } static int +tty_AwaitCarrier(struct physical *p) +{ + struct ttydevice *dev = device2tty(p->handler); + + if (dev->dev.cd.necessity == CD_NOTREQUIRED || physical_IsSync(p)) + return CARRIER_OK; + + if (dev->mbits == -1) { + if (dev->Timer.state == TIMER_STOPPED) { + dev->carrier_seconds = 0; + tty_StartTimer(p); + } + return CARRIER_PENDING; /* Not yet ! */ + } + + return Online(dev) ? CARRIER_OK : CARRIER_LOST; +} + +static int tty_Raw(struct physical *p) { struct ttydevice *dev = device2tty(p->handler); struct termios ios; int oldflag; - if (physical_IsSync(p)) - return 1; - - log_Printf(LogDEBUG, "%s: Entering physical_Raw\n", p->link.name); + log_Printf(LogDEBUG, "%s: Entering tty_Raw\n", p->link.name); if (p->type != PHYS_DIRECT && p->fd >= 0 && !Online(dev)) log_Printf(LogDEBUG, "%s: Raw: descriptor = %d, mbits = %x\n", p->link.name, p->fd, dev->mbits); - 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 (!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 (p->type != PHYS_DEDICATED) + ios.c_cflag |= HUPCL; - tcsetattr(p->fd, TCSANOW, &ios); + tcsetattr(p->fd, TCSANOW, &ios); + } oldflag = fcntl(p->fd, F_GETFL, 0); if (oldflag < 0) return 0; fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK); - if (ioctl(p->fd, TIOCMGET, &dev->mbits) == 0) - tty_StartTimer(p); - return 1; } @@ -226,7 +234,7 @@ tty_Offline(struct physical *p) if (p->fd >= 0) { timer_Stop(&dev->Timer); - dev->mbits &= ~TIOCM_DTR; + dev->mbits &= ~TIOCM_DTR; /* XXX: Hmm, what's this supposed to do ? */ if (Online(dev)) { struct termios tio; @@ -249,12 +257,12 @@ tty_Cooked(struct physical *p) tty_Offline(p); /* In case of emergency close()s */ tcflush(p->fd, TCIOFLUSH); - if (!physical_IsSync(p)) { + + if (!physical_IsSync(p)) tcsetattr(p->fd, TCSAFLUSH, &dev->ios); - oldflag = fcntl(p->fd, F_GETFL, 0); - if (oldflag == 0) - fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); - } + + if ((oldflag = fcntl(p->fd, F_GETFL, 0)) != -1) + fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); } static void @@ -296,12 +304,13 @@ tty_OpenInfo(struct physical *p) else strcpy(buf, "no"); strcat(buf, " carrier"); + return buf; } static void tty_device2iov(struct device *d, struct iovec *iov, int *niov, - int maxiov, pid_t newpid) + int maxiov, int *auxfd, int *nauxfd) { struct ttydevice *dev = device2tty(d); int sz = physical_MaxDeviceSize(); @@ -323,6 +332,9 @@ tty_device2iov(struct device *d, struct iovec *iov, int *niov, static struct device basettydevice = { TTY_DEVICE, "tty", + { CD_VARIABLE, DEF_TTYCDDELAY }, + tty_AwaitCarrier, + NULL, tty_Raw, tty_Offline, tty_Cooked, @@ -337,7 +349,7 @@ static struct device basettydevice = { struct device * tty_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, - int maxiov) + int maxiov, int *auxfd, int *nauxfd) { if (type == TTY_DEVICE) { struct ttydevice *dev = (struct ttydevice *)iov[(*niov)++].iov_base; @@ -393,9 +405,14 @@ tty_Create(struct physical *p) memcpy(&dev->dev, &basettydevice, sizeof dev->dev); memset(&dev->Timer, '\0', sizeof dev->Timer); + dev->mbits = -1; tcgetattr(p->fd, &ios); dev->ios = ios; + if (p->cfg.cd.necessity != CD_DEFAULT) + /* Any override is ok for the tty device */ + dev->dev.cd = p->cfg.cd; + log_Printf(LogDEBUG, "%s: tty_Create: physical (get): fd = %d," " iflag = %lx, oflag = %lx, cflag = %lx\n", p->link.name, p->fd, (u_long)ios.c_iflag, (u_long)ios.c_oflag, (u_long)ios.c_cflag); @@ -408,10 +425,8 @@ tty_Create(struct physical *p) ios.c_iflag |= IXOFF; } ios.c_iflag |= IXON; - if (p->type != PHYS_DEDICATED) { + if (p->type != PHYS_DEDICATED) ios.c_cflag |= HUPCL; - ios.c_cflag &= ~CLOCAL; - } if (p->type != PHYS_DIRECT) { /* Change tty speed when we're not in -direct mode */ @@ -426,22 +441,6 @@ tty_Create(struct physical *p) "cflag = %lx\n", p->link.name, (u_long)ios.c_iflag, (u_long)ios.c_oflag, (u_long)ios.c_cflag); - if (ioctl(p->fd, TIOCMGET, &dev->mbits) == -1) { - if (p->type != PHYS_DIRECT) { - /* Complete failure - parent doesn't continue trying to ``create'' */ - - log_Printf(LogWARN, "%s: Open: Cannot get physical status: %s\n", - p->link.name, strerror(errno)); - tty_Cooked(p); - close(p->fd); - p->fd = -1; - return NULL; - } else - dev->mbits = TIOCM_CD; - } - log_Printf(LogDEBUG, "%s: Open: physical control = %o\n", - p->link.name, dev->mbits); - oldflag = fcntl(p->fd, F_GETFL, 0); if (oldflag < 0) { /* Complete failure - parent doesn't continue trying to ``create'' */ @@ -451,6 +450,7 @@ tty_Create(struct physical *p) tty_Cooked(p); close(p->fd); p->fd = -1; + free(dev); return NULL; } else fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); diff --git a/usr.sbin/ppp/ppp/tty.h b/usr.sbin/ppp/ppp/tty.h index 6f2573aa7b1..dd83363f3c2 100644 --- a/usr.sbin/ppp/ppp/tty.h +++ b/usr.sbin/ppp/ppp/tty.h @@ -23,13 +23,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: tty.h,v 1.3 1999/06/05 21:36:03 brian Exp $ + * $Id: tty.h,v 1.4 2000/01/07 03:26:56 brian Exp $ */ struct physical; struct device; +#define DEF_TTYCDDELAY 1 /* Default ``set cd'' value */ + extern struct device *tty_Create(struct physical *); extern struct device *tty_iov2device(int, struct physical *, - struct iovec *, int *, int); + struct iovec *, int *, int, int *, int *); extern int tty_DeviceSize(void); diff --git a/usr.sbin/ppp/ppp/tun.c b/usr.sbin/ppp/ppp/tun.c index 8964d80fb50..60f1e9f7001 100644 --- a/usr.sbin/ppp/ppp/tun.c +++ b/usr.sbin/ppp/ppp/tun.c @@ -23,11 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: tun.c,v 1.7 1999/08/05 10:32:14 brian Exp $ + * $Id: tun.c,v 1.8 2000/01/07 03:26:56 brian Exp $ */ #include <sys/param.h> -#ifdef __OpenBSD__ +#ifndef __FreeBSD__ #include <sys/socket.h> /* For IFF_ defines */ #include <net/if.h> /* For IFF_ defines */ #endif @@ -40,7 +40,9 @@ #include <errno.h> #include <string.h> +#if defined(__OpenBSD__) || defined(__NetBSD__) #include <sys/ioctl.h> +#endif #include <termios.h> #ifdef __NetBSD__ #include <stdio.h> diff --git a/usr.sbin/ppp/ppp/udp.c b/usr.sbin/ppp/ppp/udp.c index cea2118b561..884cb20ca75 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. * - * $Id: udp.c,v 1.5 1999/07/15 02:10:32 brian Exp $ + * $Id: udp.c,v 1.6 2000/01/07 03:26:56 brian Exp $ */ #include <sys/types.h> @@ -45,7 +45,6 @@ #include "defs.h" #include "mbuf.h" #include "log.h" -#include "sync.h" #include "timer.h" #include "lqr.h" #include "hdlc.h" @@ -117,7 +116,7 @@ udp_Free(struct physical *p) static void udp_device2iov(struct device *d, struct iovec *iov, int *niov, - int maxiov, pid_t newpid) + int maxiov, int *auxfd, int *nauxfd) { int sz = physical_MaxDeviceSize(); @@ -133,6 +132,9 @@ udp_device2iov(struct device *d, struct iovec *iov, int *niov, static const struct device baseudpdevice = { UDP_DEVICE, "udp", + { CD_NOTREQUIRED, 0 }, + NULL, + NULL, NULL, NULL, NULL, @@ -147,7 +149,7 @@ static const struct device baseudpdevice = { struct device * udp_iov2device(int type, struct physical *p, struct iovec *iov, int *niov, - int maxiov) + int maxiov, int *auxfd, int *nauxfd) { if (type == UDP_DEVICE) { struct udpdevice *dev = (struct udpdevice *)iov[(*niov)++].iov_base; @@ -231,7 +233,7 @@ udp_Create(struct physical *p) dev = NULL; if (p->fd < 0) { - if ((cp = strchr(p->name.full, ':')) != NULL) { + if ((cp = strchr(p->name.full, ':')) != NULL && !strchr(cp + 1, ':')) { *cp = '\0'; host = p->name.full; port = cp + 1; @@ -240,8 +242,10 @@ udp_Create(struct physical *p) *cp = ':'; return NULL; } - if (svc) + if (svc) { + p->fd--; /* We own the device but maybe can't use it - change fd */ *svc = '\0'; + } if (*host && *port) dev = udp_CreateDevice(p, host, port); @@ -279,6 +283,8 @@ udp_Create(struct physical *p) if (dev) { memcpy(&dev->dev, &baseudpdevice, sizeof dev->dev); physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNC); + if (p->cfg.cd.necessity != CD_DEFAULT) + log_Printf(LogWARN, "Carrier settings ignored\n"); return &dev->dev; } diff --git a/usr.sbin/ppp/ppp/udp.h b/usr.sbin/ppp/ppp/udp.h index 3562169075f..a5d854846fa 100644 --- a/usr.sbin/ppp/ppp/udp.h +++ b/usr.sbin/ppp/ppp/udp.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: udp.h,v 1.2 1999/06/05 21:36:04 brian Exp $ + * $Id: udp.h,v 1.3 2000/01/07 03:26:56 brian Exp $ */ struct physical; @@ -31,5 +31,5 @@ struct device; extern struct device *udp_Create(struct physical *); extern struct device *udp_iov2device(int, struct physical *, - struct iovec *, int *, int); + struct iovec *, int *, int, int *, int *); extern int udp_DeviceSize(void); diff --git a/usr.sbin/ppp/ppp/vjcomp.c b/usr.sbin/ppp/ppp/vjcomp.c index 17453cfe600..ac4c9dda623 100644 --- a/usr.sbin/ppp/ppp/vjcomp.c +++ b/usr.sbin/ppp/ppp/vjcomp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: vjcomp.c,v 1.10 1999/07/15 02:10:33 brian Exp $ + * $Id: vjcomp.c,v 1.11 2000/01/07 03:26:56 brian Exp $ * * TODO: */ @@ -28,7 +28,7 @@ #include <sys/un.h> #include <stdio.h> -#include <string.h> +#include <string.h> /* strlen/memcpy */ #include <termios.h> #include "layer.h" @@ -66,7 +66,7 @@ vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, struct ip *pip; u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16; - bp = mbuf_Contiguous(bp); + bp = m_pullup(bp); pip = (struct ip *)MBUF_CTOP(bp); if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP && cproto == PROTO_VJCOMP) { @@ -81,18 +81,18 @@ vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, case TYPE_UNCOMPRESSED_TCP: *proto = PROTO_VJUNCOMP; log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n"); - mbuf_SetType(bp, MB_VJOUT); + m_settype(bp, MB_VJOUT); break; case TYPE_COMPRESSED_TCP: *proto = PROTO_VJCOMP; log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n"); - mbuf_SetType(bp, MB_VJOUT); + m_settype(bp, MB_VJOUT); break; default: log_Printf(LogERROR, "vj_LayerPush: Unknown frame type %x\n", type); - mbuf_Free(bp); + m_freem(bp); return NULL; } } @@ -105,11 +105,10 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf *bp, u_char type) { u_char *bufp; int len, olen, rlen; - struct mbuf *nbp; u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ - bp = mbuf_Contiguous(bp); - olen = len = mbuf_Length(bp); + bp = m_pullup(bp); + olen = len = m_length(bp); if (type == TYPE_UNCOMPRESSED_TCP) { /* * Uncompressed packet does NOT change its size, so that we can use mbuf @@ -119,10 +118,10 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf *bp, u_char type) len = sl_uncompress_tcp(&bufp, len, type, &ipcp->vj.cslc, &ipcp->vj.slstat, (ipcp->my_compproto >> 8) & 255); if (len <= 0) { - mbuf_Free(bp); + m_freem(bp); bp = NULL; } else - mbuf_SetType(bp, MB_VJIN); + m_settype(bp, MB_VJIN); return bp; } @@ -139,16 +138,16 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf *bp, u_char type) len = sl_uncompress_tcp(&bufp, olen, type, &ipcp->vj.cslc, &ipcp->vj.slstat, (ipcp->my_compproto >> 8) & 255); if (len <= 0) { - mbuf_Free(bp); + m_freem(bp); return NULL; } len -= olen; len += rlen; - nbp = mbuf_Alloc(len, MB_VJIN); - memcpy(MBUF_CTOP(nbp), bufp, len); - mbuf_SetType(bp, MB_VJIN); - nbp->next = bp; - return nbp; + + bp = m_prepend(bp, bufp, len, 0); + m_settype(bp, MB_VJIN); + + return bp; } static struct mbuf * |