summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1999-05-08 11:07:56 +0000
committerbrian <brian@FreeBSD.org>1999-05-08 11:07:56 +0000
commitab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4 (patch)
treee79816f983bd5a5be86a78fe0aafbd00a13ac2db
parent713dd62834d401cc7b9b394a4b916ab9e5e3d4d5 (diff)
downloadFreeBSD-src-ab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4.zip
FreeBSD-src-ab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4.tar.gz
o Redesign the layering mechanism and make the aliasing code part of
the layering. We now ``stack'' layers as soon as we open the device (when we figure out what we're dealing with). A static set of `dispatch' routines are also declared for dealing with incoming packets after they've been `pulled' up through the stacked layers. Physical devices are now assigned handlers based on the device type when they're opened. For the moment there are three device types; ttys, execs and tcps. o Increment version number to 2.2 o Make an entry in [uw]tmp for non-tty -direct invocations (after pap/chap authentication). o Make throughput counters quad_t's o Account for the absolute number of mbuf malloc()s and free()s in ``show mem''. o ``show modem'' becomes ``show physical''.
-rw-r--r--usr.sbin/ppp/Makefile13
-rw-r--r--usr.sbin/ppp/README.changes2
-rw-r--r--usr.sbin/ppp/acf.c111
-rw-r--r--usr.sbin/ppp/acf.h33
-rw-r--r--usr.sbin/ppp/alias_cmd.c97
-rw-r--r--usr.sbin/ppp/alias_cmd.h4
-rw-r--r--usr.sbin/ppp/arp.c4
-rw-r--r--usr.sbin/ppp/async.c79
-rw-r--r--usr.sbin/ppp/async.h6
-rw-r--r--usr.sbin/ppp/auth.c5
-rw-r--r--usr.sbin/ppp/bundle.c47
-rw-r--r--usr.sbin/ppp/cbcp.c24
-rw-r--r--usr.sbin/ppp/cbcp.h4
-rw-r--r--usr.sbin/ppp/ccp.c70
-rw-r--r--usr.sbin/ppp/ccp.h12
-rw-r--r--usr.sbin/ppp/chap.c54
-rw-r--r--usr.sbin/ppp/chap.h4
-rw-r--r--usr.sbin/ppp/chat.c65
-rw-r--r--usr.sbin/ppp/chat.h3
-rw-r--r--usr.sbin/ppp/command.c80
-rw-r--r--usr.sbin/ppp/datalink.c38
-rw-r--r--usr.sbin/ppp/deflate.c31
-rw-r--r--usr.sbin/ppp/defs.c168
-rw-r--r--usr.sbin/ppp/defs.h5
-rw-r--r--usr.sbin/ppp/exec.c160
-rw-r--r--usr.sbin/ppp/exec.h29
-rw-r--r--usr.sbin/ppp/filter.c3
-rw-r--r--usr.sbin/ppp/fsm.c50
-rw-r--r--usr.sbin/ppp/hdlc.c325
-rw-r--r--usr.sbin/ppp/hdlc.h9
-rw-r--r--usr.sbin/ppp/iface.c3
-rw-r--r--usr.sbin/ppp/ip.c176
-rw-r--r--usr.sbin/ppp/ip.h6
-rw-r--r--usr.sbin/ppp/ipcp.c31
-rw-r--r--usr.sbin/ppp/ipcp.h4
-rw-r--r--usr.sbin/ppp/iplist.c3
-rw-r--r--usr.sbin/ppp/layer.h52
-rw-r--r--usr.sbin/ppp/lcp.c12
-rw-r--r--usr.sbin/ppp/lcp.h4
-rw-r--r--usr.sbin/ppp/link.c200
-rw-r--r--usr.sbin/ppp/link.h18
-rw-r--r--usr.sbin/ppp/lqr.c143
-rw-r--r--usr.sbin/ppp/lqr.h8
-rw-r--r--usr.sbin/ppp/main.c4
-rw-r--r--usr.sbin/ppp/mbuf.c105
-rw-r--r--usr.sbin/ppp/mbuf.h16
-rw-r--r--usr.sbin/ppp/modem.c1155
-rw-r--r--usr.sbin/ppp/modem.h43
-rw-r--r--usr.sbin/ppp/mp.c57
-rw-r--r--usr.sbin/ppp/mp.h4
-rw-r--r--usr.sbin/ppp/nat_cmd.c97
-rw-r--r--usr.sbin/ppp/nat_cmd.h4
-rw-r--r--usr.sbin/ppp/pap.c43
-rw-r--r--usr.sbin/ppp/pap.h4
-rw-r--r--usr.sbin/ppp/physical.c740
-rw-r--r--usr.sbin/ppp/physical.h78
-rw-r--r--usr.sbin/ppp/ppp.838
-rw-r--r--usr.sbin/ppp/ppp.8.m438
-rw-r--r--usr.sbin/ppp/pred.c20
-rw-r--r--usr.sbin/ppp/prompt.c3
-rw-r--r--usr.sbin/ppp/proto.c110
-rw-r--r--usr.sbin/ppp/proto.h (renamed from usr.sbin/ppp/lcpproto.h)11
-rw-r--r--usr.sbin/ppp/radius.c3
-rw-r--r--usr.sbin/ppp/route.c3
-rw-r--r--usr.sbin/ppp/slcompress.c8
-rw-r--r--usr.sbin/ppp/sync.c68
-rw-r--r--usr.sbin/ppp/sync.h29
-rw-r--r--usr.sbin/ppp/systems.c3
-rw-r--r--usr.sbin/ppp/tcp.c134
-rw-r--r--usr.sbin/ppp/tcp.h29
-rw-r--r--usr.sbin/ppp/throughput.c32
-rw-r--r--usr.sbin/ppp/throughput.h16
-rw-r--r--usr.sbin/ppp/tty.c446
-rw-r--r--usr.sbin/ppp/tty.h33
-rw-r--r--usr.sbin/ppp/tun.c4
-rw-r--r--usr.sbin/ppp/vjcomp.c65
-rw-r--r--usr.sbin/ppp/vjcomp.h6
77 files changed, 3369 insertions, 2275 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile
index 4211d4c..7c2b490 100644
--- a/usr.sbin/ppp/Makefile
+++ b/usr.sbin/ppp/Makefile
@@ -1,13 +1,14 @@
-# $Id: Makefile,v 1.51 1999/01/28 01:56:30 brian Exp $
+# $Id: Makefile,v 1.52 1999/01/28 15:16:38 brian Exp $
MAINTAINER=brian@FreeBSD.org
PROG= ppp
-SRCS= arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c command.c \
- datalink.c deflate.c defs.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 modem.c \
- mp.c pap.c physical.c pred.c probe.c prompt.c route.c server.c \
- sig.c slcompress.c systems.c throughput.c timer.c tun.c vjcomp.c
+SRCS= acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.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 route.c \
+ server.c sig.c slcompress.c sync.c systems.c tcp.c throughput.c \
+ timer.c tty.c tun.c vjcomp.c
CFLAGS+=-Wall
LDADD+= -lcrypt -lmd -lutil -lz
DPADD+= ${LIBCRYPT} ${LIBMD} ${LIBUTIL} ${LIBZ}
diff --git a/usr.sbin/ppp/README.changes b/usr.sbin/ppp/README.changes
index 159aee8..d70c053 100644
--- a/usr.sbin/ppp/README.changes
+++ b/usr.sbin/ppp/README.changes
@@ -83,3 +83,5 @@ 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
+ ``show physical''.
diff --git a/usr.sbin/ppp/acf.c b/usr.sbin/ppp/acf.c
new file mode 100644
index 0000000..2839ca2
--- /dev/null
+++ b/usr.sbin/ppp/acf.c
@@ -0,0 +1,111 @@
+/*-
+ * 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:$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <termios.h>
+
+#include "defs.h"
+#include "layer.h"
+#include "timer.h"
+#include "fsm.h"
+#include "log.h"
+#include "mbuf.h"
+#include "acf.h"
+#include "proto.h"
+#include "lcp.h"
+#include "throughput.h"
+#include "lqr.h"
+#include "hdlc.h"
+#include "ccp.h"
+#include "link.h"
+#include "descriptor.h"
+#include "async.h"
+#include "physical.h"
+
+int
+acf_WrapperOctets(struct lcp *lcp, u_short proto)
+{
+ return (proto == PROTO_LCP || lcp->his_acfcomp == 0) ? 2 : 0;
+}
+
+static struct mbuf *
+acf_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ 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);
+
+ return bp;
+}
+
+static struct mbuf *
+acf_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
+{
+ struct physical *p = link2physical(l);
+ u_char cp[2];
+
+ if (!p) {
+ log_Printf(LogERROR, "Can't Pull an acf packet from a logical link\n");
+ return bp;
+ }
+
+ if (mbuf_View(bp, cp, 2) == 2) {
+ if (!p->link.lcp.want_acfcomp) {
+ /* We expect the packet not to be compressed */
+ bp = mbuf_Read(bp, cp, 2);
+ if (cp[0] != HDLC_ADDR) {
+ p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.stats.badaddr++;
+ log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]);
+ mbuf_Free(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);
+ return NULL;
+ }
+ } 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);
+ }
+ }
+
+ return bp;
+}
+
+struct layer acflayer = { LAYER_ACF, "acf", acf_LayerPush, acf_LayerPull };
diff --git a/usr.sbin/ppp/acf.h b/usr.sbin/ppp/acf.h
new file mode 100644
index 0000000..ed2d2fe
--- /dev/null
+++ b/usr.sbin/ppp/acf.h
@@ -0,0 +1,33 @@
+/*-
+ * 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:$
+ */
+
+struct lcp;
+
+extern int acf_WrapperOctets(struct lcp *, u_short);
+
+extern struct layer acflayer;
diff --git a/usr.sbin/ppp/alias_cmd.c b/usr.sbin/ppp/alias_cmd.c
index 66b6db7..d35d492 100644
--- a/usr.sbin/ppp/alias_cmd.c
+++ b/usr.sbin/ppp/alias_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.22 1999/03/25 23:36:23 brian Exp $
+ * $Id: alias_cmd.c,v 1.23 1999/04/26 08:54:32 brian Exp $
*/
#include <sys/param.h>
@@ -24,6 +24,8 @@
#else
#include "alias.h"
#endif
+#include "layer.h"
+#include "proto.h"
#include "defs.h"
#include "command.h"
#include "log.h"
@@ -304,3 +306,96 @@ alias_Pptp(struct cmdargs const *arg)
PacketAliasPptp(addr);
return 0;
}
+
+static struct mbuf *
+alias_PadMbuf(struct mbuf *bp, int type)
+{
+ struct mbuf **last;
+ int len;
+
+ 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,
+ int pri, u_short *proto)
+{
+ if (!bundle->AliasEnabled || *proto != PROTO_IP)
+ return bp;
+
+ bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPQ));
+ PacketAliasOut(MBUF_CTOP(bp), bp->cnt);
+ bp->cnt = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len);
+
+ return bp;
+}
+
+static struct mbuf *
+alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ u_short *proto)
+{
+ struct ip *pip, *piip;
+ int ret;
+ struct mbuf **last;
+ char *fptr;
+
+ if (!bundle->AliasEnabled || *proto != PROTO_IP)
+ return bp;
+
+ bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPIN));
+ pip = (struct ip *)MBUF_CTOP(bp);
+ piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
+
+ if (pip->ip_p == IPPROTO_IGMP ||
+ (pip->ip_p == IPPROTO_IPIP && IN_CLASSD(ntohl(piip->ip_dst.s_addr))))
+ return bp;
+
+ ret = PacketAliasIn(MBUF_CTOP(bp), bp->cnt);
+
+ 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);
+ return NULL;
+ }
+
+ switch (ret) {
+ case PKT_ALIAS_OK:
+ break;
+
+ case PKT_ALIAS_UNRESOLVED_FRAGMENT:
+ /* Save the data for later */
+ fptr = malloc(bp->cnt);
+ mbuf_Read(bp, fptr, bp->cnt);
+ 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;
+ while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) {
+ PacketAliasFragmentIn(MBUF_CTOP(bp), fptr);
+ *last = mbuf_Alloc(ntohs(((struct ip *)fptr)->ip_len), MB_IPIN);
+ memcpy(MBUF_CTOP(*last), fptr, (*last)->cnt);
+ free(fptr);
+ last = &(*last)->pnext;
+ }
+ break;
+
+ default:
+ mbuf_Free(bp);
+ bp = NULL;
+ break;
+ }
+
+ return bp;
+}
+
+struct layer aliaslayer =
+ { LAYER_ALIAS, "alias", alias_LayerPush, alias_LayerPull };
diff --git a/usr.sbin/ppp/alias_cmd.h b/usr.sbin/ppp/alias_cmd.h
index cf96bcf..05c0ad0 100644
--- a/usr.sbin/ppp/alias_cmd.h
+++ b/usr.sbin/ppp/alias_cmd.h
@@ -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.h,v 1.9 1999/03/07 15:02:37 brian Exp $
+ * $Id: alias_cmd.h,v 1.10 1999/03/07 18:13:44 brian Exp $
*/
struct cmdargs;
@@ -11,3 +11,5 @@ 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/arp.c b/usr.sbin/ppp/arp.c
index f7c56aa..b416652 100644
--- a/usr.sbin/ppp/arp.c
+++ b/usr.sbin/ppp/arp.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: arp.c,v 1.32 1999/01/28 01:56:30 brian Exp $
+ * $Id: arp.c,v 1.33 1999/04/26 08:54:24 brian Exp $
*
*/
@@ -42,8 +42,10 @@
#include <stdlib.h>
#include <string.h>
#include <sys/sysctl.h>
+#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "id.h"
diff --git a/usr.sbin/ppp/async.c b/usr.sbin/ppp/async.c
index ff24153..8bf26c3 100644
--- a/usr.sbin/ppp/async.c
+++ b/usr.sbin/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.17 1998/06/16 19:40:34 brian Exp $
+ * $Id: async.c,v 1.18 1999/04/11 08:51:04 brian Exp $
*
*/
#include <sys/types.h>
@@ -25,6 +25,7 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
@@ -33,7 +34,7 @@
#include "lqr.h"
#include "hdlc.h"
#include "lcp.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "async.h"
#include "throughput.h"
#include "ccp.h"
@@ -61,10 +62,10 @@ async_SetLinkParams(struct async *async, struct lcp *lcp)
}
/*
- * Encode into async HDLC byte code if necessary
+ * Encode into async HDLC byte code
*/
static void
-HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto)
+async_Encode(struct async *async, u_char **cp, u_char c, int proto)
{
u_char *wp;
@@ -82,39 +83,44 @@ HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto)
*cp = wp;
}
-void
-async_Output(int pri, struct mbuf *bp, int proto, struct physical *physical)
+static struct mbuf *
+async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
{
+ struct physical *p = link2physical(l);
u_char *cp, *sp, *ep;
struct mbuf *wp;
int cnt;
- if (mbuf_Length(bp) > HDLCSIZE) {
+ if (!p || mbuf_Length(bp) > HDLCSIZE) {
mbuf_Free(bp);
- return;
+ return NULL;
}
- cp = physical->async.xbuff;
+
+ cp = p->async.xbuff;
ep = cp + HDLCSIZE - 10;
wp = bp;
*cp++ = HDLC_SYN;
while (wp) {
sp = MBUF_CTOP(wp);
for (cnt = wp->cnt; cnt > 0; cnt--) {
- HdlcPutByte(&physical->async, &cp, *sp++, proto);
+ async_Encode(&p->async, &cp, *sp++, *proto);
if (cp >= ep) {
mbuf_Free(bp);
- return;
+ return NULL;
}
}
wp = wp->next;
}
*cp++ = HDLC_SYN;
- cnt = cp - physical->async.xbuff;
- log_DumpBuff(LogASYNC, "WriteModem", physical->async.xbuff, cnt);
- link_Write(&physical->link, pri, (char *)physical->async.xbuff, cnt);
- link_AddOutOctets(&physical->link, cnt);
+ cnt = cp - p->async.xbuff;
mbuf_Free(bp);
+ bp = mbuf_Alloc(cnt, MB_ASYNC);
+ memcpy(MBUF_CTOP(bp), p->async.xbuff, cnt);
+
+ log_DumpBp(LogASYNC, "WriteModem", bp);
+ return bp;
}
static struct mbuf *
@@ -160,25 +166,34 @@ async_Decode(struct async *async, u_char c)
return NULL;
}
-void
-async_Input(struct bundle *bundle, u_char *buff, int cnt,
- struct physical *physical)
+static struct mbuf *
+async_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
+ u_short *proto)
{
- struct mbuf *bp;
+ struct mbuf *nbp, **last;
+ struct physical *p = link2physical(l);
+ u_char *ch;
+ size_t cnt;
+
+ if (!p) {
+ log_Printf(LogERROR, "Can't Pull an async packet from a logical link\n");
+ return bp;
+ }
- link_AddInOctets(&physical->link, cnt);
-
- if (physical_IsSync(physical)) {
- bp = mbuf_Alloc(cnt, MB_ASYNC);
- memcpy(MBUF_CTOP(bp), buff, cnt);
- bp->cnt = cnt;
- hdlc_Input(bundle, bp, physical);
- } else {
- while (cnt > 0) {
- bp = async_Decode(&physical->async, *buff++);
- if (bp)
- hdlc_Input(bundle, bp, physical);
- cnt--;
+ last = &nbp;
+
+ while (bp) {
+ ch = MBUF_CTOP(bp);
+ for (cnt = bp->cnt; cnt; cnt--) {
+ *last = async_Decode(&p->async, *ch++);
+ if (*last != NULL)
+ last = &(*last)->pnext;
}
+ bp = mbuf_FreeSeg(bp);
}
+
+ return nbp;
}
+
+struct layer asynclayer =
+ { LAYER_ASYNC, "async", async_LayerPush, async_LayerPull };
diff --git a/usr.sbin/ppp/async.h b/usr.sbin/ppp/async.h
index 4bd30a9..5981547 100644
--- a/usr.sbin/ppp/async.h
+++ b/usr.sbin/ppp/async.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: async.h,v 1.3 1998/05/21 21:43:57 brian Exp $
+ * $Id: async.h,v 1.4 1998/06/27 12:03:48 brian Exp $
*/
#define HDLCSIZE (MAX_MRU*2+6)
@@ -48,5 +48,5 @@ struct bundle;
extern void async_Init(struct async *);
extern void async_SetLinkParams(struct async *, struct lcp *);
-extern void async_Output(int, struct mbuf *, int, struct physical *);
-extern void async_Input(struct bundle *, u_char *, int, struct physical *);
+
+extern struct layer asynclayer;
diff --git a/usr.sbin/ppp/auth.c b/usr.sbin/ppp/auth.c
index a60b525..9cd0292 100644
--- a/usr.sbin/ppp/auth.c
+++ b/usr.sbin/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.42 1999/02/26 21:28:06 brian Exp $
+ * $Id: auth.c,v 1.43 1999/03/31 14:21:44 brian Exp $
*
* TODO:
* o Implement check against with registered IP addresses.
@@ -34,6 +34,7 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "mbuf.h"
#include "defs.h"
#include "log.h"
@@ -52,7 +53,7 @@
#include "link.h"
#include "descriptor.h"
#include "chat.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "filter.h"
#include "mp.h"
#ifndef NORADIUS
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index c84828f..eb39858 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bundle.c,v 1.50 1999/03/25 11:37:51 brian Exp $
+ * $Id: bundle.c,v 1.51 1999/04/26 08:54:33 brian Exp $
*/
#include <sys/param.h>
@@ -49,13 +49,7 @@
#include <termios.h>
#include <unistd.h>
-#ifndef NOALIAS
-#ifdef __FreeBSD__
-#include <alias.h>
-#else
-#include "alias.h"
-#endif
-#endif
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
@@ -82,9 +76,8 @@
#include "bundle.h"
#include "async.h"
#include "physical.h"
-#include "modem.h"
#include "auth.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "chap.h"
#include "tun.h"
#include "prompt.h"
@@ -349,11 +342,11 @@ bundle_LayerUp(void *v, struct fsm *fp)
bundle->ifSpeed = 0;
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state == DATALINK_OPEN)
- bundle->ifSpeed += modem_Speed(dl->physical);
+ bundle->ifSpeed += physical_GetSpeed(dl->physical);
tun_configure(bundle, bundle->ncp.mp.peer_mrru);
bundle->autoload.running = 1;
} else {
- bundle->ifSpeed = modem_Speed(p);
+ bundle->ifSpeed = physical_GetSpeed(p);
tun_configure(bundle, fsm2lcp(fp)->his_mru);
}
} else if (fp->proto == PROTO_IPCP) {
@@ -389,7 +382,7 @@ bundle_LayerDown(void *v, struct fsm *fp)
if (fp == &dl->physical->link.lcp.fsm)
lost = dl;
else if (dl->state == DATALINK_OPEN)
- bundle->ifSpeed += modem_Speed(dl->physical);
+ bundle->ifSpeed += physical_GetSpeed(dl->physical);
if (bundle->ifSpeed)
/* Don't configure down to a speed of 0 */
@@ -639,11 +632,8 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
if (Enabled(bundle, OPT_LOOPBACK)) {
pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
if (pri >= 0) {
- struct mbuf *bp;
-
- bp = mbuf_Alloc(n, MB_IPIN);
- memcpy(MBUF_CTOP(bp), tun.data, n);
- ip_Input(bundle, bp);
+ n += sizeof tun - sizeof tun.data;
+ write(bundle->dev.fd, &tun, n);
log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
}
return;
@@ -675,15 +665,8 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
}
pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
- if (pri >= 0) {
-#ifndef NOALIAS
- if (bundle->AliasEnabled) {
- PacketAliasOut(tun.data, sizeof tun.data);
- n = ntohs(((struct ip *)tun.data)->ip_len);
- }
-#endif
+ if (pri >= 0)
ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n);
- }
}
}
@@ -1194,7 +1177,7 @@ bundle_FillQueues(struct bundle *bundle)
if (dl->state == DATALINK_OPEN) {
add = link_QueueLen(&dl->physical->link);
if (add == 0 && dl->physical->out == NULL)
- add = ip_FlushPacket(&dl->physical->link, bundle);
+ add = ip_PushPacket(&dl->physical->link, bundle);
total += add;
}
}
@@ -1211,7 +1194,7 @@ bundle_ShowLinks(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
- prompt_Printf(arg->prompt, " weight %d, %d bytes/sec",
+ prompt_Printf(arg->prompt, " weight %d, %Ld bytes/sec",
dl->mp.weight,
dl->physical->link.throughput.OctetsPerSecond);
prompt_Printf(arg->prompt, "\n");
@@ -1704,10 +1687,10 @@ bundle_setsid(struct bundle *bundle, int holdsession)
break;
default:
close(fds[0]);
- /* Give away all our modem locks (to the final process) */
+ /* Give away all our physical locks (to the final process) */
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state != DATALINK_CLOSED)
- modem_ChangedPid(dl->physical, pid);
+ physical_ChangedPid(dl->physical, pid);
write(fds[1], "!", 1); /* done */
close(fds[1]);
exit(0);
@@ -1716,10 +1699,10 @@ bundle_setsid(struct bundle *bundle, int holdsession)
break;
default:
close(fds[0]);
- /* Give away all our modem locks (to the intermediate process) */
+ /* Give away all our physical locks (to the intermediate process) */
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state != DATALINK_CLOSED)
- modem_ChangedPid(dl->physical, pid);
+ physical_ChangedPid(dl->physical, pid);
write(fds[1], "!", 1); /* done */
close(fds[1]);
if (holdsession) {
diff --git a/usr.sbin/ppp/cbcp.c b/usr.sbin/ppp/cbcp.c
index a901ef9..bea92f3 100644
--- a/usr.sbin/ppp/cbcp.c
+++ b/usr.sbin/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/02/26 21:28:07 brian Exp $
+ * $Id: cbcp.c,v 1.11 1999/03/29 08:21:26 brian Exp $
*/
#include <sys/param.h>
@@ -33,6 +33,7 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "log.h"
#include "timer.h"
@@ -47,7 +48,7 @@
#include "link.h"
#include "async.h"
#include "physical.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "cbcp.h"
#include "mp.h"
#include "chat.h"
@@ -201,7 +202,8 @@ cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data)
head->length = htons(sizeof *head + data->length);
memcpy(MBUF_CTOP(bp) + sizeof *head, data, data->length);
log_DumpBp(LogDEBUG, "cbcp_Output", bp);
- hdlc_Output(&cbcp->p->link, PRI_LINK, PROTO_CBCP, bp);
+ link_PushPacket(&cbcp->p->link, bp, cbcp->p->dl->bundle,
+ PRI_LINK, PROTO_CBCP);
}
static const char *
@@ -600,26 +602,33 @@ cbcp_SendAck(struct cbcp *cbcp)
cbcp_NewPhase(cbcp, CBCP_ACKSENT); /* Wait for an ACK */
}
-void
-cbcp_Input(struct physical *p, struct mbuf *bp)
+extern struct mbuf *
+cbcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
+ struct physical *p = link2physical(l);
struct cbcp_header *head;
struct cbcp_data *data;
struct cbcp *cbcp = &p->dl->cbcp;
int len;
+ if (p == NULL) {
+ log_Printf(LogERROR, "cbcp_Input: Not a physical link - dropped\n");
+ mbuf_Free(bp);
+ return NULL;
+ }
+
bp = mbuf_Contiguous(bp);
len = mbuf_Length(bp);
if (len < sizeof(struct cbcp_header)) {
mbuf_Free(bp);
- return;
+ 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);
- return;
+ return NULL;
}
/* XXX check the id */
@@ -706,6 +715,7 @@ cbcp_Input(struct physical *p, struct mbuf *bp)
}
mbuf_Free(bp);
+ return NULL;
}
void
diff --git a/usr.sbin/ppp/cbcp.h b/usr.sbin/ppp/cbcp.h
index d55800a..e01b36d 100644
--- a/usr.sbin/ppp/cbcp.h
+++ b/usr.sbin/ppp/cbcp.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cbcp.h,v 1.1 1998/08/07 18:44:16 brian Exp $
*/
struct mbuf;
@@ -60,6 +60,6 @@ struct cbcp {
extern void cbcp_Init(struct cbcp *, struct physical *);
extern void cbcp_Up(struct cbcp *);
-extern void cbcp_Input(struct physical *, struct mbuf *);
+extern struct mbuf *cbcp_Input(struct bundle *, struct link *, struct mbuf *);
extern void cbcp_Down(struct cbcp *);
extern void cbcp_ReceiveTerminateReq(struct physical *);
diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c
index e5adc98..1b84252 100644
--- a/usr.sbin/ppp/ccp.c
+++ b/usr.sbin/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.45 1999/03/31 14:21:44 brian Exp $
+ * $Id: ccp.c,v 1.46 1999/05/02 14:33:39 brian Exp $
*
* TODO:
* o Support other compression protocols
@@ -33,13 +33,14 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
#include "fsm.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "lcp.h"
#include "ccp.h"
#include "pred.h"
@@ -144,11 +145,13 @@ ccp_ReportStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, ccp->fsm.name,
State2Nam(ccp->fsm.state));
- prompt_Printf(arg->prompt, " My protocol = %s, His protocol = %s\n",
- protoname(ccp->my_proto), protoname(ccp->his_proto));
- prompt_Printf(arg->prompt, " Output: %ld --> %ld, Input: %ld --> %ld\n",
- ccp->uncompout, ccp->compout,
- ccp->compin, ccp->uncompin);
+ if (ccp->fsm.state == ST_OPENED) {
+ prompt_Printf(arg->prompt, " My protocol = %s, His protocol = %s\n",
+ protoname(ccp->my_proto), protoname(ccp->his_proto));
+ prompt_Printf(arg->prompt, " Output: %ld --> %ld, Input: %ld --> %ld\n",
+ ccp->uncompout, ccp->compout,
+ ccp->compin, ccp->uncompin);
+ }
prompt_Printf(arg->prompt, "\n Defaults: ");
prompt_Printf(arg->prompt, "FSM retry = %us, max %u Config"
@@ -529,18 +532,19 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
}
}
-void
-ccp_Input(struct ccp *ccp, struct bundle *bundle, struct mbuf *bp)
+extern struct mbuf *
+ccp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
/* Got PROTO_CCP from link */
if (bundle_Phase(bundle) == PHASE_NETWORK)
- fsm_Input(&ccp->fsm, bp);
+ 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",
- ccp->fsm.link->name, bundle_PhaseName(bundle));
+ l->ccp.fsm.link->name, bundle_PhaseName(bundle));
mbuf_Free(bp);
}
+ return NULL;
}
static void
@@ -571,42 +575,40 @@ CcpRecvResetAck(struct fsm *fp, u_char id)
(*algorithm[ccp->in.algorithm]->i.Reset)(ccp->in.state);
}
-int
-ccp_Compress(struct ccp *ccp, struct link *l, int pri, u_short proto,
- struct mbuf *m)
+static struct mbuf *
+ccp_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
{
- /*
- * Compress outgoing data. It's already deemed to be suitable Network
- * Layer data.
- */
- if (ccp->fsm.state == ST_OPENED && ccp->out.state != NULL)
- return (*algorithm[ccp->out.algorithm]->o.Write)
- (ccp->out.state, ccp, l, pri, proto, m);
- return 0;
+ if (PROTO_COMPRESSIBLE(*proto) && l->ccp.fsm.state == ST_OPENED &&
+ l->ccp.out.state != NULL)
+ return (*algorithm[l->ccp.out.algorithm]->o.Write)
+ (l->ccp.out.state, &l->ccp, l, pri, proto, bp);
+
+ return bp;
}
-struct mbuf *
-ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp)
+static struct mbuf *
+ccp_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
{
/*
* If proto isn't PROTO_[I]COMPD, we still want to pass it to the
* decompression routines so that the dictionary's updated
*/
- if (ccp->fsm.state == ST_OPENED) {
+ if (l->ccp.fsm.state == ST_OPENED) {
if (*proto == PROTO_COMPD || *proto == PROTO_ICOMPD) {
/* Decompress incoming data */
- if (ccp->reset_sent != -1)
+ if (l->ccp.reset_sent != -1)
/* Send another REQ and put the packet in the bit bucket */
- fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->reset_sent, NULL, 0);
- else if (ccp->in.state != NULL)
- return (*algorithm[ccp->in.algorithm]->i.Read)
- (ccp->in.state, ccp, proto, bp);
+ fsm_Output(&l->ccp.fsm, CODE_RESETREQ, l->ccp.reset_sent, NULL, 0);
+ else if (l->ccp.in.state != NULL)
+ return (*algorithm[l->ccp.in.algorithm]->i.Read)
+ (l->ccp.in.state, &l->ccp, proto, bp);
mbuf_Free(bp);
bp = NULL;
- } else if (PROTO_COMPRESSIBLE(*proto) && ccp->in.state != NULL)
+ } else if (PROTO_COMPRESSIBLE(*proto) && l->ccp.in.state != NULL)
/* Add incoming Network Layer traffic to our dictionary */
- (*algorithm[ccp->in.algorithm]->i.DictSetup)
- (ccp->in.state, ccp, *proto, bp);
+ (*algorithm[l->ccp.in.algorithm]->i.DictSetup)
+ (l->ccp.in.state, &l->ccp, *proto, bp);
}
return bp;
@@ -638,3 +640,5 @@ ccp_SetOpenMode(struct ccp *ccp)
return 0; /* No CCP at all */
}
+
+struct layer ccplayer = { LAYER_CCP, "ccp", ccp_LayerPush, ccp_LayerPull };
diff --git a/usr.sbin/ppp/ccp.h b/usr.sbin/ppp/ccp.h
index 5cac40d..effbd40 100644
--- a/usr.sbin/ppp/ccp.h
+++ b/usr.sbin/ppp/ccp.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ccp.h,v 1.19 1998/06/30 23:04:12 brian Exp $
+ * $Id: ccp.h,v 1.20 1999/02/26 21:28:07 brian Exp $
*
* TODO:
*/
@@ -109,8 +109,8 @@ struct ccp_algorithm {
void *(*Init)(struct lcp_opt *);
void (*Term)(void *);
void (*Reset)(void *);
- int (*Write)(void *, struct ccp *, struct link *, int, u_short,
- struct mbuf *);
+ struct mbuf *(*Write)(void *, struct ccp *, struct link *, int, u_short *,
+ struct mbuf *);
} o;
};
@@ -119,10 +119,10 @@ extern void ccp_Init(struct ccp *, struct bundle *, struct link *,
extern void ccp_Setup(struct ccp *);
extern void ccp_SendResetReq(struct fsm *);
-extern void ccp_Input(struct ccp *, struct bundle *, struct mbuf *);
+extern struct mbuf *ccp_Input(struct bundle *, struct link *, struct mbuf *);
extern int ccp_ReportStatus(struct cmdargs const *);
-extern int ccp_Compress(struct ccp *, struct link *, int, u_short, struct mbuf *);
-extern struct mbuf *ccp_Decompress(struct ccp *, u_short *, struct mbuf *);
extern u_short ccp_Proto(struct ccp *);
extern void ccp_SetupCallbacks(struct ccp *);
extern int ccp_SetOpenMode(struct ccp *);
+
+extern struct layer ccplayer;
diff --git a/usr.sbin/ppp/chap.c b/usr.sbin/ppp/chap.c
index e81e5e5..541a71d 100644
--- a/usr.sbin/ppp/chap.c
+++ b/usr.sbin/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.48 1999/04/01 11:05:22 brian Exp $
+ * $Id: chap.c,v 1.49 1999/04/21 08:03:51 brian Exp $
*
* TODO:
*/
@@ -41,12 +41,13 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "timer.h"
#include "fsm.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "lcp.h"
#include "lqr.h"
#include "hdlc.h"
@@ -101,7 +102,8 @@ ChapOutput(struct physical *physical, u_int code, u_int id,
log_Printf(LogPHASE, "Chap Output: %s\n", chapcodes[code]);
else
log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text);
- hdlc_Output(&physical->link, PRI_LINK, PROTO_CHAP, bp);
+ link_PushPacket(&physical->link, bp, physical->dl->bundle,
+ PRI_LINK, PROTO_CHAP);
}
static char *
@@ -532,9 +534,10 @@ chap_ReInit(struct chap *chap)
chap_Cleanup(chap, SIGTERM);
}
-void
-chap_Input(struct physical *p, struct mbuf *bp)
+struct mbuf *
+chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
+ struct physical *p = link2physical(l);
struct chap *chap = &p->dl->chap;
char *name, *key, *ans;
int len, nlen;
@@ -543,11 +546,17 @@ chap_Input(struct physical *p, struct mbuf *bp)
int lanman;
#endif
- if (bundle_Phase(p->dl->bundle) != PHASE_NETWORK &&
- bundle_Phase(p->dl->bundle) != PHASE_AUTHENTICATE) {
+ if (p == NULL) {
+ log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n");
+ mbuf_Free(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);
- return;
+ return NULL;
}
if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL &&
@@ -562,13 +571,13 @@ chap_Input(struct physical *p, struct mbuf *bp)
if (chap->auth.in.hdr.code != CHAP_CHALLENGE &&
chap->auth.id != chap->auth.in.hdr.id &&
- Enabled(p->dl->bundle, OPT_IDCHECK)) {
+ Enabled(bundle, OPT_IDCHECK)) {
/* Wrong conversation dude ! */
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);
- return;
+ return NULL;
}
chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */
@@ -582,7 +591,7 @@ chap_Input(struct physical *p, struct mbuf *bp)
if (len < 0) {
log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
mbuf_Free(bp);
- return;
+ return NULL;
}
*chap->challenge.peer = alen;
bp = mbuf_Read(bp, chap->challenge.peer + 1, alen);
@@ -601,12 +610,12 @@ chap_Input(struct physical *p, struct mbuf *bp)
if (len < 0) {
log_Printf(LogERROR, "Chap Input: Truncated response !\n");
mbuf_Free(bp);
- return;
+ return NULL;
}
if ((ans = malloc(alen + 2)) == NULL) {
log_Printf(LogERROR, "Chap Input: Out of memory !\n");
mbuf_Free(bp);
- return;
+ return NULL;
}
*ans = chap->auth.id;
bp = mbuf_Read(bp, ans + 1, alen);
@@ -623,7 +632,7 @@ chap_Input(struct physical *p, struct mbuf *bp)
if ((ans = malloc(len + 1)) == NULL) {
log_Printf(LogERROR, "Chap Input: Out of memory !\n");
mbuf_Free(bp);
- return;
+ return NULL;
}
bp = mbuf_Read(bp, ans, len);
ans[len] = '\0';
@@ -665,12 +674,12 @@ chap_Input(struct physical *p, struct mbuf *bp)
switch (chap->auth.in.hdr.code) {
case CHAP_CHALLENGE:
- if (*p->dl->bundle->cfg.auth.key == '!')
- chap_StartChild(chap, p->dl->bundle->cfg.auth.key + 1,
- p->dl->bundle->cfg.auth.name);
+ if (*bundle->cfg.auth.key == '!')
+ chap_StartChild(chap, bundle->cfg.auth.key + 1,
+ bundle->cfg.auth.name);
else
- chap_Respond(chap, p->dl->bundle->cfg.auth.name,
- p->dl->bundle->cfg.auth.key, p->link.lcp.his_authtype
+ chap_Respond(chap, bundle->cfg.auth.name,
+ bundle->cfg.auth.key, p->link.lcp.his_authtype
#ifdef HAVE_DES
, lanman
#endif
@@ -681,17 +690,17 @@ chap_Input(struct physical *p, struct mbuf *bp)
name = chap->auth.in.name;
nlen = strlen(name);
#ifndef NORADIUS
- if (*p->dl->bundle->radius.cfg.file) {
+ if (*bundle->radius.cfg.file) {
end = chap->challenge.local[*chap->challenge.local+1];
chap->challenge.local[*chap->challenge.local+1] = '\0';
- radius_Authenticate(&p->dl->bundle->radius, &chap->auth,
+ radius_Authenticate(&bundle->radius, &chap->auth,
chap->auth.in.name, ans,
chap->challenge.local + 1);
chap->challenge.local[*chap->challenge.local+1] = end;
} else
#endif
{
- key = auth_GetSecret(p->dl->bundle, name, nlen, p);
+ key = auth_GetSecret(bundle, name, nlen, p);
if (key) {
char *myans;
#ifdef HAVE_DES
@@ -760,4 +769,5 @@ chap_Input(struct physical *p, struct mbuf *bp)
}
mbuf_Free(bp);
+ return NULL;
}
diff --git a/usr.sbin/ppp/chap.h b/usr.sbin/ppp/chap.h
index fe12dae..083e651 100644
--- a/usr.sbin/ppp/chap.h
+++ b/usr.sbin/ppp/chap.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: chap.h,v 1.14 1999/02/18 19:45:06 brian Exp $
+ * $Id: chap.h,v 1.15 1999/04/21 08:03:51 brian Exp $
*
* TODO:
*/
@@ -55,4 +55,4 @@ struct chap {
extern void chap_Init(struct chap *, struct physical *);
extern void chap_ReInit(struct chap *);
-extern void chap_Input(struct physical *, struct mbuf *);
+extern struct mbuf *chap_Input(struct bundle *, struct link *, struct mbuf *);
diff --git a/usr.sbin/ppp/chat.c b/usr.sbin/ppp/chat.c
index ad56a01..f6fc574 100644
--- a/usr.sbin/ppp/chat.c
+++ b/usr.sbin/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.53 1999/01/28 01:56:31 brian Exp $
+ * $Id: chat.c,v 1.54 1999/02/12 00:52:29 brian Exp $
*/
#include <sys/param.h>
@@ -42,6 +42,7 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
@@ -73,7 +74,6 @@
#include "bundle.h"
#define BUFLEFT(c) (sizeof (c)->buf - ((c)->bufend - (c)->buf))
-#define issep(c) ((c) == '\t' || (c) == ' ')
static void ExecStr(struct physical *, char *, char *, int);
static char *ExpandString(struct chat *, const char *, char *, int, int);
@@ -301,9 +301,9 @@ chat_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
*/
if (c->state == CHAT_EXPECT)
- return physical_UpdateSet(&c->physical->desc, r, NULL, e, n, 1);
+ return physical_doUpdateSet(&c->physical->desc, r, NULL, e, n, 1);
else
- return physical_UpdateSet(&c->physical->desc, NULL, w, e, n, 1);
+ return physical_doUpdateSet(&c->physical->desc, NULL, w, e, n, 1);
}
static int
@@ -566,61 +566,6 @@ chat_Destroy(struct chat *c)
c->abort.num = 0;
}
-static char *
-findblank(char *p, int instring)
-{
- if (instring) {
- while (*p) {
- if (*p == '\\') {
- strcpy(p, p + 1);
- if (!*p)
- break;
- } else if (*p == '"')
- return (p);
- p++;
- }
- } else {
- while (*p) {
- if (issep(*p))
- return (p);
- p++;
- }
- }
- return p;
-}
-
-int
-MakeArgs(char *script, char **pvect, int maxargs)
-{
- int nargs, nb;
- int instring;
-
- nargs = 0;
- while (*script) {
- nb = strspn(script, " \t");
- script += nb;
- 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++ = '\0';
- }
- }
- *pvect = NULL;
- return nargs;
-}
-
/*
* \c don't add a cr
* \d Sleep a little (delay 2 seconds
@@ -743,7 +688,7 @@ ExecStr(struct physical *physical, char *command, char *out, int olen)
close(fids[0]);
timer_TermService();
fids[1] = fcntl(fids[1], F_DUPFD, 4);
- dup2(physical_GetFD(physical), STDIN_FILENO);
+ dup2(physical->fd, STDIN_FILENO);
dup2(STDIN_FILENO, STDOUT_FILENO);
dup2(fids[1], STDERR_FILENO);
close(3);
diff --git a/usr.sbin/ppp/chat.h b/usr.sbin/ppp/chat.h
index e57f32e..037b57f 100644
--- a/usr.sbin/ppp/chat.h
+++ b/usr.sbin/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.9.2.8 1998/05/01 19:24:13 brian Exp $
+ * $Id: chat.h,v 1.10 1998/05/21 21:44:39 brian Exp $
*/
#define CHAT_EXPECT 0
@@ -79,4 +79,3 @@ struct chat {
extern void chat_Init(struct chat *, struct physical *, const char *, int,
const char *);
extern void chat_Destroy(struct chat *);
-extern int MakeArgs(char *, char **, int); /* Mangles the first arg ! */
diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c
index 7644978..ecc814b 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/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.190 1999/03/25 23:36:23 brian Exp $
+ * $Id: command.c,v 1.191 1999/04/26 08:54:33 brian Exp $
*
*/
#include <sys/param.h>
@@ -48,6 +48,7 @@
#include "alias.h"
#endif
#endif
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
@@ -61,7 +62,6 @@
#include "lqr.h"
#include "hdlc.h"
#include "ipcp.h"
-#include "modem.h"
#ifndef NOALIAS
#include "alias_cmd.h"
#endif
@@ -120,6 +120,8 @@
#define VAR_RECVPIPE 28
#define VAR_RADIUS 29
#define VAR_CD 30
+#define VAR_PARITY 31
+#define VAR_CRTSCTS 32
/* ``accept|deny|disable|enable'' masks */
#define NEG_HISMASK (1)
@@ -140,8 +142,8 @@
#define NEG_VJCOMP 51
#define NEG_DNS 52
-const char Version[] = "2.11";
-const char VersionDate[] = "$Date: 1999/03/25 23:36:23 $";
+const char Version[] = "2.2";
+const char VersionDate[] = "$Date: 1999/04/26 08:54:33 $";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@@ -622,7 +624,8 @@ static struct cmdtab const Commands[] = {
{"bg", "!bg", BgShellCommand, LOCAL_AUTH,
"Run a background command", "[!]bg command"},
{"clear", NULL, ClearCommand, LOCAL_AUTH | LOCAL_CX_OPT,
- "Clear throughput statistics", "clear ipcp|modem [current|overall|peak]..."},
+ "Clear throughput statistics",
+ "clear ipcp|physical [current|overall|peak]..."},
{"clone", NULL, CloneCommand, LOCAL_AUTH | LOCAL_CX,
"Clone a link", "clone newname..."},
{"close", NULL, CloseCommand, LOCAL_AUTH | LOCAL_CX_OPT,
@@ -638,7 +641,7 @@ static struct cmdtab const Commands[] = {
{"disable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
"Disable option", "disable option .."},
{"down", NULL, DownCommand, LOCAL_AUTH | LOCAL_CX_OPT,
- "Generate a down event", "down"},
+ "Generate a down event", "down [ccp|lcp]"},
{"enable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
"Enable option", "enable option .."},
{"iface", "interface", RunListCommand, LOCAL_AUTH,
@@ -764,8 +767,8 @@ static struct cmdtab const ShowCommands[] = {
"log levels", "show log"},
{"mem", NULL, mbuf_Show, LOCAL_AUTH,
"mbuf allocations", "show mem"},
- {"modem", NULL, modem_ShowStatus, LOCAL_AUTH | LOCAL_CX,
- "(low-level) link info", "show modem"},
+ {"physical", NULL, physical_ShowStatus, LOCAL_AUTH | LOCAL_CX,
+ "(low-level) link info", "show physical"},
{"mp", "multilink", mp_ShowStatus, LOCAL_AUTH,
"multilink setup", "show mp"},
{"proto", NULL, ShowProtocolStats, LOCAL_AUTH | LOCAL_CX_OPT,
@@ -1250,13 +1253,6 @@ SetServer(struct cmdargs const *arg)
}
static int
-SetModemParity(struct cmdargs const *arg)
-{
- return arg->argc > arg->argn ? modem_SetParity(arg->cx->physical,
- arg->argv[arg->argn]) : -1;
-}
-
-static int
SetEscape(struct cmdargs const *arg)
{
int code;
@@ -1738,24 +1734,29 @@ SetVariable(struct cmdargs const *arg)
cx->physical->cfg.cd.required = 0;
}
break;
- }
- return err ? 1 : 0;
-}
+ case VAR_PARITY:
+ if (arg->argc == arg->argn + 1)
+ return physical_SetParity(arg->cx->physical, argp);
+ else {
+ err = "Parity value must be odd, even or none\n";
+ log_Printf(LogWARN, err);
+ }
+ break;
-static int
-SetCtsRts(struct cmdargs const *arg)
-{
- if (arg->argc == arg->argn+1) {
- if (strcmp(arg->argv[arg->argn], "on") == 0)
+ case VAR_CRTSCTS:
+ if (strcasecmp(argp, "on") == 0)
physical_SetRtsCts(arg->cx->physical, 1);
- else if (strcmp(arg->argv[arg->argn], "off") == 0)
+ else if (strcasecmp(argp, "off") == 0)
physical_SetRtsCts(arg->cx->physical, 0);
- else
- return -1;
- return 0;
+ else {
+ err = "RTS/CTS value must be on or off\n";
+ log_Printf(LogWARN, err);
+ }
+ break;
}
- return -1;
+
+ return err ? 1 : 0;
}
static struct cmdtab const SetCommands[] = {
@@ -1783,13 +1784,14 @@ static struct cmdtab const SetCommands[] = {
(const void *)VAR_CHAPRETRY},
{"choked", NULL, SetVariable, LOCAL_AUTH,
"choked timeout", "set choked [secs]", (const void *)VAR_CHOKED},
- {"ctsrts", "crtscts", SetCtsRts, LOCAL_AUTH | LOCAL_CX,
- "Use hardware flow control", "set ctsrts [on|off]"},
+ {"ctsrts", "crtscts", SetVariable, LOCAL_AUTH | LOCAL_CX,
+ "Use hardware flow control", "set ctsrts [on|off]",
+ (const char *)VAR_CRTSCTS},
{"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
"deflate window sizes", "set deflate out-winsize in-winsize",
(const void *) VAR_WINSIZE},
{"device", "line", SetVariable, LOCAL_AUTH | LOCAL_CX,
- "modem device name", "set device|line device-name[,device-name]",
+ "physical device name", "set device|line device-name[,device-name]",
(const void *) VAR_DEVICE},
{"dial", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
"dialing script", "set dial chat-script", (const void *) VAR_DIAL},
@@ -1832,8 +1834,8 @@ static struct cmdtab const SetCommands[] = {
"set openmode active|passive [secs]", (const void *)VAR_OPENMODE},
{"papretry", "papretries", SetVariable, LOCAL_AUTH | LOCAL_CX, "PAP retries",
"set papretry value [attempts]", (const void *)VAR_PAPRETRY},
- {"parity", NULL, SetModemParity, LOCAL_AUTH | LOCAL_CX,
- "modem parity", "set parity [odd|even|none]"},
+ {"parity", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "serial parity",
+ "set parity [odd|even|none]", (const void *)VAR_PARITY},
{"phone", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "telephone number(s)",
"set phone phone1[:phone2[...]]", (const void *)VAR_PHONE},
{"proctitle", "title", SetProcTitle, LOCAL_AUTH,
@@ -1853,7 +1855,7 @@ static struct cmdtab const SetCommands[] = {
{"server", "socket", SetServer, LOCAL_AUTH,
"server port", "set server|socket TcpPort|LocalName|none password [mask]"},
{"speed", NULL, SetModemSpeed, LOCAL_AUTH | LOCAL_CX,
- "modem speed", "set speed value"},
+ "physical speed", "set speed value|sync"},
{"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH | LOCAL_CX,
"STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"},
{"timeout", NULL, SetVariable, LOCAL_AUTH, "Idle timeout",
@@ -1977,7 +1979,11 @@ AliasEnable(struct cmdargs const *arg)
{
if (arg->argc == arg->argn+1) {
if (strcasecmp(arg->argv[arg->argn], "yes") == 0) {
- arg->bundle->AliasEnabled = 1;
+ if (!arg->bundle->AliasEnabled) {
+ if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED)
+ PacketAliasSetAddress(arg->bundle->ncp.ipcp.my_ip);
+ arg->bundle->AliasEnabled = 1;
+ }
return 0;
} else if (strcasecmp(arg->argv[arg->argn], "no") == 0) {
arg->bundle->AliasEnabled = 0;
@@ -2373,12 +2379,12 @@ ClearCommand(struct cmdargs const *arg)
if (arg->argc < arg->argn + 1)
return -1;
- if (strcasecmp(arg->argv[arg->argn], "modem") == 0) {
+ if (strcasecmp(arg->argv[arg->argn], "physical") == 0) {
cx = arg->cx;
if (!cx)
cx = bundle2datalink(arg->bundle, NULL);
if (!cx) {
- log_Printf(LogWARN, "A link must be specified for ``clear modem''\n");
+ log_Printf(LogWARN, "A link must be specified for ``clear physical''\n");
return 1;
}
t = &cx->physical->link.throughput;
diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c
index ea1a3d8..e06c8b8 100644
--- a/usr.sbin/ppp/datalink.c
+++ b/usr.sbin/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.36 1999/04/05 21:52:10 brian Exp $
+ * $Id: datalink.c,v 1.37 1999/04/06 14:48:10 brian Exp $
*/
#include <sys/param.h>
@@ -39,6 +39,7 @@
#include <sys/uio.h>
#include <termios.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
@@ -64,9 +65,8 @@
#include "bundle.h"
#include "chat.h"
#include "auth.h"
-#include "modem.h"
#include "prompt.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "pap.h"
#include "chap.h"
#include "command.h"
@@ -114,13 +114,13 @@ static void
datalink_HangupDone(struct datalink *dl)
{
if (dl->physical->type == PHYS_DEDICATED && !dl->bundle->CleaningUp &&
- physical_GetFD(dl->physical) != -1) {
- /* Don't close our modem if the link is dedicated */
+ dl->physical->fd != -1) {
+ /* Don't close our device if the link is dedicated */
datalink_LoginDone(dl);
return;
}
- modem_Close(dl->physical);
+ physical_Close(dl->physical);
dl->phone.chosen = "N/A";
if (dl->cbcp.required) {
@@ -202,18 +202,18 @@ datalink_LoginDone(struct datalink *dl)
dl->dial.tries = -1;
dl->dial.incs = 0;
datalink_NewState(dl, DATALINK_READY);
- } else if (modem_Raw(dl->physical, dl->bundle) < 0) {
+ } else if (!physical_Raw(dl->physical)) {
dl->dial.tries = 0;
log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n");
if (dl->script.run) {
datalink_NewState(dl, DATALINK_HANGUP);
- modem_Offline(dl->physical);
+ physical_Offline(dl->physical);
chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL);
} else {
timer_Stop(&dl->physical->Timer);
if (dl->physical->type == PHYS_DEDICATED)
/* force a redial timeout */
- modem_Close(dl->physical);
+ physical_Close(dl->physical);
datalink_HangupDone(dl);
}
} else {
@@ -260,7 +260,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
if (dl->dial.timer.state != TIMER_RUNNING) {
if (--dl->dial.tries < 0)
dl->dial.tries = 0;
- if (modem_Open(dl->physical, dl->bundle) >= 0) {
+ if (physical_Open(dl->physical, dl->bundle) >= 0) {
log_WritePrompts(dl, "%s: Entering terminal mode on %s\r\n"
"Type `~?' for help\r\n", dl->name,
dl->physical->name.full);
@@ -279,10 +279,10 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
} else {
if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) &&
dl->cfg.dial.max)
- log_Printf(LogCHAT, "Failed to open modem (attempt %u of %d)\n",
+ log_Printf(LogCHAT, "Failed to open device (attempt %u of %d)\n",
dl->cfg.dial.max - dl->dial.tries, dl->cfg.dial.max);
else
- log_Printf(LogCHAT, "Failed to open modem\n");
+ log_Printf(LogCHAT, "Failed to open device\n");
if (dl->bundle->CleaningUp ||
(!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) &&
@@ -338,7 +338,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
case DATALINK_DIAL:
case DATALINK_LOGIN:
datalink_NewState(dl, DATALINK_HANGUP);
- modem_Offline(dl->physical); /* Is this required ? */
+ physical_Offline(dl->physical); /* Is this required ? */
chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL);
return datalink_UpdateSet(d, r, w, e, n);
}
@@ -466,7 +466,7 @@ datalink_ComeDown(struct datalink *dl, int how)
timer_Stop(&dl->physical->Timer);
datalink_NewState(dl, DATALINK_READY);
} else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP) {
- modem_Offline(dl->physical);
+ physical_Offline(dl->physical);
chat_Destroy(&dl->chat);
if (dl->script.run && dl->state != DATALINK_OPENING) {
datalink_NewState(dl, DATALINK_HANGUP);
@@ -764,7 +764,7 @@ datalink_Create(const char *name, struct bundle *bundle, int type)
dl->fsmp.LayerFinish = datalink_LayerFinish;
dl->fsmp.object = dl;
- if ((dl->physical = modem_Create(dl, type)) == NULL) {
+ if ((dl->physical = physical_Create(dl, type)) == NULL) {
free(dl->name);
free(dl);
return NULL;
@@ -815,7 +815,7 @@ datalink_Clone(struct datalink *odl, const char *name)
memcpy(&dl->fsmp, &odl->fsmp, sizeof dl->fsmp);
dl->fsmp.object = dl;
- if ((dl->physical = modem_Create(dl, PHYS_INTERACTIVE)) == NULL) {
+ if ((dl->physical = physical_Create(dl, PHYS_INTERACTIVE)) == NULL) {
free(dl->name);
free(dl);
return NULL;
@@ -862,7 +862,7 @@ datalink_Destroy(struct datalink *dl)
timer_Stop(&dl->dial.timer);
result = dl->next;
- modem_Destroy(dl->physical);
+ physical_Destroy(dl->physical);
free(dl->name);
free(dl);
@@ -1251,7 +1251,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov,
dl->fsmp.LayerFinish = datalink_LayerFinish;
dl->fsmp.object = dl;
- dl->physical = iov2modem(dl, iov, niov, maxiov, fd);
+ dl->physical = iov2physical(dl, iov, niov, maxiov, fd);
if (!dl->physical) {
free(dl->name);
@@ -1306,7 +1306,7 @@ datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
dl ? realloc(dl->name, DATALINK_MAXNAME) : malloc(DATALINK_MAXNAME);
iov[(*niov)++].iov_len = DATALINK_MAXNAME;
- link_fd = modem2iov(dl ? dl->physical : NULL, iov, niov, maxiov, newpid);
+ link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, newpid);
if (link_fd == -1 && dl) {
free(dl->name);
diff --git a/usr.sbin/ppp/deflate.c b/usr.sbin/ppp/deflate.c
index d19d93c..261d3e2 100644
--- a/usr.sbin/ppp/deflate.c
+++ b/usr.sbin/ppp/deflate.c
@@ -23,13 +23,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: deflate.c,v 1.11 1998/08/07 18:42:48 brian Exp $
+ * $Id: deflate.c,v 1.12 1999/03/11 01:49:15 brian Exp $
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
+#include <termios.h>
#include <zlib.h>
#include "defs.h"
@@ -54,7 +55,7 @@ struct deflate_state {
static char garbage[10];
static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
-#define DEFLATE_CHUNK_LEN 1024 /* Allocate mbufs this size */
+#define DEFLATE_CHUNK_LEN 1600 /* Allocate mbufs this size */
static void
DeflateResetOutput(void *v)
@@ -67,8 +68,8 @@ DeflateResetOutput(void *v)
log_Printf(LogCCP, "Deflate: Output channel reset\n");
}
-static int
-DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
+static struct mbuf *
+DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
struct mbuf *mp)
{
struct deflate_state *state = (struct deflate_state *)v;
@@ -77,19 +78,19 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
struct mbuf *mo_head, *mo, *mi_head, *mi;
ilen = mbuf_Length(mp);
- log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", proto, ilen);
+ 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_HDLCOUT);
mi->next = mp;
rp = MBUF_CTOP(mi);
- if (proto < 0x100) { /* Compress the protocol */
- rp[0] = proto & 0377;
+ if (*proto < 0x100) { /* Compress the protocol */
+ rp[0] = *proto & 0377;
mi->cnt = 1;
} else { /* Don't compress the protocol */
- rp[0] = proto >> 8;
- rp[1] = proto & 0377;
+ rp[0] = *proto >> 8;
+ rp[1] = *proto & 0377;
mi->cnt = 2;
}
@@ -119,7 +120,7 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
mbuf_Free(mo_head);
mbuf_FreeSeg(mi_head);
state->seqno--;
- return 1; /* packet dropped */
+ return mp; /* Our dictionary's probably dead now :-( */
}
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
@@ -154,10 +155,10 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
mbuf_Free(mo_head);
mbuf_FreeSeg(mi_head);
log_Printf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n",
- ilen, olen, proto);
+ ilen, olen, *proto);
ccp->uncompout += ilen;
ccp->compout += ilen; /* We measure this stuff too */
- return 0;
+ return mp;
}
mbuf_Free(mi_head);
@@ -179,10 +180,10 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
ccp->compout += olen;
log_Printf(LogDEBUG, "DeflateOutput: %d => %d bytes, proto 0x%04x\n",
- ilen, olen, proto);
+ ilen, olen, *proto);
- hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mo_head);
- return 1;
+ *proto = ccp_Proto(ccp);
+ return mo_head;
}
static void
diff --git a/usr.sbin/ppp/defs.c b/usr.sbin/ppp/defs.c
index 07a664d..0081ee4 100644
--- a/usr.sbin/ppp/defs.c
+++ b/usr.sbin/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.18 1999/02/25 20:05:55 brian Exp $
+ * $Id: defs.c,v 1.19 1999/04/26 08:54:24 brian Exp $
*/
@@ -37,6 +37,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#if !defined(__FreeBSD__) || __FreeBSD__ < 3
#include <time.h>
#endif
@@ -44,6 +45,8 @@
#include "defs.h"
+#define issep(c) ((c) == '\t' || (c) == ' ')
+
void
randinit()
{
@@ -151,3 +154,166 @@ GetIpAddr(const char *cp)
return ipaddr;
}
+
+static const struct speeds {
+ int nspeed;
+ speed_t speed;
+} speeds[] = {
+#ifdef B50
+ { 50, B50, },
+#endif
+#ifdef B75
+ { 75, B75, },
+#endif
+#ifdef B110
+ { 110, B110, },
+#endif
+#ifdef B134
+ { 134, B134, },
+#endif
+#ifdef B150
+ { 150, B150, },
+#endif
+#ifdef B200
+ { 200, B200, },
+#endif
+#ifdef B300
+ { 300, B300, },
+#endif
+#ifdef B600
+ { 600, B600, },
+#endif
+#ifdef B1200
+ { 1200, B1200, },
+#endif
+#ifdef B1800
+ { 1800, B1800, },
+#endif
+#ifdef B2400
+ { 2400, B2400, },
+#endif
+#ifdef B4800
+ { 4800, B4800, },
+#endif
+#ifdef B9600
+ { 9600, B9600, },
+#endif
+#ifdef B19200
+ { 19200, B19200, },
+#endif
+#ifdef B38400
+ { 38400, B38400, },
+#endif
+#ifndef _POSIX_SOURCE
+#ifdef B7200
+ { 7200, B7200, },
+#endif
+#ifdef B14400
+ { 14400, B14400, },
+#endif
+#ifdef B28800
+ { 28800, B28800, },
+#endif
+#ifdef B57600
+ { 57600, B57600, },
+#endif
+#ifdef B76800
+ { 76800, B76800, },
+#endif
+#ifdef B115200
+ { 115200, B115200, },
+#endif
+#ifdef B230400
+ { 230400, B230400, },
+#endif
+#ifdef EXTA
+ { 19200, EXTA, },
+#endif
+#ifdef EXTB
+ { 38400, EXTB, },
+#endif
+#endif /* _POSIX_SOURCE */
+ { 0, 0 }
+};
+
+int
+SpeedToInt(speed_t speed)
+{
+ const struct speeds *sp;
+
+ for (sp = speeds; sp->nspeed; sp++) {
+ if (sp->speed == speed) {
+ return sp->nspeed;
+ }
+ }
+ return 0;
+}
+
+speed_t
+IntToSpeed(int nspeed)
+{
+ const struct speeds *sp;
+
+ for (sp = speeds; sp->nspeed; sp++) {
+ if (sp->nspeed == nspeed) {
+ return sp->speed;
+ }
+ }
+ return B0;
+}
+
+static char *
+findblank(char *p, int instring)
+{
+ if (instring) {
+ while (*p) {
+ if (*p == '\\') {
+ memmove(p, p + 1, strlen(p + 1));
+ if (!*p)
+ break;
+ } else if (*p == '"')
+ return (p);
+ p++;
+ }
+ } else {
+ while (*p) {
+ if (issep(*p))
+ return (p);
+ p++;
+ }
+ }
+
+ return p;
+}
+
+int
+MakeArgs(char *script, char **pvect, int maxargs)
+{
+ int nargs, nb;
+ int instring;
+
+ nargs = 0;
+ while (*script) {
+ nb = strspn(script, " \t");
+ script += nb;
+ 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++ = '\0';
+ }
+ }
+ *pvect = NULL;
+ return nargs;
+}
diff --git a/usr.sbin/ppp/defs.h b/usr.sbin/ppp/defs.h
index c47a46a..4b9163a 100644
--- a/usr.sbin/ppp/defs.h
+++ b/usr.sbin/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.41 1999/02/26 21:28:10 brian Exp $
+ * $Id: defs.h,v 1.42 1999/04/27 00:23:54 brian Exp $
*
* TODO:
*/
@@ -96,3 +96,6 @@ extern ssize_t fullread(int, void *, size_t);
extern const char *mode2Nam(int);
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);
diff --git a/usr.sbin/ppp/exec.c b/usr.sbin/ppp/exec.c
new file mode 100644
index 0000000..da6ad96
--- /dev/null
+++ b/usr.sbin/ppp/exec.c
@@ -0,0 +1,160 @@
+/*-
+ * 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:$
+ */
+
+#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>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "layer.h"
+#include "defs.h"
+#include "mbuf.h"
+#include "log.h"
+#include "sync.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 "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 "exec.h"
+
+static int
+exec_Open(struct physical *p)
+{
+ if (*p->name.full == '!') {
+ int fids[2];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0)
+ log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
+ strerror(errno));
+ else {
+ int stat, argc;
+ pid_t pid;
+ char *argv[MAXARGS];
+
+ stat = fcntl(fids[0], F_GETFL, 0);
+ if (stat > 0) {
+ stat |= O_NONBLOCK;
+ fcntl(fids[0], F_SETFL, stat);
+ }
+ switch ((pid = fork())) {
+ case -1:
+ log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
+ strerror(errno));
+ break;
+
+ case 0:
+ close(fids[0]);
+ timer_TermService();
+ setuid(geteuid());
+
+ switch (fork()) {
+ case 0:
+ break;
+
+ case -1:
+ log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n",
+ strerror(errno));
+ default:
+ _exit(127);
+ }
+
+ fids[1] = fcntl(fids[1], F_DUPFD, 3);
+ dup2(fids[1], STDIN_FILENO);
+ dup2(fids[1], STDOUT_FILENO);
+ dup2(fids[1], STDERR_FILENO);
+
+ argc = MakeArgs(p->name.base, argv, VECSIZE(argv));
+ command_Expand(argv, argc, (char const *const *)argv,
+ p->dl->bundle, 0);
+ execvp(*argv, argv);
+ fprintf(stderr, "execvp failed: %s: %s\r\n", *argv, strerror(errno));
+ _exit(127);
+ break;
+
+ default:
+ close(fids[1]);
+ p->fd = fids[0];
+ waitpid(pid, &stat, 0);
+ log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd);
+ physical_SetupStack(p, 1);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+const struct device execdevice = {
+ EXEC_DEVICE,
+ "exec",
+ exec_Open,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/usr.sbin/ppp/exec.h b/usr.sbin/ppp/exec.h
new file mode 100644
index 0000000..34630a2
--- /dev/null
+++ b/usr.sbin/ppp/exec.h
@@ -0,0 +1,29 @@
+/*-
+ * 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:$
+ */
+
+extern const struct device execdevice;
diff --git a/usr.sbin/ppp/filter.c b/usr.sbin/ppp/filter.c
index c9972fd..f9c7def 100644
--- a/usr.sbin/ppp/filter.c
+++ b/usr.sbin/ppp/filter.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: filter.c,v 1.26 1998/10/22 02:32:48 brian Exp $
+ * $Id: filter.c,v 1.27 1999/01/28 01:56:31 brian Exp $
*
* TODO: Shoud send ICMP error message when we discard packets.
*/
@@ -35,6 +35,7 @@
#include <strings.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
diff --git a/usr.sbin/ppp/fsm.c b/usr.sbin/ppp/fsm.c
index db4be6d..bbc5bc5 100644
--- a/usr.sbin/ppp/fsm.c
+++ b/usr.sbin/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.40 1999/03/01 02:52:39 brian Exp $
+ * $Id: fsm.c,v 1.41 1999/03/29 08:21:26 brian Exp $
*
* TODO:
*/
@@ -31,6 +31,7 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "ua.h"
#include "mbuf.h"
#include "log.h"
@@ -55,7 +56,7 @@
#include "bundle.h"
#include "async.h"
#include "physical.h"
-#include "lcpproto.h"
+#include "proto.h"
static void FsmSendConfigReq(struct fsm *);
static void FsmSendTerminateReq(struct fsm *);
@@ -87,7 +88,7 @@ static const struct fsmcodedesc {
{ FsmRecvDiscReq, 0, 0, "DiscardReq" },
{ FsmRecvIdent, 0, 0, "Ident" },
{ FsmRecvTimeRemain,0, 0, "TimeRemain" },
- { FsmRecvResetReq, 0, 0, "ResetReqt" },
+ { FsmRecvResetReq, 0, 0, "ResetReq" },
{ FsmRecvResetAck, 0, 1, "ResetAck" }
};
@@ -140,7 +141,7 @@ fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode,
fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL;
fp->reqid = 1;
fp->restart = 1;
- fp->more.reqs = fp->more.naks = fp->more.rejs = 1;
+ fp->more.reqs = fp->more.naks = fp->more.rejs = 3;
memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer);
memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer);
memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer);
@@ -204,7 +205,7 @@ fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, int count)
if (count)
memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count);
log_DumpBp(LogDEBUG, "fsm_Output", bp);
- hdlc_Output(fp->link, PRI_LINK, fp->proto, bp);
+ link_PushPacket(fp->link, bp, fp->bundle, PRI_LINK, fp->proto);
}
static void
@@ -468,13 +469,13 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) {
/*
* ccp_SetOpenMode() leaves us in initial if we're disabling
- * & denying everything. This is a bit smelly, we know that
- * ``bp'' really has ``fsmheader'' in front of it, and CCP_PROTO
- * in front of that. CCP_PROTO isn't compressed either 'cos it
- * doesn't begin with 0x00....
+ * & denying everything.
+ *
+ * this is a bit smelly... we know that bp has a leading fsmheader.
*/
- bp->offset -= sizeof(struct fsmheader) + 2;
- bp->cnt += sizeof(struct fsmheader) + 2;
+ bp = mbuf_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);
return;
@@ -501,6 +502,8 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
break;
}
+ bp = mbuf_Contiguous(bp);
+
dec.ackend = dec.ack;
dec.nakend = dec.nak;
dec.rejend = dec.rej;
@@ -576,7 +579,6 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
}
if (dec.nakend != dec.nak && --fp->more.naks <= 0) {
- fsm_Close(fp);
log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n",
fp->link->name, fp->name);
fsm_Close(fp);
@@ -961,7 +963,7 @@ void
fsm_Input(struct fsm *fp, struct mbuf *bp)
{
int len;
- struct fsmheader *lhp;
+ struct fsmheader lh;
const struct fsmcodedesc *codep;
len = mbuf_Length(bp);
@@ -969,41 +971,41 @@ fsm_Input(struct fsm *fp, struct mbuf *bp)
mbuf_Free(bp);
return;
}
- lhp = (struct fsmheader *) MBUF_CTOP(bp);
- if (lhp->code < fp->min_code || lhp->code > fp->max_code ||
- lhp->code > sizeof FsmCodes / sizeof *FsmCodes) {
+ bp = mbuf_Read(bp, &lh, sizeof lh);
+ if (lh.code < fp->min_code || lh.code > fp->max_code ||
+ lh.code > sizeof FsmCodes / sizeof *FsmCodes) {
/*
* Use a private id. This is really a response-type packet, but we
* MUST send a unique id for each REQ....
*/
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);
mbuf_Free(bp);
return;
}
- bp->offset += sizeof(struct fsmheader);
- bp->cnt -= sizeof(struct fsmheader);
- codep = FsmCodes + lhp->code - 1;
- if (lhp->id != fp->reqid && codep->check_reqid &&
+ codep = FsmCodes + lh.code - 1;
+ if (lh.id != fp->reqid && codep->check_reqid &&
Enabled(fp->bundle, OPT_IDCHECK)) {
log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n",
- fp->link->name, codep->name, lhp->id, fp->reqid);
+ fp->link->name, codep->name, lh.id, fp->reqid);
return;
}
log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n",
- fp->link->name, codep->name, lhp->id, State2Nam(fp->state));
+ fp->link->name, codep->name, lh.id, State2Nam(fp->state));
if (log_IsKept(LogDEBUG))
mbuf_Log();
- if (codep->inc_reqid && (lhp->id == fp->reqid ||
+ if (codep->inc_reqid && (lh.id == fp->reqid ||
(!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid)))
fp->reqid++; /* That's the end of that ``exchange''.... */
- (*codep->recv)(fp, lhp, bp);
+ (*codep->recv)(fp, &lh, bp);
if (log_IsKept(LogDEBUG))
mbuf_Log();
diff --git a/usr.sbin/ppp/hdlc.c b/usr.sbin/ppp/hdlc.c
index 2176b5f..a2042ff 100644
--- a/usr.sbin/ppp/hdlc.c
+++ b/usr.sbin/ppp/hdlc.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: hdlc.c,v 1.40 1999/03/29 08:21:26 brian Exp $
+ * $Id: hdlc.c,v 1.41 1999/04/03 11:54:00 brian Exp $
*
* TODO:
*/
@@ -32,6 +32,7 @@
#include <termios.h>
#include "defs.h"
+#include "layer.h"
#include "command.h"
#include "mbuf.h"
#include "log.h"
@@ -39,7 +40,7 @@
#include "fsm.h"
#include "lqr.h"
#include "hdlc.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "iplist.h"
#include "throughput.h"
#include "slcompress.h"
@@ -112,12 +113,15 @@ hdlc_Init(struct hdlc *hdlc, struct lcp *lcp)
* HDLC FCS computation. Read RFC 1171 Appendix B and CCITT X.25 section
* 2.27 for further details.
*/
-inline u_short
-hdlc_Fcs(u_short fcs, u_char * cp, int len)
+u_short
+hdlc_Fcs(u_char *cp, size_t len)
{
+ u_short fcs = INITFCS;
+
while (len--)
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
- return (fcs);
+
+ return fcs;
}
static inline u_short
@@ -140,107 +144,41 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m)
return (fcs);
}
-void
-hdlc_Output(struct link *l, int pri, u_short proto, struct mbuf *bp)
+int
+hdlc_WrapperOctets(struct lcp *lcp, u_short proto)
{
- struct physical *p = link2physical(l);
- struct mbuf *mhp, *mfcs;
+ return 2;
+}
+
+static struct mbuf *
+hdlc_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ struct mbuf *last;
u_char *cp;
u_short fcs;
- if (!p || physical_IsSync(p))
- mfcs = NULL;
- else
- mfcs = mbuf_Alloc(2, MB_HDLCOUT);
-
- mhp = mbuf_Alloc(4, MB_HDLCOUT);
- mhp->cnt = 0;
- cp = MBUF_CTOP(mhp);
- if (p && (proto == PROTO_LCP || l->lcp.his_acfcomp == 0)) {
- *cp++ = HDLC_ADDR;
- *cp++ = HDLC_UI;
- mhp->cnt += 2;
- }
-
- /*
- * If possible, compress protocol field.
- */
- if (l->lcp.his_protocomp && (proto & 0xff00) == 0) {
- *cp++ = proto;
- mhp->cnt++;
- } else {
- *cp++ = proto >> 8;
- *cp = proto & 0377;
- mhp->cnt += 2;
- }
+ fcs = HdlcFcsBuf(INITFCS, bp);
+ fcs = ~fcs;
- mhp->next = bp = mbuf_Contiguous(bp);
+ for (last = bp; last->next; last = last->next)
+ ;
- if (!p) {
- /*
- * This is where we multiplex the data over our available physical
- * links. We don't frame our logical link data. Instead we wait
- * for the logical link implementation to chop our data up and pile
- * it into the physical links by re-calling this function with the
- * encapsulated fragments.
- */
- link_Output(l, pri, mhp);
- return;
- }
-
- bp->next = mfcs; /* Tack mfcs onto the end */
-
- p->hdlc.lqm.OutOctets += mbuf_Length(mhp) + 1;
- p->hdlc.lqm.OutPackets++;
-
- if (proto == PROTO_LQR) {
- /* Overwrite the entire packet */
- struct lqrdata lqr;
-
- lqr.MagicNumber = p->link.lcp.want_magic;
- lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
- lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
- lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
- lqr.PeerInLQRs = p->hdlc.lqm.lqr.SaveInLQRs;
- lqr.PeerInPackets = p->hdlc.lqm.SaveInPackets;
- lqr.PeerInDiscards = p->hdlc.lqm.SaveInDiscards;
- lqr.PeerInErrors = p->hdlc.lqm.SaveInErrors;
- lqr.PeerInOctets = p->hdlc.lqm.SaveInOctets;
- lqr.PeerOutPackets = p->hdlc.lqm.OutPackets;
- lqr.PeerOutOctets = p->hdlc.lqm.OutOctets;
- if (p->hdlc.lqm.lqr.peer.LastOutLQRs == p->hdlc.lqm.lqr.OutLQRs) {
- /*
- * only increment if it's the first time or we've got a reply
- * from the last one
- */
- lqr.PeerOutLQRs = ++p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output", &lqr);
- } else {
- lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output (again)", &lqr);
- }
- lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
- }
-
- if (mfcs) {
- mfcs->cnt = 0;
- fcs = HdlcFcsBuf(INITFCS, mhp);
- fcs = ~fcs;
- cp = MBUF_CTOP(mfcs);
- *cp++ = fcs & 0377; /* Low byte first!! */
- *cp++ = fcs >> 8;
- mfcs->cnt = 2;
+ if (last->size - last->offset - last->cnt >= 2) {
+ cp = MBUF_CTOP(last) + last->cnt;
+ last->cnt += 2;
+ } else {
+ struct mbuf *tail = mbuf_Alloc(2, MB_HDLCOUT);
+ last->next = tail;
+ cp = MBUF_CTOP(tail);
}
- log_DumpBp(LogHDLC, "hdlc_Output", mhp);
+ *cp++ = fcs & 0377; /* Low byte first (nothing like consistency) */
+ *cp++ = fcs >> 8;
- link_ProtocolRecord(l, proto, PROTO_OUT);
- log_Printf(LogDEBUG, "hdlc_Output: proto = 0x%04x\n", proto);
+ log_DumpBp(LogHDLC, "hdlc_Output", bp);
- if (physical_IsSync(p))
- link_Output(l, pri, mhp); /* Send it raw */
- else
- async_Output(pri, mhp, proto, p);
+ return bp;
}
/* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
@@ -369,192 +307,45 @@ hdlc_Protocol2Nam(u_short proto)
return "unrecognised protocol";
}
-void
-hdlc_DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp,
- struct link *l)
+static struct mbuf *
+hdlc_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
+ u_short *proto)
{
struct physical *p = link2physical(l);
- u_char *cp;
- const char *type;
-
- log_Printf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto);
-
- /* decompress everything. CCP needs uncompressed data too */
- if ((bp = ccp_Decompress(&l->ccp, &proto, bp)) == NULL)
- return;
-
- switch (proto) {
- case PROTO_LCP:
- lcp_Input(&l->lcp, bp);
- break;
- case PROTO_PAP:
- if (p)
- pap_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: PAP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_CBCP:
- if (p)
- cbcp_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: CBCP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_LQR:
- if (p) {
- p->hdlc.lqm.lqr.SaveInLQRs++;
- lqr_Input(p, bp);
- } else {
- log_Printf(LogERROR, "DecodePacket: LQR: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_CHAP:
- if (p)
- chap_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: CHAP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_VJUNCOMP:
- case PROTO_VJCOMP:
- bp = vj_Input(&bundle->ncp.ipcp, bp, proto);
- if (bp == NULL)
- break;
- /* fall down */
- case PROTO_IP:
- ip_Input(bundle, bp);
- break;
- case PROTO_IPCP:
- ipcp_Input(&bundle->ncp.ipcp, bundle, bp);
- break;
- case PROTO_CCP:
- ccp_Input(&l->ccp, bundle, bp);
- break;
- case PROTO_MP:
- if (bundle->ncp.mp.active) {
- if (p)
- mp_Input(&bundle->ncp.mp, bp, p);
- else {
- log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
- mbuf_Free(bp);
- }
- break;
- }
- /* Fall through */
- default:
- switch (proto) {
- case PROTO_MP:
- case PROTO_COMPD:
- case PROTO_ICOMPD:
- type = "Unexpected";
- break;
- default:
- type = "Unknown";
- break;
- }
- log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n", type, proto,
- hdlc_Protocol2Nam(proto));
- bp->offset -= 2;
- bp->cnt += 2;
- cp = MBUF_CTOP(bp);
- lcp_SendProtoRej(&l->lcp, cp, bp->cnt);
- if (p) {
- p->hdlc.lqm.SaveInDiscards++;
- p->hdlc.stats.unknownproto++;
- }
- mbuf_Free(bp);
- break;
- }
-}
+ u_short fcs;
+ int len;
-static int
-hdlc_GetProto(const u_char *cp, u_short *proto)
-{
- *proto = *cp;
- if (!(*proto & 1)) {
- *proto = (*proto << 8) | cp[1];
- return 2;
+ if (!p) {
+ log_Printf(LogERROR, "Can't Pull a hdlc packet from a logical link\n");
+ return bp;
}
- return 1;
-}
-
-void
-hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical)
-{
- u_short fcs, proto;
- u_char *cp, addr, ctrl;
- int n;
log_DumpBp(LogHDLC, "hdlc_Input:", bp);
- if (physical_IsSync(physical))
- fcs = GOODFCS;
- else
- fcs = hdlc_Fcs(INITFCS, MBUF_CTOP(bp), bp->cnt);
- physical->hdlc.lqm.SaveInOctets += bp->cnt + 1;
+
+ fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->cnt);
log_Printf(LogDEBUG, "%s: hdlc_Input: fcs = %04x (%s)\n",
- physical->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
+ p->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
+
if (fcs != GOODFCS) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badfcs++;
+ p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.stats.badfcs++;
mbuf_Free(bp);
- return;
+ return NULL;
}
- if (!physical_IsSync(physical))
- bp->cnt -= 2; /* discard FCS part */
- if (bp->cnt < 2) { /* XXX: raise this bar ? */
+ p->hdlc.lqm.SaveInOctets += bp->cnt + 1;
+ p->hdlc.lqm.SaveInPackets++;
+
+ len = mbuf_Length(bp);
+ if (len < 4) { /* rfc1662 section 4.3 */
mbuf_Free(bp);
- return;
- }
- cp = MBUF_CTOP(bp);
-
- if (!physical->link.lcp.want_acfcomp) {
- /* We expect the packet not to be compressed */
- addr = *cp++;
- if (addr != HDLC_ADDR) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badaddr++;
- log_Printf(LogDEBUG, "hdlc_Input: addr %02x\n", *cp);
- mbuf_Free(bp);
- return;
- }
- ctrl = *cp++;
- if (ctrl != HDLC_UI) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badcommand++;
- log_Printf(LogDEBUG, "hdlc_Input: %02x\n", *cp);
- mbuf_Free(bp);
- return;
- }
- bp->offset += 2;
- bp->cnt -= 2;
- } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
- /*
- * We can receive compressed packets, but the peer still sends
- * uncompressed packets !
- */
- cp += 2;
- bp->offset += 2;
- bp->cnt -= 2;
+ bp = NULL;
}
- n = hdlc_GetProto(cp, &proto);
- bp->offset += n;
- bp->cnt -= n;
- if (!physical->link.lcp.want_protocomp && n == 1)
- log_Printf(LogHDLC, "%s: Warning: received a proto-compressed packet !\n",
- physical->link.name);
-
- link_ProtocolRecord(&physical->link, proto, PROTO_IN);
- physical->hdlc.lqm.SaveInPackets++;
+ bp = mbuf_Truncate(bp, len - 2); /* discard the FCS */
- hdlc_DecodePacket(bundle, proto, bp, &physical->link);
+ return bp;
}
/*
@@ -650,3 +441,5 @@ hdlc_StopTimer(struct hdlc *hdlc)
{
timer_Stop(&hdlc->ReportTimer);
}
+
+struct layer hdlclayer = { LAYER_HDLC, "hdlc", hdlc_LayerPush, hdlc_LayerPull };
diff --git a/usr.sbin/ppp/hdlc.h b/usr.sbin/ppp/hdlc.h
index 39d4388..2602921 100644
--- a/usr.sbin/ppp/hdlc.h
+++ b/usr.sbin/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.15 1998/05/21 21:45:30 brian Exp $
+ * $Id: hdlc.h,v 1.16 1999/04/03 11:54:00 brian Exp $
*
* TODO:
*/
@@ -109,7 +109,8 @@ extern const char *hdlc_Protocol2Nam(u_short);
extern void hdlc_DecodePacket(struct bundle *, u_short, struct mbuf *,
struct link *);
-extern void hdlc_Input(struct bundle *, struct mbuf *, struct physical *);
-extern void hdlc_Output(struct link *, int, u_short, struct mbuf *bp);
-extern u_short hdlc_Fcs(u_short, u_char *, int);
+extern u_short hdlc_Fcs(u_char *, size_t);
extern int hdlc_Detect(u_char const **, int, int);
+extern int hdlc_WrapperOctets(struct lcp *, u_short);
+
+extern struct layer hdlclayer;
diff --git a/usr.sbin/ppp/iface.c b/usr.sbin/ppp/iface.c
index e13c1f8..5977845 100644
--- a/usr.sbin/ppp/iface.c
+++ b/usr.sbin/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.3 1999/01/28 01:56:32 brian Exp $
+ * $Id: iface.c,v 1.4 1999/04/26 08:54:24 brian Exp $
*/
#include <sys/param.h>
@@ -46,6 +46,7 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c
index 89af1fc..e791ad7 100644
--- a/usr.sbin/ppp/ip.c
+++ b/usr.sbin/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.57 1999/04/26 08:54:34 brian Exp $
+ * $Id: ip.c,v 1.58 1999/05/01 11:31:29 brian Exp $
*
* TODO:
* o Return ICMP message for filterd packet
@@ -40,15 +40,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
-#ifndef NOALIAS
-#ifdef __FreeBSD__
-#include <alias.h>
-#else
-#include "alias.h"
-#endif
-#endif
+#include "layer.h"
+#include "proto.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
@@ -99,7 +95,7 @@ PortMatch(int op, u_short pport, u_short rport)
}
/*
- * Check a packet against with defined filters
+ * Check a packet against a defined filter
*/
static int
FilterCheck(struct ip *pip, struct filter *filter)
@@ -384,124 +380,42 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
}
}
-void
-ip_Input(struct bundle *bundle, struct mbuf * bp)
+struct mbuf *
+ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
- u_char *cp;
- struct mbuf *wp;
int nb, nw;
struct tun_data tun;
- struct ip *pip = (struct ip *)tun.data;
-#ifndef NOALIAS
- struct ip *piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
-#endif
+ struct ip *pip;
- tun_fill_header(tun, AF_INET);
- cp = tun.data;
- nb = 0;
- for (wp = bp; wp; wp = wp->next) { /* Copy to contiguous region */
- if (sizeof tun.data - (cp - tun.data) < wp->cnt) {
- log_Printf(LogWARN, "ip_Input: Packet too large (%d) - dropped\n",
- mbuf_Length(bp));
- mbuf_Free(bp);
- return;
- }
- memcpy(cp, MBUF_CTOP(wp), wp->cnt);
- cp += wp->cnt;
- nb += wp->cnt;
+ if (bundle->ncp.ipcp.fsm.state != ST_OPENED) {
+ log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n");
+ mbuf_Free(bp);
+ return NULL;
}
-#ifndef NOALIAS
- if (bundle->AliasEnabled && pip->ip_p != IPPROTO_IGMP &&
- (pip->ip_p != IPPROTO_IPIP || !IN_CLASSD(ntohl(piip->ip_dst.s_addr)))) {
- struct tun_data *frag;
- int iresult;
- char *fptr;
-
- iresult = PacketAliasIn(tun.data, sizeof tun.data);
- nb = ntohs(((struct ip *) tun.data)->ip_len);
-
- if (nb > MAX_MRU) {
- log_Printf(LogWARN, "ip_Input: Problem with IP header length\n");
- mbuf_Free(bp);
- return;
- }
- if (iresult == PKT_ALIAS_OK
- || iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
- if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
- mbuf_Free(bp);
- return;
- }
-
- if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
- bundle_StartIdleTimer(bundle);
-
- ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
-
- nb = ntohs(((struct ip *) tun.data)->ip_len);
- nb += sizeof tun - sizeof tun.data;
- nw = write(bundle->dev.fd, &tun, nb);
- if (nw != nb) {
- if (nw == -1)
- log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
- strerror(errno));
- else
- log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
- }
+ tun_fill_header(tun, AF_INET);
+ nb = mbuf_Length(bp);
+ mbuf_Read(bp, tun.data, nb);
- if (iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
- while ((fptr = PacketAliasGetFragment(tun.data)) != NULL) {
- PacketAliasFragmentIn(tun.data, fptr);
- nb = ntohs(((struct ip *) fptr)->ip_len);
- frag = (struct tun_data *)
- ((char *)fptr - sizeof tun + sizeof tun.data);
- nb += sizeof tun - sizeof tun.data;
- nw = write(bundle->dev.fd, frag, nb);
- if (nw != nb) {
- if (nw == -1)
- log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
- strerror(errno));
- else
- log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
- }
- free(frag);
- }
- }
- } else if (iresult == PKT_ALIAS_UNRESOLVED_FRAGMENT) {
- nb = ntohs(((struct ip *) tun.data)->ip_len);
- nb += sizeof tun - sizeof tun.data;
- frag = (struct tun_data *)malloc(nb);
- if (frag == NULL)
- log_Printf(LogALERT, "ip_Input: Cannot allocate memory for fragment\n");
- else {
- tun_fill_header(*frag, AF_INET);
- memcpy(frag->data, tun.data, nb - sizeof tun + sizeof tun.data);
- PacketAliasSaveFragment(frag->data);
- }
- }
- } else
-#endif /* #ifndef NOALIAS */
- { /* no aliasing */
- if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
- mbuf_Free(bp);
- return;
- }
+ if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0)
+ return NULL;
- if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
- bundle_StartIdleTimer(bundle);
+ pip = (struct ip *)tun.data;
+ if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
+ bundle_StartIdleTimer(bundle);
- ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
+ ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
- nb += sizeof tun - sizeof tun.data;
- nw = write(bundle->dev.fd, &tun, nb);
- if (nw != nb) {
- if (nw == -1)
- log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
- else
- log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
- }
+ nb += sizeof tun - sizeof tun.data;
+ nw = write(bundle->dev.fd, &tun, nb);
+ if (nw != nb) {
+ if (nw == -1)
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
+ else
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
}
- mbuf_Free(bp);
+
+ return NULL;
}
void
@@ -512,7 +426,15 @@ ip_Enqueue(struct ipcp *ipcp, int pri, char *ptr, int count)
if (pri < 0 || pri > sizeof ipcp->Queue / sizeof ipcp->Queue[0])
log_Printf(LogERROR, "Can't store in ip queue %d\n", pri);
else {
- bp = mbuf_Alloc(count, MB_IPQ);
+ /*
+ * 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
+ * appending in hdlc_LayerPush().
+ */
+ bp = mbuf_Alloc(count + 6, MB_IPQ);
+ bp->offset += 4;
+ bp->cnt -= 6;
memcpy(MBUF_CTOP(bp), ptr, count);
mbuf_Enqueue(&ipcp->Queue[pri], bp);
}
@@ -541,11 +463,12 @@ ip_QueueLen(struct ipcp *ipcp)
}
int
-ip_FlushPacket(struct link *l, struct bundle *bundle)
+ip_PushPacket(struct link *l, struct bundle *bundle)
{
struct ipcp *ipcp = &bundle->ncp.ipcp;
struct mqueue *queue;
struct mbuf *bp;
+ struct ip *pip;
int cnt;
if (ipcp->fsm.state != ST_OPENED)
@@ -554,16 +477,13 @@ ip_FlushPacket(struct link *l, struct bundle *bundle)
for (queue = &ipcp->Queue[PRI_FAST]; queue >= ipcp->Queue; queue--)
if (queue->top) {
bp = mbuf_Contiguous(mbuf_Dequeue(queue));
- if (bp) {
- struct ip *pip = (struct ip *)MBUF_CTOP(bp);
-
- cnt = mbuf_Length(bp);
- if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
- bundle_StartIdleTimer(bundle);
- vj_SendFrame(l, bp, bundle);
- ipcp_AddOutOctets(ipcp, cnt);
- return 1;
- }
+ cnt = mbuf_Length(bp);
+ pip = (struct ip *)MBUF_CTOP(bp);
+ if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
+ bundle_StartIdleTimer(bundle);
+ link_PushPacket(l, bp, bundle, PRI_NORMAL, PROTO_IP);
+ ipcp_AddOutOctets(ipcp, cnt);
+ return 1;
}
return 0;
diff --git a/usr.sbin/ppp/ip.h b/usr.sbin/ppp/ip.h
index 20ce67d..a22e42a 100644
--- a/usr.sbin/ppp/ip.h
+++ b/usr.sbin/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.10 1998/08/25 17:48:42 brian Exp $
+ * $Id: ip.h,v 1.11 1998/08/26 17:39:37 brian Exp $
*
*/
@@ -26,9 +26,9 @@ struct filter;
struct link;
struct bundle;
-extern int ip_FlushPacket(struct link *, struct bundle *);
+extern int ip_PushPacket(struct link *, struct bundle *);
extern int PacketCheck(struct bundle *, char *, int, struct filter *);
extern void ip_Enqueue(struct ipcp *, int, char *, int);
-extern void ip_Input(struct bundle *, struct mbuf *);
+extern struct mbuf *ip_Input(struct bundle *, struct link *, struct mbuf *);
extern void ip_DeleteQueue(struct ipcp *);
extern int ip_QueueLen(struct ipcp *);
diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c
index aa981ef..c36ef66 100644
--- a/usr.sbin/ppp/ipcp.c
+++ b/usr.sbin/ppp/ipcp.c
@@ -17,10 +17,11 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ipcp.c,v 1.74 1999/04/26 08:54:24 brian Exp $
+ * $Id: ipcp.c,v 1.75 1999/04/26 08:54:34 brian Exp $
*
* TODO:
- * o More RFC1772 backward compatibility
+ * o Support IPADDRS properly
+ * o Validate the length in IpcpDecodeConfig
*/
#include <sys/param.h>
#include <netinet/in_systm.h>
@@ -47,6 +48,7 @@
#include "alias.h"
#endif
#endif
+#include "layer.h"
#include "ua.h"
#include "defs.h"
#include "command.h"
@@ -54,7 +56,7 @@
#include "log.h"
#include "timer.h"
#include "fsm.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "lcp.h"
#include "iplist.h"
#include "throughput.h"
@@ -1007,22 +1009,12 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
switch (mode_type) {
case MODE_REQ:
- ipcp->peer_ip = ipaddr;
- ipcp->my_ip = dstipaddr;
- memcpy(dec->ackend, cp, length);
- dec->ackend += length;
+ memcpy(dec->rejend, cp, length);
+ dec->rejend += length;
break;
case MODE_NAK:
- snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff,
- inet_ntoa(ipcp->my_ip));
- log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
- ipcp->my_ip = ipaddr;
- ipcp->peer_ip = dstipaddr;
- break;
-
case MODE_REJ:
- ipcp->peer_reject |= (1 << type);
break;
}
break;
@@ -1147,18 +1139,19 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
}
}
-void
-ipcp_Input(struct ipcp *ipcp, struct bundle *bundle, struct mbuf *bp)
+extern struct mbuf *
+ipcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
/* Got PROTO_IPCP from link */
if (bundle_Phase(bundle) == PHASE_NETWORK)
- fsm_Input(&ipcp->fsm, bp);
+ 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",
- ipcp->fsm.link->name, bundle_PhaseName(bundle));
+ l->name, bundle_PhaseName(bundle));
mbuf_Free(bp);
}
+ return NULL;
}
int
diff --git a/usr.sbin/ppp/ipcp.h b/usr.sbin/ppp/ipcp.h
index b25c41d..562f14b 100644
--- a/usr.sbin/ppp/ipcp.h
+++ b/usr.sbin/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.24 1999/02/26 21:28:12 brian Exp $
+ * $Id: ipcp.h,v 1.25 1999/03/03 23:00:40 brian Exp $
*
* TODO:
*/
@@ -108,7 +108,7 @@ extern void ipcp_Setup(struct ipcp *, u_int32_t);
extern void ipcp_SetLink(struct ipcp *, struct link *);
extern int ipcp_Show(struct cmdargs const *);
-extern void ipcp_Input(struct ipcp *, struct bundle *, struct mbuf *);
+extern struct mbuf *ipcp_Input(struct bundle *, struct link *, struct mbuf *);
extern void ipcp_AddInOctets(struct ipcp *, int);
extern void ipcp_AddOutOctets(struct ipcp *, int);
extern int ipcp_UseHisIPaddr(struct bundle *, struct in_addr);
diff --git a/usr.sbin/ppp/iplist.c b/usr.sbin/ppp/iplist.c
index 2eddeeb..76606e7 100644
--- a/usr.sbin/ppp/iplist.c
+++ b/usr.sbin/ppp/iplist.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: iplist.c,v 1.6 1998/06/15 19:06:47 brian Exp $
+ * $Id: iplist.c,v 1.7 1998/06/27 23:48:47 brian Exp $
*/
#include <sys/types.h>
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include "log.h"
#include "defs.h"
diff --git a/usr.sbin/ppp/layer.h b/usr.sbin/ppp/layer.h
new file mode 100644
index 0000000..67dde31
--- /dev/null
+++ b/usr.sbin/ppp/layer.h
@@ -0,0 +1,52 @@
+/*-
+ * 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:$
+ */
+
+#define LAYER_ASYNC 2
+#define LAYER_SYNC 3
+#define LAYER_HDLC 4
+#define LAYER_ACF 5
+#define LAYER_PROTO 6
+#define LAYER_LQR 7
+#define LAYER_CCP 8
+#define LAYER_VJ 9
+#define LAYER_ALIAS 10
+
+#define LAYER_MAX 10 /* How many layers we can handle on a link */
+
+struct mbuf;
+struct link;
+struct bundle;
+
+struct layer {
+ int type;
+ const char *name;
+ struct mbuf *(*push)(struct bundle *, struct link *, struct mbuf *,
+ int pri, u_short *proto);
+ struct mbuf *(*pull)(struct bundle *, struct link *, struct mbuf *,
+ u_short *);
+};
diff --git a/usr.sbin/ppp/lcp.c b/usr.sbin/ppp/lcp.c
index 5524082..0e45418 100644
--- a/usr.sbin/ppp/lcp.c
+++ b/usr.sbin/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.69 1999/02/26 21:28:12 brian Exp $
+ * $Id: lcp.c,v 1.72 1999/04/11 08:51:04 brian Exp $
*
*/
@@ -34,6 +34,7 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "ua.h"
#include "defs.h"
#include "command.h"
@@ -44,7 +45,7 @@
#include "iplist.h"
#include "lcp.h"
#include "throughput.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "descriptor.h"
#include "lqr.h"
#include "hdlc.h"
@@ -1147,9 +1148,10 @@ reqreject:
}
}
-void
-lcp_Input(struct lcp *lcp, struct mbuf *bp)
+extern struct mbuf *
+lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
/* Got PROTO_LCP from link */
- fsm_Input(&lcp->fsm, bp);
+ fsm_Input(&l->lcp.fsm, bp);
+ return NULL;
}
diff --git a/usr.sbin/ppp/lcp.h b/usr.sbin/ppp/lcp.h
index 47a984d..f4724c6 100644
--- a/usr.sbin/ppp/lcp.h
+++ b/usr.sbin/ppp/lcp.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lcp.h,v 1.20 1999/02/18 00:52:15 brian Exp $
+ * $Id: lcp.h,v 1.21 1999/02/26 21:28:12 brian Exp $
*
* TODO:
*/
@@ -136,5 +136,5 @@ extern void lcp_Setup(struct lcp *, int);
extern void lcp_SendProtoRej(struct lcp *, u_char *, int);
extern int lcp_ReportStatus(struct cmdargs const *);
-extern void lcp_Input(struct lcp *, struct mbuf *);
+extern struct mbuf *lcp_Input(struct bundle *, struct link *, struct mbuf *);
extern void lcp_SetupCallbacks(struct lcp *);
diff --git a/usr.sbin/ppp/link.c b/usr.sbin/ppp/link.c
index 1473969..99e91e9 100644
--- a/usr.sbin/ppp/link.c
+++ b/usr.sbin/ppp/link.c
@@ -23,30 +23,49 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: link.c,v 1.7 1999/02/06 02:54:46 brian Exp $
+ * $Id: link.c,v 1.8 1999/03/31 14:21:45 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>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include "defs.h"
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
#include "lqr.h"
#include "hdlc.h"
#include "throughput.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "fsm.h"
#include "descriptor.h"
#include "lcp.h"
#include "ccp.h"
#include "link.h"
#include "prompt.h"
+#include "async.h"
+#include "physical.h"
+#include "mp.h"
+#include "iplist.h"
+#include "slcompress.h"
+#include "ipcp.h"
+#include "ip.h"
+#include "auth.h"
+#include "pap.h"
+#include "chap.h"
+#include "cbcp.h"
+
+static void Despatch(struct bundle *, struct link *, struct mbuf *, u_short);
void
link_AddInOctets(struct link *l, int n)
@@ -125,39 +144,6 @@ link_Dequeue(struct link *l)
return bp;
}
-/*
- * Write to the link. Actualy, requested packets are queued, and go out
- * at some later time depending on the physical link implementation.
- */
-void
-link_Write(struct link *l, int pri, const char *ptr, int count)
-{
- struct mbuf *bp;
-
- if(pri < 0 || pri >= LINK_QUEUES)
- pri = 0;
-
- bp = mbuf_Alloc(count, MB_LINK);
- memcpy(MBUF_CTOP(bp), ptr, count);
-
- mbuf_Enqueue(l->Queue + pri, bp);
-}
-
-void
-link_Output(struct link *l, int pri, struct mbuf *bp)
-{
- struct mbuf *wp;
- int len;
-
- if(pri < 0 || pri >= LINK_QUEUES)
- pri = 0;
-
- len = mbuf_Length(bp);
- wp = mbuf_Alloc(len, MB_LINK);
- mbuf_Read(bp, MBUF_CTOP(wp), len);
- mbuf_Enqueue(l->Queue + pri, wp);
-}
-
static struct protostatheader {
u_short number;
const char *name;
@@ -208,3 +194,147 @@ link_ReportProtocolStatus(struct link *l, struct prompt *prompt)
if (!(i % 2))
prompt_Printf(prompt, "\n");
}
+
+void
+link_PushPacket(struct link *l, struct mbuf *bp, struct bundle *b, int pri,
+ u_short proto)
+{
+ int layer;
+
+ /*
+ * When we ``push'' a packet into the link, it gets processed by the
+ * ``push'' function in each layer starting at the top.
+ * We never expect the result of a ``push'' to be more than one
+ * packet (as we do with ``pull''s).
+ */
+
+ if(pri < 0 || pri >= LINK_QUEUES)
+ pri = 0;
+
+ for (layer = l->nlayers; layer && bp; layer--)
+ if (l->layer[layer - 1]->push != NULL)
+ bp = (*l->layer[layer - 1]->push)(b, l, bp, pri, &proto);
+
+ if (bp) {
+ log_Printf(LogDEBUG, "link_PushPacket: proto = 0x%04x\n", proto);
+ link_AddOutOctets(l, mbuf_Length(bp));
+ mbuf_Enqueue(l->Queue + pri, mbuf_Contiguous(bp));
+ }
+}
+
+void
+link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b)
+{
+ struct mbuf *bp, *lbp[LAYER_MAX], *next;
+ u_short lproto[LAYER_MAX], proto;
+ int layer;
+
+ /*
+ * 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.
+ * 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
+ * fsm state resulting from the receipt of the previous packet aren't
+ * surprised.
+ */
+
+ link_AddInOctets(l, len);
+
+ memset(lbp, '\0', sizeof lbp);
+ lbp[0] = mbuf_Alloc(len, MB_ASYNC);
+ memcpy(MBUF_CTOP(lbp[0]), buf, len);
+ lproto[0] = 0;
+ layer = 0;
+
+ while (layer || lbp[layer]) {
+ if (lbp[layer] == NULL) {
+ layer--;
+ continue;
+ }
+ bp = lbp[layer];
+ lbp[layer] = bp->pnext;
+ bp->pnext = NULL;
+ proto = lproto[layer];
+
+ if (l->layer[layer]->pull != NULL)
+ bp = (*l->layer[layer]->pull)(b, l, bp, &proto);
+
+ if (layer == l->nlayers - 1) {
+ /* We've just done the top layer, despatch the packet(s) */
+ while (bp) {
+ next = bp->pnext;
+ bp->pnext = NULL;
+ Despatch(b, l, bp, proto);
+ bp = next;
+ }
+ } else {
+ lbp[++layer] = bp;
+ lproto[layer] = proto;
+ }
+ }
+}
+
+int
+link_Stack(struct link *l, struct layer *layer)
+{
+ if (l->nlayers == sizeof l->layer / sizeof l->layer[0]) {
+ log_Printf(LogERROR, "%s: Oops, cannot stack a %s layer...\n",
+ l->name, layer->name);
+ return 0;
+ }
+ l->layer[l->nlayers++] = layer;
+ return 1;
+}
+
+void
+link_EmptyStack(struct link *l)
+{
+ l->nlayers = 0;
+}
+
+static const struct {
+ u_short proto;
+ struct mbuf *(*fn)(struct bundle *, struct link *, struct mbuf *);
+} despatcher[] = {
+ { PROTO_IP, ip_Input },
+ { PROTO_MP, mp_Input },
+ { PROTO_LCP, lcp_Input },
+ { PROTO_IPCP, ipcp_Input },
+ { PROTO_PAP, pap_Input },
+ { PROTO_CHAP, chap_Input },
+ { PROTO_CCP, ccp_Input },
+ { PROTO_LQR, lqr_Input },
+ { PROTO_CBCP, cbcp_Input }
+};
+
+#define DSIZE (sizeof despatcher / sizeof despatcher[0])
+
+static void
+Despatch(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short proto)
+{
+ int f;
+
+ for (f = 0; f < DSIZE; f++)
+ if (despatcher[f].proto == proto) {
+ bp = (*despatcher[f].fn)(bundle, l, bp);
+ break;
+ }
+
+ if (bp) {
+ struct physical *p = link2physical(l);
+
+ 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);
+ if (p) {
+ p->hdlc.lqm.SaveInDiscards++;
+ p->hdlc.stats.unknownproto++;
+ }
+ mbuf_Free(bp);
+ }
+}
diff --git a/usr.sbin/ppp/link.h b/usr.sbin/ppp/link.h
index 6a3858b..6225014 100644
--- a/usr.sbin/ppp/link.h
+++ b/usr.sbin/ppp/link.h
@@ -23,13 +23,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: link.h,v 1.3 1998/05/23 17:05:27 brian Exp $
+ * $Id: link.h,v 1.4 1998/08/25 17:48:42 brian Exp $
*
*/
-#define PHYSICAL_LINK 1
-#define MP_LINK 2
+#define PHYSICAL_LINK 1
+#define LOGICAL_LINK 2
#define LINK_QUEUES (PRI_MAX + 1)
#define NPROTOSTAT 13
@@ -49,6 +49,9 @@ struct link {
struct lcp lcp; /* Our line control FSM */
struct ccp ccp; /* Our compression FSM */
+
+ struct layer const *layer[LAYER_MAX]; /* i/o layers */
+ int nlayers;
};
extern void link_AddInOctets(struct link *, int);
@@ -59,9 +62,12 @@ extern void link_DeleteQueue(struct link *);
extern int link_QueueLen(struct link *);
extern int link_QueueBytes(struct link *);
extern struct mbuf *link_Dequeue(struct link *);
-extern void link_Write(struct link *, int, const char *, int);
-extern void link_StartOutput(struct link *, struct bundle *);
-extern void link_Output(struct link *, int, struct mbuf *);
+
+extern void link_PushPacket(struct link *, struct mbuf *, struct bundle *,
+ int, u_short);
+extern void link_PullPacket(struct link *, char *, size_t, struct bundle *);
+extern int link_Stack(struct link *, struct layer *);
+extern void link_EmptyStack(struct link *);
#define PROTO_IN 1 /* third arg to link_ProtocolRecord */
#define PROTO_OUT 2
diff --git a/usr.sbin/ppp/lqr.c b/usr.sbin/ppp/lqr.c
index 82bf6df..36966b1 100644
--- a/usr.sbin/ppp/lqr.c
+++ b/usr.sbin/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.31 1999/01/28 01:56:33 brian Exp $
+ * $Id: lqr.c,v 1.32 1999/03/29 08:21:28 brian Exp $
*
* o LQR based on RFC1333
*
@@ -32,12 +32,14 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "timer.h"
#include "fsm.h"
-#include "lcpproto.h"
+#include "acf.h"
+#include "proto.h"
#include "lcp.h"
#include "lqr.h"
#include "hdlc.h"
@@ -108,8 +110,8 @@ lqr_ChangeOrder(struct lqrdata * src, struct lqrdata * dst)
sp = (u_int32_t *) src;
dp = (u_int32_t *) dst;
- for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_int32_t); n++)
- *dp++ = ntohl(*sp++);
+ for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_int32_t); n++, sp++, dp++)
+ *dp = ntohl(*sp);
}
static void
@@ -118,7 +120,7 @@ SendLqrData(struct lcp *lcp)
struct mbuf *bp;
bp = mbuf_Alloc(sizeof(struct lqrdata), MB_LQR);
- hdlc_Output(lcp->fsm.link, PRI_LINK, PROTO_LQR, bp);
+ link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle, PRI_LINK, PROTO_LQR);
}
static void
@@ -160,59 +162,65 @@ SendLqrReport(void *v)
timer_Start(&p->hdlc.lqm.timer);
}
-void
-lqr_Input(struct physical *physical, struct mbuf *bp)
+struct mbuf *
+lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
+ struct physical *p = link2physical(l);
+ struct lcp *lcp = p->hdlc.lqm.owner;
int len;
+ if (p == NULL) {
+ log_Printf(LogERROR, "lqr_Input: Not a physical link - dropped\n");
+ mbuf_Free(bp);
+ return NULL;
+ }
+
+ p->hdlc.lqm.lqr.SaveInLQRs++;
+
len = mbuf_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(physical->link.lcp.cfg.lqr) &&
- !(physical->hdlc.lqm.method & LQM_LQR)) {
- bp->offset -= 2; /* XXX: We have a bit too much knowledge here ! */
- bp->cnt += 2;
- lcp_SendProtoRej(physical->hdlc.lqm.owner, MBUF_CTOP(bp), bp->cnt);
+ 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);
} else {
struct lqrdata *lqr;
- struct lcp *lcp;
u_int32_t lastLQR;
bp = mbuf_Contiguous(bp);
lqr = (struct lqrdata *)MBUF_CTOP(bp);
- lcp = physical->hdlc.lqm.owner;
- if (ntohl(lqr->MagicNumber) != physical->hdlc.lqm.owner->his_magic)
+ if (ntohl(lqr->MagicNumber) != lcp->his_magic)
log_Printf(LogWARN, "lqr_Input: magic 0x%08lx is wrong,"
" expecting 0x%08lx\n",
- (u_long)ntohl(lqr->MagicNumber),
- (u_long)physical->hdlc.lqm.owner->his_magic);
+ (u_long)ntohl(lqr->MagicNumber), (u_long)lcp->his_magic);
else {
/*
* Remember our PeerInLQRs, then convert byte order and save
*/
- lastLQR = physical->hdlc.lqm.lqr.peer.PeerInLQRs;
+ lastLQR = p->hdlc.lqm.lqr.peer.PeerInLQRs;
- lqr_ChangeOrder(lqr, &physical->hdlc.lqm.lqr.peer);
- lqr_Dump(physical->link.name, "Input", &physical->hdlc.lqm.lqr.peer);
+ lqr_ChangeOrder(lqr, &p->hdlc.lqm.lqr.peer);
+ lqr_Dump(l->name, "Input", &p->hdlc.lqm.lqr.peer);
/* we have received an LQR from peer */
- physical->hdlc.lqm.lqr.resent = 0;
+ p->hdlc.lqm.lqr.resent = 0;
/*
* Generate an LQR response if we're not running an LQR timer OR
* two successive LQR's PeerInLQRs are the same OR we're not going to
* send our next one before the peers max timeout.
*/
- if (physical->hdlc.lqm.timer.load == 0 ||
- !(physical->hdlc.lqm.method & LQM_LQR) ||
- (lastLQR && lastLQR == physical->hdlc.lqm.lqr.peer.PeerInLQRs) ||
- (physical->hdlc.lqm.lqr.peer_timeout &&
- physical->hdlc.lqm.timer.rest * 100 / SECTICKS >
- physical->hdlc.lqm.lqr.peer_timeout))
- SendLqrData(physical->hdlc.lqm.owner);
+ if (p->hdlc.lqm.timer.load == 0 ||
+ !(p->hdlc.lqm.method & LQM_LQR) ||
+ (lastLQR && lastLQR == p->hdlc.lqm.lqr.peer.PeerInLQRs) ||
+ (p->hdlc.lqm.lqr.peer_timeout &&
+ p->hdlc.lqm.timer.rest * 100 / SECTICKS >
+ p->hdlc.lqm.lqr.peer_timeout))
+ SendLqrData(lcp);
}
}
mbuf_Free(bp);
+ return NULL;
}
/*
@@ -319,3 +327,82 @@ lqr_Dump(const char *link, const char *message, const struct lqrdata *lqr)
lqr->PeerOutPackets, lqr->PeerOutOctets);
}
}
+
+static struct mbuf *
+lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ struct physical *p = link2physical(l);
+ int len;
+
+ if (!p) {
+ /* Oops - can't happen :-] */
+ mbuf_Free(bp);
+ return NULL;
+ }
+
+ /*
+ * From rfc1989:
+ *
+ * All octets which are included in the FCS calculation MUST be counted,
+ * including the packet header, the information field, and any padding.
+ * The FCS octets MUST also be counted, and one flag octet per frame
+ * MUST be counted. All other octets (such as additional flag
+ * sequences, and escape bits or octets) MUST NOT be counted.
+ *
+ * As we're stacked before the HDLC layer (otherwise HDLC wouldn't be
+ * able to calculate the FCS), we must not forget about these additional
+ * bytes when we're asynchronous.
+ *
+ * We're also expecting to be stacked *before* the proto and acf layers.
+ * If we were after these, it makes alignment more of a pain, and we
+ * don't do LQR without these layers.
+ */
+
+ bp = mbuf_Contiguous(bp);
+ len = mbuf_Length(bp);
+
+ if (!physical_IsSync(p))
+ p->hdlc.lqm.OutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
+ p->hdlc.lqm.OutOctets += acf_WrapperOctets(&l->lcp, *proto) +
+ proto_WrapperOctets(&l->lcp, *proto) + len + 1;
+ p->hdlc.lqm.OutPackets++;
+
+ if (*proto == PROTO_LQR) {
+ /* Overwrite the entire packet */
+ struct lqrdata lqr;
+
+ lqr.MagicNumber = p->link.lcp.want_magic;
+ lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
+ lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
+ lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
+ lqr.PeerInLQRs = p->hdlc.lqm.lqr.SaveInLQRs;
+ lqr.PeerInPackets = p->hdlc.lqm.SaveInPackets;
+ lqr.PeerInDiscards = p->hdlc.lqm.SaveInDiscards;
+ lqr.PeerInErrors = p->hdlc.lqm.SaveInErrors;
+ lqr.PeerInOctets = p->hdlc.lqm.SaveInOctets;
+ lqr.PeerOutPackets = p->hdlc.lqm.OutPackets;
+ lqr.PeerOutOctets = p->hdlc.lqm.OutOctets;
+ if (p->hdlc.lqm.lqr.peer.LastOutLQRs == p->hdlc.lqm.lqr.OutLQRs) {
+ /*
+ * only increment if it's the first time or we've got a reply
+ * from the last one
+ */
+ lqr.PeerOutLQRs = ++p->hdlc.lqm.lqr.OutLQRs;
+ lqr_Dump(l->name, "Output", &lqr);
+ } else {
+ lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
+ lqr_Dump(l->name, "Output (again)", &lqr);
+ }
+ lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
+ }
+
+ return bp;
+}
+
+/*
+ * Statistics for pulled packets are recorded either in hdlc_PullPacket()
+ * or sync_PullPacket()
+ */
+
+struct layer lqrlayer = { LAYER_LQR, "lqr", lqr_LayerPush, NULL };
diff --git a/usr.sbin/ppp/lqr.h b/usr.sbin/ppp/lqr.h
index f562828..7b29b4b 100644
--- a/usr.sbin/ppp/lqr.h
+++ b/usr.sbin/ppp/lqr.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lqr.h,v 1.12.2.6 1998/05/08 01:15:09 brian Exp $
+ * $Id: lqr.h,v 1.13 1998/05/21 21:46:36 brian Exp $
*
* TODO:
*/
@@ -48,6 +48,8 @@ struct mbuf;
struct physical;
struct lcp;
struct fsm;
+struct link;
+struct bundle;
extern void lqr_Dump(const char *, const char *, const struct lqrdata *);
extern void lqr_ChangeOrder(struct lqrdata *, struct lqrdata *);
@@ -56,4 +58,6 @@ extern void lqr_reStart(struct lcp *);
extern void lqr_Stop(struct physical *, int);
extern void lqr_StopTimer(struct physical *);
extern void lqr_RecvEcho(struct fsm *, struct mbuf *);
-extern void lqr_Input(struct physical *, struct mbuf *);
+extern struct mbuf *lqr_Input(struct bundle *, struct link *, struct mbuf *);
+
+extern struct layer lqrlayer;
diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c
index 6c5f6ff..e0c09c3 100644
--- a/usr.sbin/ppp/main.c
+++ b/usr.sbin/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.152 1999/03/30 00:44:57 brian Exp $
+ * $Id: main.c,v 1.153 1999/04/26 08:54:34 brian Exp $
*
* TODO:
*/
@@ -45,6 +45,7 @@
#include "alias.h"
#endif
#endif
+#include "layer.h"
#include "probe.h"
#include "mbuf.h"
#include "log.h"
@@ -571,7 +572,6 @@ 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/mbuf.c b/usr.sbin/ppp/mbuf.c
index 0e29c81..e9096aa 100644
--- a/usr.sbin/ppp/mbuf.c
+++ b/usr.sbin/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.23 1999/02/06 02:54:47 brian Exp $
+ * $Id: mbuf.c,v 1.24 1999/03/29 08:21:28 brian Exp $
*
*/
#include <sys/types.h>
@@ -42,6 +42,7 @@ static struct memmap {
} MemMap[MB_MAX + 2];
static int totalalloced;
+static unsigned long long mbuf_Mallocs, mbuf_Frees;
int
mbuf_Length(struct mbuf * bp)
@@ -66,6 +67,7 @@ mbuf_Alloc(int cnt, int type)
(long)sizeof(struct mbuf));
AbortProgram(EX_OSERR);
}
+ mbuf_Mallocs++;
memset(bp, '\0', sizeof(struct mbuf));
MemMap[type].fragments++;
MemMap[type].octets += cnt;
@@ -76,7 +78,7 @@ mbuf_Alloc(int cnt, int type)
}
struct mbuf *
-mbuf_FreeSeg(struct mbuf * bp)
+mbuf_FreeSeg(struct mbuf *bp)
{
struct mbuf *nbp;
@@ -86,6 +88,7 @@ mbuf_FreeSeg(struct mbuf * bp)
MemMap[bp->type].octets -= bp->size;
totalalloced -= bp->size;
free(bp);
+ mbuf_Frees++;
bp = nbp;
}
@@ -93,35 +96,108 @@ mbuf_FreeSeg(struct mbuf * bp)
}
void
-mbuf_Free(struct mbuf * bp)
+mbuf_Free(struct mbuf *bp)
{
while (bp)
bp = mbuf_FreeSeg(bp);
}
struct mbuf *
-mbuf_Read(struct mbuf * bp, u_char * ptr, int len)
+mbuf_Read(struct mbuf *bp, void *v, size_t len)
{
int nb;
+ u_char *ptr = v;
while (bp && len > 0) {
if (len > bp->cnt)
nb = bp->cnt;
else
nb = len;
- memcpy(ptr, MBUF_CTOP(bp), nb);
- ptr += nb;
- bp->cnt -= nb;
- len -= nb;
- bp->offset += nb;
+ if (nb) {
+ memcpy(ptr, MBUF_CTOP(bp), nb);
+ ptr += nb;
+ bp->cnt -= nb;
+ len -= nb;
+ bp->offset += nb;
+ }
if (bp->cnt == 0)
bp = mbuf_FreeSeg(bp);
}
- return (bp);
+
+ while (bp && bp->cnt == 0)
+ bp = mbuf_FreeSeg(bp);
+
+ return bp;
+}
+
+size_t
+mbuf_View(struct mbuf *bp, void *v, size_t len)
+{
+ size_t nb, l = len;
+ u_char *ptr = v;
+
+ while (bp && l > 0) {
+ if (l > bp->cnt)
+ nb = bp->cnt;
+ else
+ nb = l;
+ memcpy(ptr, MBUF_CTOP(bp), nb);
+ ptr += nb;
+ l -= nb;
+ bp = bp->next;
+ }
+
+ return len - l;
+}
+
+struct mbuf *
+mbuf_Prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra)
+{
+ struct mbuf *head;
+
+ if (bp->offset) {
+ if (bp->offset >= len) {
+ bp->offset -= len;
+ bp->cnt += 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;
+ }
+
+ head = mbuf_Alloc(len + extra, bp->type);
+ head->offset = extra;
+ head->cnt -= extra;
+ memcpy(MBUF_CTOP(head), ptr, len);
+ head->next = bp;
+
+ return head;
+}
+
+struct mbuf *
+mbuf_Truncate(struct mbuf *bp, size_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;
+ }
+
+ return bp;
}
void
-mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt)
+mbuf_Write(struct mbuf *bp, const void *ptr, size_t cnt)
{
int plen;
int nb;
@@ -143,8 +219,8 @@ mbuf_Show(struct cmdargs const *arg)
{
int i;
static const char *mbuftype[] = {
- "async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "link",
- "vjcomp", "ipq", "mp" };
+ "async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "vjcomp",
+ "ipq", "mp" };
prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
for (i = 1; i < MB_MAX; i += 2)
@@ -156,6 +232,9 @@ mbuf_Show(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n",
mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets);
+ prompt_Printf(arg->prompt, "Mallocs: %qu, Frees: %qu\n",
+ mbuf_Mallocs, mbuf_Frees);
+
return 0;
}
diff --git a/usr.sbin/ppp/mbuf.h b/usr.sbin/ppp/mbuf.h
index 1ee8e6f..f92dcd5 100644
--- a/usr.sbin/ppp/mbuf.h
+++ b/usr.sbin/ppp/mbuf.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: mbuf.h,v 1.14 1998/08/21 18:10:15 brian Exp $
+ * $Id: mbuf.h,v 1.15 1999/03/29 08:21:28 brian Exp $
*
* TODO:
*/
@@ -46,10 +46,9 @@ struct mqueue {
#define MB_IPIN 5
#define MB_ECHO 6
#define MB_LQR 7
-#define MB_LINK 8
-#define MB_VJCOMP 9
-#define MB_IPQ 10
-#define MB_MP 11
+#define MB_VJCOMP 8
+#define MB_IPQ 9
+#define MB_MP 10
#define MB_MAX MB_MP
struct cmdargs;
@@ -58,8 +57,11 @@ 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 void mbuf_Write(struct mbuf *, u_char *, int);
-extern struct mbuf *mbuf_Read(struct mbuf *, u_char *, int);
+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 void mbuf_Log(void);
extern int mbuf_Show(struct cmdargs const *);
extern void mbuf_Enqueue(struct mqueue *, struct mbuf *);
diff --git a/usr.sbin/ppp/modem.c b/usr.sbin/ppp/modem.c
deleted file mode 100644
index e8ef2f1..0000000
--- a/usr.sbin/ppp/modem.c
+++ /dev/null
@@ -1,1155 +0,0 @@
-/*
- * PPP Modem handling module
- *
- * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
- *
- * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Internet Initiative Japan, Inc. The name of the
- * IIJ may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: modem.c,v 1.111 1999/04/26 08:54:34 brian Exp $
- *
- * TODO:
- */
-#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>
-#include <fcntl.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/tty.h> /* TIOCOUTQ */
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#if defined(__OpenBSD__) || defined(__NetBSD__)
-#include <sys/ioctl.h>
-#include <util.h>
-#else
-#include <libutil.h>
-#endif
-
-#include "defs.h"
-#include "command.h"
-#include "mbuf.h"
-#include "log.h"
-#include "id.h"
-#include "timer.h"
-#include "fsm.h"
-#include "lqr.h"
-#include "hdlc.h"
-#include "lcp.h"
-#include "modem.h"
-#include "throughput.h"
-#include "async.h"
-#include "iplist.h"
-#include "slcompress.h"
-#include "ipcp.h"
-#include "filter.h"
-#include "descriptor.h"
-#include "ccp.h"
-#include "link.h"
-#include "physical.h"
-#include "mp.h"
-#ifndef NORADIUS
-#include "radius.h"
-#endif
-#include "bundle.h"
-#include "prompt.h"
-#include "chat.h"
-#include "auth.h"
-#include "chap.h"
-#include "cbcp.h"
-#include "datalink.h"
-
-
-static int modem_DescriptorWrite(struct descriptor *, struct bundle *,
- const fd_set *);
-static void modem_DescriptorRead(struct descriptor *, struct bundle *,
- const fd_set *);
-static int modem_UpdateSet(struct descriptor *, fd_set *, fd_set *, fd_set *,
- int *);
-
-struct physical *
-modem_Create(struct datalink *dl, int type)
-{
- struct physical *p;
-
- p = (struct physical *)malloc(sizeof(struct physical));
- if (!p)
- return NULL;
-
- p->link.type = PHYSICAL_LINK;
- p->link.name = dl->name;
- p->link.len = sizeof *p;
- throughput_init(&p->link.throughput);
- memset(&p->Timer, '\0', sizeof p->Timer);
- memset(p->link.Queue, '\0', sizeof p->link.Queue);
- memset(p->link.proto_in, '\0', sizeof p->link.proto_in);
- memset(p->link.proto_out, '\0', sizeof p->link.proto_out);
-
- p->desc.type = PHYSICAL_DESCRIPTOR;
- p->desc.UpdateSet = modem_UpdateSet;
- p->desc.IsSet = physical_IsSet;
- p->desc.Read = modem_DescriptorRead;
- p->desc.Write = modem_DescriptorWrite;
- p->type = type;
-
- hdlc_Init(&p->hdlc, &p->link.lcp);
- async_Init(&p->async);
-
- p->fd = -1;
- p->mbits = 0;
- p->isatty = 0;
- p->out = NULL;
- p->connect_count = 0;
- p->dl = dl;
- p->input.sz = 0;
- *p->name.full = '\0';
- p->name.base = p->name.full;
-
- p->Utmp = 0;
- p->session_owner = (pid_t)-1;
-
- p->cfg.rts_cts = MODEM_CTSRTS;
- p->cfg.speed = MODEM_SPEED;
- 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;
-
- lcp_Init(&p->link.lcp, dl->bundle, &p->link, &dl->fsmp);
- ccp_Init(&p->link.ccp, dl->bundle, &p->link, &dl->fsmp);
-
- return p;
-}
-
-/* XXX-ML this should probably change when we add support for other
- types of devices */
-#define Online(modem) ((modem)->mbits & TIOCM_CD)
-
-static void modem_LogicalClose(struct physical *);
-
-static const struct speeds {
- int nspeed;
- speed_t speed;
-} speeds[] = {
-#ifdef B50
- { 50, B50, },
-#endif
-#ifdef B75
- { 75, B75, },
-#endif
-#ifdef B110
- { 110, B110, },
-#endif
-#ifdef B134
- { 134, B134, },
-#endif
-#ifdef B150
- { 150, B150, },
-#endif
-#ifdef B200
- { 200, B200, },
-#endif
-#ifdef B300
- { 300, B300, },
-#endif
-#ifdef B600
- { 600, B600, },
-#endif
-#ifdef B1200
- { 1200, B1200, },
-#endif
-#ifdef B1800
- { 1800, B1800, },
-#endif
-#ifdef B2400
- { 2400, B2400, },
-#endif
-#ifdef B4800
- { 4800, B4800, },
-#endif
-#ifdef B9600
- { 9600, B9600, },
-#endif
-#ifdef B19200
- { 19200, B19200, },
-#endif
-#ifdef B38400
- { 38400, B38400, },
-#endif
-#ifndef _POSIX_SOURCE
-#ifdef B7200
- { 7200, B7200, },
-#endif
-#ifdef B14400
- { 14400, B14400, },
-#endif
-#ifdef B28800
- { 28800, B28800, },
-#endif
-#ifdef B57600
- { 57600, B57600, },
-#endif
-#ifdef B76800
- { 76800, B76800, },
-#endif
-#ifdef B115200
- { 115200, B115200, },
-#endif
-#ifdef B230400
- { 230400, B230400, },
-#endif
-#ifdef EXTA
- { 19200, EXTA, },
-#endif
-#ifdef EXTB
- { 38400, EXTB, },
-#endif
-#endif /* _POSIX_SOURCE */
- { 0, 0 }
-};
-
-static int
-SpeedToInt(speed_t speed)
-{
- const struct speeds *sp;
-
- for (sp = speeds; sp->nspeed; sp++) {
- if (sp->speed == speed) {
- return (sp->nspeed);
- }
- }
- return 0;
-}
-
-speed_t
-IntToSpeed(int nspeed)
-{
- const struct speeds *sp;
-
- for (sp = speeds; sp->nspeed; sp++) {
- if (sp->nspeed == nspeed) {
- return (sp->speed);
- }
- }
- return B0;
-}
-
-static void
-modem_SetDevice(struct physical *physical, const char *name)
-{
- int len = strlen(_PATH_DEV);
-
- strncpy(physical->name.full, name, sizeof physical->name.full - 1);
- physical->name.full[sizeof physical->name.full - 1] = '\0';
- physical->name.base = *physical->name.full == '!' ?
- physical->name.full + 1 :
- strncmp(physical->name.full, _PATH_DEV, len) ?
- physical->name.full : physical->name.full + len;
-}
-
-/*
- * modem_Timeout() watches DCD signal and notifies if it's status is changed.
- *
- */
-static void
-modem_Timeout(void *data)
-{
- struct physical *modem = data;
- int ombits = modem->mbits;
- int change;
-
- timer_Stop(&modem->Timer);
- modem->Timer.load = SECTICKS; /* Once a second please */
- timer_Start(&modem->Timer);
-
- if (modem->isatty || physical_IsSync(modem)) {
- ombits = modem->mbits;
-
- if (modem->fd >= 0) {
- if (ioctl(modem->fd, TIOCMGET, &modem->mbits) < 0) {
- log_Printf(LogPHASE, "%s: Carrier not required (pseudo tty ?)\n",
- modem->link.name);
- timer_Stop(&modem->Timer);
- modem->mbits = TIOCM_CD;
- return;
- }
- } else
- modem->mbits = 0;
-
- if (ombits == -1) {
- /* First time looking for carrier */
- if (Online(modem))
- log_Printf(LogDEBUG, "%s: %s: CD detected\n",
- modem->link.name, modem->name.full);
- else if (modem->cfg.cd.required) {
- log_Printf(LogPHASE, "%s: %s: Required CD not detected\n",
- modem->link.name, modem->name.full);
- datalink_Down(modem->dl, CLOSE_NORMAL);
- } else {
- log_Printf(LogPHASE, "%s: %s doesn't support CD\n",
- modem->link.name, modem->name.full);
- timer_Stop(&modem->Timer);
- modem->mbits = TIOCM_CD;
- }
- } else {
- change = ombits ^ modem->mbits;
- if (change & TIOCM_CD) {
- if (modem->mbits & TIOCM_CD)
- log_Printf(LogDEBUG, "%s: offline -> online\n", modem->link.name);
- else {
- log_Printf(LogDEBUG, "%s: online -> offline\n", modem->link.name);
- log_Printf(LogPHASE, "%s: Carrier lost\n", modem->link.name);
- datalink_Down(modem->dl, CLOSE_NORMAL);
- }
- } else
- log_Printf(LogDEBUG, "%s: Still %sline\n", modem->link.name,
- Online(modem) ? "on" : "off");
- }
- } else if (!Online(modem)) {
- /* mbits was set to zero in modem_Open() */
- modem->mbits = TIOCM_CD;
- }
-}
-
-static void
-modem_StartTimer(struct bundle *bundle, struct physical *modem)
-{
- timer_Stop(&modem->Timer);
- modem->Timer.load = SECTICKS * modem->cfg.cd.delay;
- modem->Timer.func = modem_Timeout;
- modem->Timer.name = "modem CD";
- modem->Timer.arg = modem;
- log_Printf(LogDEBUG, "%s: Using modem_Timeout [%p]\n",
- modem->link.name, modem_Timeout);
- modem->mbits = -1; /* So we know it's the first time */
- timer_Start(&modem->Timer);
-}
-
-static const struct parity {
- const char *name;
- const char *name1;
- int set;
-} validparity[] = {
- { "even", "P_EVEN", CS7 | PARENB },
- { "odd", "P_ODD", CS7 | PARENB | PARODD },
- { "none", "P_ZERO", CS8 },
- { NULL, 0 },
-};
-
-static int
-GetParityValue(const char *str)
-{
- const struct parity *pp;
-
- for (pp = validparity; pp->name; pp++) {
- if (strcasecmp(pp->name, str) == 0 ||
- strcasecmp(pp->name1, str) == 0) {
- return pp->set;
- }
- }
- return (-1);
-}
-
-int
-modem_SetParity(struct physical *modem, const char *str)
-{
- struct termios rstio;
- int val;
-
- val = GetParityValue(str);
- if (val > 0) {
- modem->cfg.parity = val;
- tcgetattr(modem->fd, &rstio);
- rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
- rstio.c_cflag |= val;
- tcsetattr(modem->fd, TCSADRAIN, &rstio);
- return 0;
- }
- log_Printf(LogWARN, "%s: %s: Invalid parity\n", modem->link.name, str);
- return -1;
-}
-
-static int
-OpenConnection(const char *name, char *host, char *port)
-{
- struct sockaddr_in dest;
- int sock;
- struct servent *sp;
-
- dest.sin_family = AF_INET;
- dest.sin_addr.s_addr = inet_addr(host);
- dest.sin_addr = GetIpAddr(host);
- if (dest.sin_addr.s_addr == INADDR_NONE) {
- log_Printf(LogWARN, "%s: %s: unknown host\n", name, host);
- return (-1);
- }
- dest.sin_port = htons(atoi(port));
- if (dest.sin_port == 0) {
- sp = getservbyname(port, "tcp");
- if (sp) {
- dest.sin_port = sp->s_port;
- } else {
- log_Printf(LogWARN, "%s: %s: unknown service\n", name, port);
- return (-1);
- }
- }
- log_Printf(LogPHASE, "%s: Connecting to %s:%s\n", name, host, port);
-
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- return (sock);
- }
- if (connect(sock, (struct sockaddr *)&dest, sizeof dest) < 0) {
- log_Printf(LogWARN, "%s: connect: %s\n", name, strerror(errno));
- close(sock);
- return (-1);
- }
- return (sock);
-}
-
-static int
-modem_lock(struct physical *modem, int tunno)
-{
- int res;
- FILE *lockfile;
- char fn[MAXPATHLEN];
-
- if (*modem->name.full != '/')
- return 0;
-
- if (modem->type != PHYS_DIRECT &&
- (res = ID0uu_lock(modem->name.base)) != UU_LOCK_OK) {
- if (res == UU_LOCK_INUSE)
- log_Printf(LogPHASE, "%s: %s is in use\n",
- modem->link.name, modem->name.full);
- else
- log_Printf(LogPHASE, "%s: %s is in use: uu_lock: %s\n",
- modem->link.name, modem->name.full, uu_lockerr(res));
- return (-1);
- }
-
- snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, modem->name.base);
- lockfile = ID0fopen(fn, "w");
- if (lockfile != NULL) {
- fprintf(lockfile, "%s%d\n", TUN_NAME, tunno);
- fclose(lockfile);
- }
-#ifndef RELEASE_CRUNCH
- else
- log_Printf(LogALERT, "%s: Can't create %s: %s\n",
- modem->link.name, fn, strerror(errno));
-#endif
-
- return 0;
-}
-
-static void
-modem_Unlock(struct physical *modem)
-{
- char fn[MAXPATHLEN];
-
- if (*modem->name.full != '/')
- return;
-
- snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, modem->name.base);
-#ifndef RELEASE_CRUNCH
- if (ID0unlink(fn) == -1)
- log_Printf(LogALERT, "%s: Can't remove %s: %s\n",
- modem->link.name, fn, strerror(errno));
-#else
- ID0unlink(fn);
-#endif
-
- if (modem->type != PHYS_DIRECT && ID0uu_unlock(modem->name.base) == -1)
- log_Printf(LogALERT, "%s: Can't uu_unlock %s\n", modem->link.name, fn);
-}
-
-static void
-modem_Found(struct physical *modem, struct bundle *bundle)
-{
- throughput_start(&modem->link.throughput, "modem throughput",
- Enabled(bundle, OPT_THROUGHPUT));
- modem->connect_count++;
- modem->input.sz = 0;
- log_Printf(LogPHASE, "%s: Connected!\n", modem->link.name);
-}
-
-int
-modem_Open(struct physical *modem, struct bundle *bundle)
-{
- struct termios rstio;
- int oldflag, devno;
- char *host, *port, *cp, *dev;
-
- if (modem->fd >= 0)
- log_Printf(LogDEBUG, "%s: Open: Modem is already open!\n", modem->link.name);
- /* We're going back into "term" mode */
- else if (modem->type == PHYS_DIRECT) {
- if (isatty(STDIN_FILENO)) {
- log_Printf(LogDEBUG, "%s: Open(direct): Modem is a tty\n",
- modem->link.name);
- modem_SetDevice(modem, ttyname(STDIN_FILENO));
- if (modem_lock(modem, bundle->unit) == -1) {
- close(STDIN_FILENO);
- return -1;
- }
- modem->fd = STDIN_FILENO;
- modem_Found(modem, bundle);
- } else {
- log_Printf(LogDEBUG, "%s: Open(direct): Modem is not a tty\n",
- modem->link.name);
- modem_SetDevice(modem, "");
- /* We don't call modem_Timeout() with this type of connection */
- modem_Found(modem, bundle);
- return modem->fd = STDIN_FILENO;
- }
- } else {
- dev = modem->cfg.devlist;
- devno = 0;
- while (devno < modem->cfg.ndev && modem->fd < 0) {
- modem_SetDevice(modem, dev);
-
- if (*modem->name.full == '/') {
- /* PPP via a device file */
- /*
- * XXX: Fix me - this should be another sort of link (similar to a
- * physical
- */
- if (modem_lock(modem, bundle->unit) != -1) {
- modem->fd = ID0open(modem->name.full, O_RDWR | O_NONBLOCK);
- if (modem->fd < 0) {
- log_Printf(LogPHASE, "%s: Open(\"%s\"): %s\n",
- modem->link.name, modem->name.full, strerror(errno));
- modem_Unlock(modem);
- } else {
- modem_Found(modem, bundle);
- log_Printf(LogDEBUG, "%s: Opened %s\n",
- modem->link.name, modem->name.full);
- }
- }
- } else if (*modem->name.full == '!') {
- /* PPP via an external program */
- /*
- * XXX: Fix me - this should be another sort of link (similar to a
- * physical
- */
- int fids[2];
-
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0)
- log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
- strerror(errno));
- else {
- int stat, argc;
- pid_t pid;
- char *argv[MAXARGS];
-
- stat = fcntl(fids[0], F_GETFL, 0);
- if (stat > 0) {
- stat |= O_NONBLOCK;
- fcntl(fids[0], F_SETFL, stat);
- }
- switch ((pid = fork())) {
- case -1:
- log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
- strerror(errno));
- break;
-
- case 0:
- close(fids[0]);
- timer_TermService();
- setuid(geteuid());
-
- switch (fork()) {
- case 0:
- break;
-
- case -1:
- log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n",
- strerror(errno));
- default:
- _exit(127);
- }
-
- fids[1] = fcntl(fids[1], F_DUPFD, 3);
- dup2(fids[1], STDIN_FILENO);
- dup2(fids[1], STDOUT_FILENO);
- dup2(fids[1], STDERR_FILENO);
-
- argc = MakeArgs(modem->name.base, argv, VECSIZE(argv));
- command_Expand(argv, argc, (char const *const *)argv, bundle, 0);
- execvp(*argv, argv);
- fprintf(stderr, "execvp failed: %s: %s\r\n", *argv,
- strerror(errno));
- _exit(127);
- break;
-
- default:
- close(fids[1]);
- modem->fd = fids[0];
- waitpid(pid, &stat, 0);
- log_Printf(LogDEBUG, "Using descriptor %d for child\n",
- modem->fd);
- modem_Found(modem, bundle);
- break;
- }
- }
- } else if ((cp = strchr(modem->name.full, ':')) != NULL) {
- /* PPP over TCP */
- /*
- * XXX: Fix me - this should be another sort of link (similar to a
- * physical
- */
- *cp = '\0';
- host = modem->name.full;
- port = cp + 1;
- if (*host && *port) {
- modem->fd = OpenConnection(modem->link.name, host, port);
- *cp = ':'; /* Don't destroy name.full */
- if (modem->fd >= 0) {
- modem_Found(modem, bundle);
- log_Printf(LogDEBUG, "%s: Opened socket %s\n", modem->link.name,
- modem->name.full);
- }
- } else {
- *cp = ':'; /* Don't destroy name.full */
- log_Printf(LogWARN, "%s: Invalid host:port: \"%s\"\n",
- modem->link.name, modem->name.full);
- }
- } else {
- log_Printf(LogWARN, "%s: Device (%s) must begin with a '/',"
- " a '!' or be a host:port pair\n", modem->link.name,
- modem->name.full);
- }
- dev += strlen(dev) + 1;
- devno++;
- }
-
- if (modem->fd < 0)
- return modem->fd;
- }
-
- /*
- * If we are working on tty device, change it's mode into the one desired
- * for further operation.
- */
- modem->mbits = 0;
- modem->isatty = isatty(modem->fd);
- if (modem->isatty) {
- tcgetattr(modem->fd, &rstio);
- modem->ios = rstio;
- log_Printf(LogDEBUG, "%s: Open: modem (get): fd = %d, iflag = %lx, "
- "oflag = %lx, cflag = %lx\n", modem->link.name, modem->fd,
- (u_long)rstio.c_iflag, (u_long)rstio.c_oflag,
- (u_long)rstio.c_cflag);
- cfmakeraw(&rstio);
- if (modem->cfg.rts_cts)
- rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
- else {
- rstio.c_cflag |= CLOCAL;
- rstio.c_iflag |= IXOFF;
- }
- rstio.c_iflag |= IXON;
- if (modem->type != PHYS_DEDICATED)
- rstio.c_cflag |= HUPCL;
-
- if (modem->type != PHYS_DIRECT) {
- /* Change tty speed when we're not in -direct mode */
- rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
- rstio.c_cflag |= modem->cfg.parity;
- if (cfsetspeed(&rstio, IntToSpeed(modem->cfg.speed)) == -1)
- log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
- modem->link.name, modem->name.full, modem->cfg.speed);
- }
- tcsetattr(modem->fd, TCSADRAIN, &rstio);
- log_Printf(LogDEBUG, "%s: modem (put): iflag = %lx, oflag = %lx, "
- "cflag = %lx\n", modem->link.name, (u_long)rstio.c_iflag,
- (u_long)rstio.c_oflag, (u_long)rstio.c_cflag);
-
- if (ioctl(modem->fd, TIOCMGET, &modem->mbits) == -1) {
- if (modem->type != PHYS_DIRECT) {
- log_Printf(LogWARN, "%s: Open: Cannot get modem status: %s\n",
- modem->link.name, strerror(errno));
- modem_LogicalClose(modem);
- return (-1);
- } else
- modem->mbits = TIOCM_CD;
- }
- log_Printf(LogDEBUG, "%s: Open: modem control = %o\n",
- modem->link.name, modem->mbits);
-
- oldflag = fcntl(modem->fd, F_GETFL, 0);
- if (oldflag < 0) {
- log_Printf(LogWARN, "%s: Open: Cannot get modem flags: %s\n",
- modem->link.name, strerror(errno));
- modem_LogicalClose(modem);
- return (-1);
- }
- fcntl(modem->fd, F_SETFL, oldflag & ~O_NONBLOCK);
- }
-
- return modem->fd;
-}
-
-int
-modem_Speed(struct physical *modem)
-{
- struct termios rstio;
-
- if (!modem->isatty)
- return 115200;
-
- tcgetattr(modem->fd, &rstio);
- return (SpeedToInt(cfgetispeed(&rstio)));
-}
-
-/*
- * Put modem tty line into raw mode which is necessary in packet mode operation
- */
-int
-modem_Raw(struct physical *modem, struct bundle *bundle)
-{
- struct termios rstio;
- int oldflag;
-
- log_Printf(LogDEBUG, "%s: Entering modem_Raw\n", modem->link.name);
-
- if (!modem->isatty || physical_IsSync(modem))
- return 0;
-
- if (modem->type != PHYS_DIRECT && modem->fd >= 0 && !Online(modem))
- log_Printf(LogDEBUG, "%s: Raw: modem = %d, mbits = %x\n",
- modem->link.name, modem->fd, modem->mbits);
-
- tcgetattr(modem->fd, &rstio);
- cfmakeraw(&rstio);
- if (modem->cfg.rts_cts)
- rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
- else
- rstio.c_cflag |= CLOCAL;
-
- if (modem->type != PHYS_DEDICATED)
- rstio.c_cflag |= HUPCL;
-
- tcsetattr(modem->fd, TCSANOW, &rstio);
-
- oldflag = fcntl(modem->fd, F_GETFL, 0);
- if (oldflag < 0)
- return (-1);
- fcntl(modem->fd, F_SETFL, oldflag | O_NONBLOCK);
-
- modem_StartTimer(bundle, modem);
-
- return 0;
-}
-
-static void
-modem_Unraw(struct physical *modem)
-{
- int oldflag;
-
- if (modem->isatty && !physical_IsSync(modem)) {
- tcsetattr(modem->fd, TCSAFLUSH, &modem->ios);
- oldflag = fcntl(modem->fd, F_GETFL, 0);
- if (oldflag < 0)
- return;
- (void) fcntl(modem->fd, F_SETFL, oldflag & ~O_NONBLOCK);
- }
-}
-
-static void
-modem_PhysicalClose(struct physical *modem)
-{
- int newsid;
-
- log_Printf(LogDEBUG, "%s: Physical Close\n", modem->link.name);
- timer_Stop(&modem->Timer);
- newsid = tcgetpgrp(modem->fd) == getpgrp();
- close(modem->fd);
- modem->fd = -1;
- log_SetTtyCommandMode(modem->dl);
- throughput_stop(&modem->link.throughput);
- throughput_log(&modem->link.throughput, LogPHASE, modem->link.name);
- if (modem->session_owner != (pid_t)-1) {
- ID0kill(modem->session_owner, SIGHUP);
- modem->session_owner = (pid_t)-1;
- }
- if (newsid)
- bundle_setsid(modem->dl->bundle, 0);
-}
-
-void
-modem_Offline(struct physical *modem)
-{
- if (modem->fd >= 0) {
- struct termios tio;
-
- timer_Stop(&modem->Timer);
- modem->mbits &= ~TIOCM_DTR;
- if (modem->isatty && Online(modem)) {
- tcgetattr(modem->fd, &tio);
- if (cfsetspeed(&tio, B0) == -1)
- log_Printf(LogWARN, "%s: Unable to set modem to speed 0\n",
- modem->link.name);
- else
- tcsetattr(modem->fd, TCSANOW, &tio);
- /* nointr_sleep(1); */
- }
- log_Printf(LogPHASE, "%s: Disconnected!\n", modem->link.name);
- }
-}
-
-void
-modem_Close(struct physical *modem)
-{
- if (modem->fd < 0)
- return;
-
- log_Printf(LogDEBUG, "%s: Close\n", modem->link.name);
-
- if (!modem->isatty) {
- modem_PhysicalClose(modem);
- if (*modem->name.full == '/')
- modem_Unlock(modem);
- *modem->name.full = '\0';
- modem->name.base = modem->name.full;
- return;
- }
-
- if (modem->fd >= 0) {
- tcflush(modem->fd, TCIOFLUSH);
- modem_Unraw(modem);
- modem_LogicalClose(modem);
- }
-}
-
-void
-modem_Destroy(struct physical *modem)
-{
- modem_Close(modem);
- free(modem);
-}
-
-static void
-modem_LogicalClose(struct physical *modem)
-{
- log_Printf(LogDEBUG, "%s: Logical Close\n", modem->link.name);
- if (modem->fd >= 0) {
- physical_Logout(modem);
- modem_PhysicalClose(modem);
- modem_Unlock(modem);
- }
- *modem->name.full = '\0';
- modem->name.base = modem->name.full;
-}
-
-static int
-modem_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
- const fd_set *fdset)
-{
- struct physical *modem = descriptor2physical(d);
- int nw, result = 0;
-
- if (modem->out == NULL)
- modem->out = link_Dequeue(&modem->link);
-
- if (modem->out) {
- nw = physical_Write(modem, MBUF_CTOP(modem->out), modem->out->cnt);
- log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%d) to %d\n",
- modem->link.name, nw, modem->out->cnt, modem->fd);
- if (nw > 0) {
- modem->out->cnt -= nw;
- modem->out->offset += nw;
- if (modem->out->cnt == 0)
- modem->out = mbuf_FreeSeg(modem->out);
- result = 1;
- } else if (nw < 0) {
- if (errno != EAGAIN) {
- log_Printf(LogPHASE, "%s: write (%d): %s\n", modem->link.name,
- modem->fd, strerror(errno));
- datalink_Down(modem->dl, CLOSE_NORMAL);
- }
- result = 1;
- }
- /* else we shouldn't really have been called ! select() is broken ! */
- }
-
- return result;
-}
-
-int
-modem_ShowStatus(struct cmdargs const *arg)
-{
- struct physical *modem = arg->cx->physical;
- const char *dev;
- int n;
-
- prompt_Printf(arg->prompt, "Name: %s\n", modem->link.name);
- prompt_Printf(arg->prompt, " State: ");
- if (modem->fd >= 0) {
- if (modem->isatty)
- prompt_Printf(arg->prompt, "open, %s carrier\n",
- Online(modem) ? "with" : "no");
- else
- prompt_Printf(arg->prompt, "open\n");
- } else
- prompt_Printf(arg->prompt, "closed\n");
- prompt_Printf(arg->prompt, " Device: %s",
- *modem->name.full ? modem->name.full :
- modem->type == PHYS_DIRECT ? "unknown" : "N/A");
- if (modem->session_owner != (pid_t)-1)
- prompt_Printf(arg->prompt, " (session owner: %d)",
- (int)modem->session_owner);
-
- prompt_Printf(arg->prompt, "\n Link Type: %s\n", mode2Nam(modem->type));
- prompt_Printf(arg->prompt, " Connect Count: %d\n",
- modem->connect_count);
-#ifdef TIOCOUTQ
- if (modem->fd >= 0 && ioctl(modem->fd, TIOCOUTQ, &n) >= 0)
- prompt_Printf(arg->prompt, " Physical outq: %d\n", n);
-#endif
-
- prompt_Printf(arg->prompt, " Queued Packets: %d\n",
- link_QueueLen(&modem->link));
- prompt_Printf(arg->prompt, " Phone Number: %s\n", arg->cx->phone.chosen);
-
- prompt_Printf(arg->prompt, "\nDefaults:\n");
-
- prompt_Printf(arg->prompt, " Device List: ");
- dev = modem->cfg.devlist;
- for (n = 0; n < modem->cfg.ndev; n++) {
- if (n)
- prompt_Printf(arg->prompt, ", ");
- prompt_Printf(arg->prompt, "\"%s\"", dev);
- dev += strlen(dev) + 1;
- }
-
- prompt_Printf(arg->prompt, "\n Characteristics: ");
- if (physical_IsSync(arg->cx->physical))
- prompt_Printf(arg->prompt, "sync");
- else
- prompt_Printf(arg->prompt, "%dbps", modem->cfg.speed);
-
- switch (modem->cfg.parity & CSIZE) {
- case CS7:
- prompt_Printf(arg->prompt, ", cs7");
- break;
- case CS8:
- prompt_Printf(arg->prompt, ", cs8");
- break;
- }
- if (modem->cfg.parity & PARENB) {
- if (modem->cfg.parity & PARODD)
- prompt_Printf(arg->prompt, ", odd parity");
- else
- prompt_Printf(arg->prompt, ", even parity");
- } else
- prompt_Printf(arg->prompt, ", no parity");
-
- prompt_Printf(arg->prompt, ", CTS/RTS %s\n",
- (modem->cfg.rts_cts ? "on" : "off"));
-
- prompt_Printf(arg->prompt, " CD check delay: %d second%s",
- modem->cfg.cd.delay, modem->cfg.cd.delay == 1 ? "" : "s");
- if (modem->cfg.cd.required)
- prompt_Printf(arg->prompt, " (required!)\n\n");
- else
- prompt_Printf(arg->prompt, "\n\n");
-
- throughput_disp(&modem->link.throughput, arg->prompt);
-
- return 0;
-}
-
-static void
-modem_DescriptorRead(struct descriptor *d, struct bundle *bundle,
- const fd_set *fdset)
-{
- struct physical *p = descriptor2physical(d);
- u_char *rbuff;
- int n, found;
-
- rbuff = p->input.buf + p->input.sz;
-
- /* something to read from modem */
- n = physical_Read(p, rbuff, sizeof p->input.buf - p->input.sz);
- log_Printf(LogDEBUG, "%s: DescriptorRead: read %d/%d from %d\n",
- p->link.name, n, (int)(sizeof p->input.buf - p->input.sz), p->fd);
- if (n <= 0) {
- if (n < 0)
- log_Printf(LogPHASE, "%s: read (%d): %s\n", p->link.name, p->fd,
- strerror(errno));
- else
- log_Printf(LogPHASE, "%s: read (%d): Got zero bytes\n",
- p->link.name, p->fd);
- datalink_Down(p->dl, CLOSE_NORMAL);
- return;
- }
-
- log_DumpBuff(LogASYNC, "ReadFromModem", rbuff, n);
- rbuff -= p->input.sz;
- n += p->input.sz;
-
- if (p->link.lcp.fsm.state <= ST_CLOSED) {
- if (p->type != PHYS_DEDICATED) {
- found = hdlc_Detect((u_char const **)&rbuff, n, physical_IsSync(p));
- if (rbuff != p->input.buf)
- log_WritePrompts(p->dl, "%.*s", (int)(rbuff - p->input.buf),
- p->input.buf);
- p->input.sz = n - (rbuff - p->input.buf);
-
- if (found) {
- /* LCP packet is detected. Turn ourselves into packet mode */
- log_Printf(LogPHASE, "%s: PPP packet detected, coming up\n",
- p->link.name);
- log_SetTtyCommandMode(p->dl);
- datalink_Up(p->dl, 0, 1);
- async_Input(bundle, rbuff, p->input.sz, p);
- p->input.sz = 0;
- } else
- bcopy(rbuff, p->input.buf, p->input.sz);
- } else
- /* In -dedicated mode, we just discard input until LCP is started */
- p->input.sz = 0;
- } else if (n > 0)
- async_Input(bundle, rbuff, n, p);
-}
-
-static int
-modem_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
-{
- return physical_UpdateSet(d, r, w, e, n, 0);
-}
-
-struct physical *
-iov2modem(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, int fd)
-{
- struct physical *p;
- int len;
-
- p = (struct physical *)iov[(*niov)++].iov_base;
- p->link.name = dl->name;
- throughput_init(&p->link.throughput);
- memset(&p->Timer, '\0', sizeof p->Timer);
- memset(p->link.Queue, '\0', sizeof p->link.Queue);
-
- p->desc.UpdateSet = modem_UpdateSet;
- p->desc.IsSet = physical_IsSet;
- p->desc.Read = modem_DescriptorRead;
- p->desc.Write = modem_DescriptorWrite;
- p->type = PHYS_DIRECT;
- p->dl = dl;
- len = strlen(_PATH_DEV);
- p->name.base = strncmp(p->name.full, _PATH_DEV, len) ?
- p->name.full : p->name.full + len;
- p->out = NULL;
- p->connect_count = 1;
-
- p->link.lcp.fsm.bundle = dl->bundle;
- p->link.lcp.fsm.link = &p->link;
- memset(&p->link.lcp.fsm.FsmTimer, '\0', sizeof p->link.lcp.fsm.FsmTimer);
- memset(&p->link.lcp.fsm.OpenTimer, '\0', sizeof p->link.lcp.fsm.OpenTimer);
- memset(&p->link.lcp.fsm.StoppedTimer, '\0',
- sizeof p->link.lcp.fsm.StoppedTimer);
- p->link.lcp.fsm.parent = &dl->fsmp;
- lcp_SetupCallbacks(&p->link.lcp);
-
- p->link.ccp.fsm.bundle = dl->bundle;
- p->link.ccp.fsm.link = &p->link;
- /* Our in.state & out.state are NULL (no link-level ccp yet) */
- memset(&p->link.ccp.fsm.FsmTimer, '\0', sizeof p->link.ccp.fsm.FsmTimer);
- memset(&p->link.ccp.fsm.OpenTimer, '\0', sizeof p->link.ccp.fsm.OpenTimer);
- memset(&p->link.ccp.fsm.StoppedTimer, '\0',
- sizeof p->link.ccp.fsm.StoppedTimer);
- p->link.ccp.fsm.parent = &dl->fsmp;
- ccp_SetupCallbacks(&p->link.ccp);
-
- p->hdlc.lqm.owner = &p->link.lcp;
- p->hdlc.ReportTimer.state = TIMER_STOPPED;
- p->hdlc.lqm.timer.state = TIMER_STOPPED;
-
- p->fd = fd;
-
- if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
- lqr_reStart(&p->link.lcp);
- hdlc_StartTimer(&p->hdlc);
-
- throughput_start(&p->link.throughput, "modem throughput",
- Enabled(dl->bundle, OPT_THROUGHPUT));
- p->input.sz = 0;
- if (p->Timer.state != TIMER_STOPPED) {
- p->Timer.state = TIMER_STOPPED; /* Special - see modem2iov() */
- modem_StartTimer(dl->bundle, p); /* XXX: Should we set cd.required ? */
- }
-
- return p;
-}
-
-int
-modem2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
- pid_t newpid)
-{
- if (p) {
- hdlc_StopTimer(&p->hdlc);
- lqr_StopTimer(p);
- timer_Stop(&p->link.lcp.fsm.FsmTimer);
- timer_Stop(&p->link.ccp.fsm.FsmTimer);
- timer_Stop(&p->link.lcp.fsm.OpenTimer);
- timer_Stop(&p->link.ccp.fsm.OpenTimer);
- timer_Stop(&p->link.lcp.fsm.StoppedTimer);
- timer_Stop(&p->link.ccp.fsm.StoppedTimer);
- if (p->Timer.state != TIMER_STOPPED) {
- timer_Stop(&p->Timer);
- p->Timer.state = TIMER_RUNNING; /* Special - see iov2modem() */
- }
- if (tcgetpgrp(p->fd) == getpgrp())
- p->session_owner = getpid(); /* So I'll eventually get HUP'd */
- timer_Stop(&p->link.throughput.Timer);
- modem_ChangedPid(p, newpid);
- }
-
- if (*niov >= maxiov) {
- log_Printf(LogERROR, "modem2iov: No room for physical !\n");
- if (p)
- free(p);
- return -1;
- }
-
- iov[*niov].iov_base = p ? p : malloc(sizeof *p);
- iov[*niov].iov_len = sizeof *p;
- (*niov)++;
-
- return p ? p->fd : 0;
-}
-
-void
-modem_ChangedPid(struct physical *p, pid_t newpid)
-{
- if (p->fd >= 0 && p->type != PHYS_DIRECT) {
- int res;
-
- if ((res = ID0uu_lock_txfr(p->name.base, newpid)) != UU_LOCK_OK)
- log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
- }
-}
diff --git a/usr.sbin/ppp/modem.h b/usr.sbin/ppp/modem.h
deleted file mode 100644
index 58f54dd..0000000
--- a/usr.sbin/ppp/modem.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
- *
- * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the Internet Initiative Japan. The name of the
- * IIJ may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Id: modem.h,v 1.17 1998/05/21 21:47:02 brian Exp $
- *
- * TODO:
- */
-
-struct iovec;
-struct datalink;
-struct physical;
-struct bundle;
-struct ccp;
-struct cmdargs;
-
-extern int modem_Raw(struct physical *, struct bundle *);
-extern struct physical *modem_Create(struct datalink *, int);
-extern int modem_Open(struct physical *, struct bundle *);
-extern int modem_Speed(struct physical *);
-extern speed_t IntToSpeed(int);
-extern int modem_SetParity(struct physical *, const char *);
-extern int modem_ShowStatus(struct cmdargs const *);
-extern void modem_Close(struct physical *);
-extern void modem_Offline(struct physical *);
-extern void modem_Destroy(struct physical *);
-extern struct physical *iov2modem(struct datalink *, struct iovec *, int *,
- int, int);
-extern int modem2iov(struct physical *, struct iovec *, int *, int, pid_t);
-extern void modem_ChangedPid(struct physical *, pid_t);
diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c
index c2e5515..af5a47c 100644
--- a/usr.sbin/ppp/mp.c
+++ b/usr.sbin/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.17 1998/10/24 01:08:45 brian Exp $
+ * $Id: mp.c,v 1.18 1999/01/28 01:56:33 brian Exp $
*/
#include <sys/param.h>
@@ -44,6 +44,11 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
+#ifndef NOALIAS
+#include "alias_cmd.h"
+#endif
+#include "vjcomp.h"
#include "ua.h"
#include "defs.h"
#include "command.h"
@@ -65,7 +70,7 @@
#include "descriptor.h"
#include "physical.h"
#include "chat.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "filter.h"
#include "mp.h"
#include "chap.h"
@@ -193,7 +198,7 @@ mp_Init(struct mp *mp, struct bundle *bundle)
mp->inbufs = NULL;
mp->bundle = bundle;
- mp->link.type = MP_LINK;
+ mp->link.type = LOGICAL_LINK;
mp->link.name = "mp";
mp->link.len = sizeof *mp;
@@ -218,6 +223,14 @@ mp_Init(struct mp *mp, struct bundle *bundle)
lcp_Init(&mp->link.lcp, mp->bundle, &mp->link, NULL);
ccp_Init(&mp->link.ccp, mp->bundle, &mp->link, &mp->fsmp);
+
+ link_EmptyStack(&mp->link);
+ link_Stack(&mp->link, &protolayer);
+ link_Stack(&mp->link, &ccplayer);
+ link_Stack(&mp->link, &vjlayer);
+#ifndef NOALIAS
+ link_Stack(&mp->link, &aliaslayer);
+#endif
}
int
@@ -323,8 +336,8 @@ mp_linkInit(struct mp_link *mplink)
mplink->weight = 1500;
}
-void
-mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
+static void
+mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p)
{
struct mp_header mh, h;
struct mbuf *q, *last;
@@ -490,7 +503,8 @@ mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
if (log_IsKept(LogDEBUG))
log_Printf(LogDEBUG, "MP: Reassembled frags %ld-%lu, length %d\n",
first, (u_long)h.seq, mbuf_Length(q));
- hdlc_DecodePacket(mp->bundle, proto, q, &mp->link);
+ q = mbuf_Contiguous(q);
+ link_PullPacket(&mp->link, MBUF_CTOP(q), q->cnt, mp->bundle);
}
mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
@@ -521,9 +535,27 @@ mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
}
}
+struct mbuf *
+mp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
+{
+ struct physical *p = link2physical(l);
+
+ if (!bundle->ncp.mp.active)
+ /* Let someone else deal with it ! */
+ return bp;
+
+ if (p == NULL) {
+ log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
+ mbuf_Free(bp);
+ } else
+ mp_Assemble(&bundle->ncp.mp, bp, p);
+
+ return NULL;
+}
+
static void
-mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin,
- u_int32_t end)
+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;
@@ -548,8 +580,7 @@ mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin,
mp->out.seq, mbuf_Length(mo), l->name);
mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq);
- if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, PROTO_MP, mo))
- hdlc_Output(l, PRI_NORMAL, PROTO_MP, mo);
+ link_PushPacket(l, mo, bundle, PRI_NORMAL, PROTO_MP);
}
int
@@ -600,7 +631,7 @@ mp_FillQueues(struct bundle *bundle)
/* this link has got stuff already queued. Let it continue */
continue;
- if (!link_QueueLen(&mp->link) && !ip_FlushPacket(&mp->link, bundle))
+ if (!link_QueueLen(&mp->link) && !ip_PushPacket(&mp->link, bundle))
/* Nothing else to send */
break;
@@ -624,7 +655,7 @@ mp_FillQueues(struct bundle *bundle)
len -= mo->cnt;
m = mbuf_Read(m, MBUF_CTOP(mo), mo->cnt);
}
- mp_Output(mp, &dl->physical->link, mo, begin, end);
+ mp_Output(mp, bundle, &dl->physical->link, mo, begin, end);
begin = 0;
}
@@ -1028,7 +1059,7 @@ mp_LinkLost(struct mp *mp, struct datalink *dl)
{
if (mp->seq.min_in == dl->mp.seq)
/* We've lost the link that's holding everything up ! */
- mp_Input(mp, NULL, NULL);
+ mp_Assemble(mp, NULL, NULL);
}
void
diff --git a/usr.sbin/ppp/mp.h b/usr.sbin/ppp/mp.h
index c421b4b..20794b5 100644
--- a/usr.sbin/ppp/mp.h
+++ b/usr.sbin/ppp/mp.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mp.h,v 1.3 1998/05/23 17:05:28 brian Exp $
+ * $Id: mp.h,v 1.4 1998/08/25 17:48:43 brian Exp $
*/
struct mbuf;
@@ -126,7 +126,7 @@ extern void mp_Init(struct mp *, struct bundle *);
extern void mp_linkInit(struct mp_link *);
extern int mp_Up(struct mp *, struct datalink *);
extern void mp_Down(struct mp *);
-extern void mp_Input(struct mp *, struct mbuf *, struct physical *);
+extern struct mbuf *mp_Input(struct bundle *, struct link *, struct mbuf *);
extern int mp_FillQueues(struct bundle *);
extern int mp_SetDatalinkWeight(struct cmdargs const *);
extern int mp_ShowStatus(struct cmdargs const *);
diff --git a/usr.sbin/ppp/nat_cmd.c b/usr.sbin/ppp/nat_cmd.c
index 66b6db7..d35d492 100644
--- a/usr.sbin/ppp/nat_cmd.c
+++ b/usr.sbin/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.22 1999/03/25 23:36:23 brian Exp $
+ * $Id: alias_cmd.c,v 1.23 1999/04/26 08:54:32 brian Exp $
*/
#include <sys/param.h>
@@ -24,6 +24,8 @@
#else
#include "alias.h"
#endif
+#include "layer.h"
+#include "proto.h"
#include "defs.h"
#include "command.h"
#include "log.h"
@@ -304,3 +306,96 @@ alias_Pptp(struct cmdargs const *arg)
PacketAliasPptp(addr);
return 0;
}
+
+static struct mbuf *
+alias_PadMbuf(struct mbuf *bp, int type)
+{
+ struct mbuf **last;
+ int len;
+
+ 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,
+ int pri, u_short *proto)
+{
+ if (!bundle->AliasEnabled || *proto != PROTO_IP)
+ return bp;
+
+ bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPQ));
+ PacketAliasOut(MBUF_CTOP(bp), bp->cnt);
+ bp->cnt = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len);
+
+ return bp;
+}
+
+static struct mbuf *
+alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ u_short *proto)
+{
+ struct ip *pip, *piip;
+ int ret;
+ struct mbuf **last;
+ char *fptr;
+
+ if (!bundle->AliasEnabled || *proto != PROTO_IP)
+ return bp;
+
+ bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPIN));
+ pip = (struct ip *)MBUF_CTOP(bp);
+ piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
+
+ if (pip->ip_p == IPPROTO_IGMP ||
+ (pip->ip_p == IPPROTO_IPIP && IN_CLASSD(ntohl(piip->ip_dst.s_addr))))
+ return bp;
+
+ ret = PacketAliasIn(MBUF_CTOP(bp), bp->cnt);
+
+ 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);
+ return NULL;
+ }
+
+ switch (ret) {
+ case PKT_ALIAS_OK:
+ break;
+
+ case PKT_ALIAS_UNRESOLVED_FRAGMENT:
+ /* Save the data for later */
+ fptr = malloc(bp->cnt);
+ mbuf_Read(bp, fptr, bp->cnt);
+ 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;
+ while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) {
+ PacketAliasFragmentIn(MBUF_CTOP(bp), fptr);
+ *last = mbuf_Alloc(ntohs(((struct ip *)fptr)->ip_len), MB_IPIN);
+ memcpy(MBUF_CTOP(*last), fptr, (*last)->cnt);
+ free(fptr);
+ last = &(*last)->pnext;
+ }
+ break;
+
+ default:
+ mbuf_Free(bp);
+ bp = NULL;
+ break;
+ }
+
+ return bp;
+}
+
+struct layer aliaslayer =
+ { LAYER_ALIAS, "alias", alias_LayerPush, alias_LayerPull };
diff --git a/usr.sbin/ppp/nat_cmd.h b/usr.sbin/ppp/nat_cmd.h
index cf96bcf..05c0ad0 100644
--- a/usr.sbin/ppp/nat_cmd.h
+++ b/usr.sbin/ppp/nat_cmd.h
@@ -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.h,v 1.9 1999/03/07 15:02:37 brian Exp $
+ * $Id: alias_cmd.h,v 1.10 1999/03/07 18:13:44 brian Exp $
*/
struct cmdargs;
@@ -11,3 +11,5 @@ 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/pap.c b/usr.sbin/ppp/pap.c
index 5b3e17a..d9ada44 100644
--- a/usr.sbin/ppp/pap.c
+++ b/usr.sbin/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.33 1999/03/31 14:21:45 brian Exp $
+ * $Id: pap.c,v 1.34 1999/04/01 11:05:23 brian Exp $
*
* TODO:
*/
@@ -32,6 +32,7 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
@@ -42,7 +43,7 @@
#include "pap.h"
#include "lqr.h"
#include "hdlc.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "async.h"
#include "throughput.h"
#include "ccp.h"
@@ -93,8 +94,7 @@ pap_Req(struct authinfo *authp)
cp += namelen;
*cp++ = keylen;
memcpy(cp, bundle->cfg.auth.key, keylen);
-
- hdlc_Output(&authp->physical->link, PRI_LINK, PROTO_PAP, bp);
+ link_PushPacket(&authp->physical->link, bp, bundle, PRI_LINK, PROTO_PAP);
}
static void
@@ -117,7 +117,8 @@ SendPapCode(struct authinfo *authp, int code, const char *message)
memcpy(cp, message, mlen);
log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]);
- hdlc_Output(&authp->physical->link, PRI_LINK, PROTO_PAP, bp);
+ link_PushPacket(&authp->physical->link, bp, authp->physical->dl->bundle,
+ PRI_LINK, PROTO_PAP);
}
static void
@@ -150,38 +151,45 @@ pap_Init(struct authinfo *pap, struct physical *p)
auth_Init(pap, p, pap_Req, pap_Success, pap_Failure);
}
-void
-pap_Input(struct physical *p, struct mbuf *bp)
+struct mbuf *
+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;
- if (bundle_Phase(p->dl->bundle) != PHASE_NETWORK &&
- bundle_Phase(p->dl->bundle) != PHASE_AUTHENTICATE) {
+ if (p == NULL) {
+ log_Printf(LogERROR, "pap_Input: Not a physical link - dropped\n");
+ mbuf_Free(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);
- return;
+ return NULL;
}
if ((bp = auth_ReadHeader(authp, bp)) == NULL &&
ntohs(authp->in.hdr.length) == 0) {
log_Printf(LogWARN, "Pap Input: Truncated header !\n");
- return;
+ return NULL;
}
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);
- return;
+ return NULL;
}
if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id &&
- Enabled(p->dl->bundle, OPT_IDCHECK)) {
+ Enabled(bundle, OPT_IDCHECK)) {
/* 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);
- return;
+ return NULL;
}
authp->id = authp->in.hdr.id; /* We respond with this id */
@@ -212,12 +220,12 @@ pap_Input(struct physical *p, struct mbuf *bp)
key[klen] = '\0';
#ifndef NORADIUS
- if (*p->dl->bundle->radius.cfg.file)
- radius_Authenticate(&p->dl->bundle->radius, authp, authp->in.name,
+ if (*bundle->radius.cfg.file)
+ radius_Authenticate(&bundle->radius, authp, authp->in.name,
key, NULL);
else
#endif
- if (auth_Validate(p->dl->bundle, authp->in.name, key, p))
+ if (auth_Validate(bundle, authp->in.name, key, p))
pap_Success(authp);
else
pap_Failure(authp);
@@ -246,4 +254,5 @@ pap_Input(struct physical *p, struct mbuf *bp)
}
mbuf_Free(bp);
+ return NULL;
}
diff --git a/usr.sbin/ppp/pap.h b/usr.sbin/ppp/pap.h
index bef8292..9827b4c 100644
--- a/usr.sbin/ppp/pap.h
+++ b/usr.sbin/ppp/pap.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: pap.h,v 1.8 1999/02/02 09:35:17 brian Exp $
+ * $Id: pap.h,v 1.9 1999/02/06 02:54:47 brian Exp $
*
* TODO:
*/
@@ -29,4 +29,4 @@ struct physical;
struct authinfo;
extern void pap_Init(struct authinfo *, struct physical *);
-extern void pap_Input(struct physical *, struct mbuf *);
+extern struct mbuf *pap_Input(struct bundle *, struct link *, struct mbuf *);
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index 48a2770..31ed65e 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -16,51 +16,593 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: physical.c,v 1.7 1999/01/10 01:26:29 brian Exp $
+ * $Id: physical.c,v 1.8 1999/04/27 00:23: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>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#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>
-#include <sys/tty.h>
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+#include <sys/ioctl.h>
+#include <util.h>
+#else
+#include <libutil.h>
+#endif
+#include "layer.h"
+#ifndef NOALIAS
+#include "alias_cmd.h"
+#endif
+#include "proto.h"
+#include "acf.h"
+#include "vjcomp.h"
#include "defs.h"
+#include "command.h"
#include "mbuf.h"
+#include "log.h"
+#include "id.h"
#include "timer.h"
+#include "fsm.h"
#include "lqr.h"
#include "hdlc.h"
-#include "throughput.h"
-#include "fsm.h"
#include "lcp.h"
+#include "throughput.h"
+#include "sync.h"
#include "async.h"
+#include "iplist.h"
+#include "slcompress.h"
+#include "ipcp.h"
+#include "filter.h"
+#include "descriptor.h"
#include "ccp.h"
#include "link.h"
-#include "descriptor.h"
#include "physical.h"
-#include "log.h"
-#include "id.h"
+#include "mp.h"
+#ifndef NORADIUS
+#include "radius.h"
+#endif
+#include "bundle.h"
+#include "prompt.h"
+#include "chat.h"
+#include "auth.h"
+#include "chap.h"
+#include "cbcp.h"
+#include "datalink.h"
+#include "tcp.h"
+#include "exec.h"
+#include "tty.h"
+
+
+static int physical_DescriptorWrite(struct descriptor *, struct bundle *,
+ const fd_set *);
+static void physical_DescriptorRead(struct descriptor *, struct bundle *,
+ const fd_set *);
+
+static const struct device *handlers[] = {
+ &ttydevice, &tcpdevice, &execdevice
+};
+
+#define NHANDLERS (sizeof handlers / sizeof handlers[0])
+
+static int
+physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
+ int *n)
+{
+ return physical_doUpdateSet(d, r, w, e, n, 0);
+}
+
+struct physical *
+physical_Create(struct datalink *dl, int type)
+{
+ struct physical *p;
+
+ p = (struct physical *)malloc(sizeof(struct physical));
+ if (!p)
+ return NULL;
+
+ p->link.type = PHYSICAL_LINK;
+ p->link.name = dl->name;
+ p->link.len = sizeof *p;
+ throughput_init(&p->link.throughput);
+
+ memset(p->link.Queue, '\0', sizeof p->link.Queue);
+ memset(p->link.proto_in, '\0', sizeof p->link.proto_in);
+ memset(p->link.proto_out, '\0', sizeof p->link.proto_out);
+ link_EmptyStack(&p->link);
+
+ memset(&p->Timer, '\0', sizeof p->Timer);
+ 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;
+ p->type = type;
-/* External calls - should possibly be moved inline */
-extern int IntToSpeed(int);
+ hdlc_Init(&p->hdlc, &p->link.lcp);
+ async_Init(&p->async);
+
+ p->fd = -1;
+ p->out = NULL;
+ p->connect_count = 0;
+ p->dl = dl;
+ p->input.sz = 0;
+ *p->name.full = '\0';
+ p->name.base = p->name.full;
+
+ p->Utmp = 0;
+ p->session_owner = (pid_t)-1;
+
+ p->cfg.rts_cts = MODEM_CTSRTS;
+ p->cfg.speed = MODEM_SPEED;
+ 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;
+
+ lcp_Init(&p->link.lcp, dl->bundle, &p->link, &dl->fsmp);
+ ccp_Init(&p->link.ccp, dl->bundle, &p->link, &dl->fsmp);
+
+ return p;
+}
+
+static const struct parity {
+ const char *name;
+ const char *name1;
+ int set;
+} validparity[] = {
+ { "even", "P_EVEN", CS7 | PARENB },
+ { "odd", "P_ODD", CS7 | PARENB | PARODD },
+ { "none", "P_ZERO", CS8 },
+ { NULL, 0 },
+};
+
+static int
+GetParityValue(const char *str)
+{
+ const struct parity *pp;
+
+ for (pp = validparity; pp->name; pp++) {
+ if (strcasecmp(pp->name, str) == 0 ||
+ strcasecmp(pp->name1, str) == 0) {
+ return pp->set;
+ }
+ }
+ return (-1);
+}
+
+int
+physical_SetParity(struct physical *p, const char *str)
+{
+ struct termios rstio;
+ int val;
+
+ val = GetParityValue(str);
+ if (val > 0) {
+ p->cfg.parity = val;
+ if (p->fd >= 0) {
+ tcgetattr(p->fd, &rstio);
+ rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
+ rstio.c_cflag |= val;
+ tcsetattr(p->fd, TCSADRAIN, &rstio);
+ }
+ return 0;
+ }
+ log_Printf(LogWARN, "%s: %s: Invalid parity\n", p->link.name, str);
+ return -1;
+}
+
+int
+physical_GetSpeed(struct physical *p)
+{
+ if (p->handler && p->handler->speed)
+ return (*p->handler->speed)(p);
+ return 115200;
+}
int
-physical_GetFD(struct physical *phys) {
- return phys->fd;
+physical_SetSpeed(struct physical *p, int speed)
+{
+ if (IntToSpeed(speed) != B0) {
+ p->cfg.speed = speed;
+ return 1;
+ }
+
+ return 0;
}
int
-physical_IsSync(struct physical *phys) {
- return phys->cfg.speed == 0;
+physical_Raw(struct physical *p)
+{
+ if (p->handler && p->handler->raw)
+ return (*p->handler->raw)(p);
+
+ return 1;
}
-const char *physical_GetDevice(struct physical *phys)
+void
+physical_Offline(struct physical *p)
{
- return phys->name.full;
+ if (p->handler && p->handler->offline)
+ (*p->handler->offline)(p);
+ log_Printf(LogPHASE, "%s: Disconnected!\n", p->link.name);
+}
+
+static void
+physical_ReallyClose(struct physical *p)
+{
+ int newsid;
+
+ log_Printf(LogDEBUG, "%s: Really close %d\n", p->link.name, p->fd);
+ if (p->fd >= 0) {
+ timer_Stop(&p->Timer);
+ if (p->Utmp) {
+ ID0logout(p->name.base);
+ p->Utmp = 0;
+ }
+ newsid = tcgetpgrp(p->fd) == getpgrp();
+ close(p->fd);
+ p->fd = -1;
+ log_SetTtyCommandMode(p->dl);
+ throughput_stop(&p->link.throughput);
+ throughput_log(&p->link.throughput, LogPHASE, p->link.name);
+ if (p->session_owner != (pid_t)-1) {
+ ID0kill(p->session_owner, SIGHUP);
+ p->session_owner = (pid_t)-1;
+ }
+ if (newsid)
+ bundle_setsid(p->dl->bundle, 0);
+ if (p->handler && p->handler->postclose)
+ (*p->handler->postclose)(p);
+ p->handler = NULL;
+ }
+ *p->name.full = '\0';
+ p->name.base = p->name.full;
+}
+
+void
+physical_Close(struct physical *p)
+{
+ if (p->fd < 0)
+ return;
+
+ log_Printf(LogDEBUG, "%s: Close\n", p->link.name);
+
+ if (p->handler && p->handler->cooked)
+ (*p->handler->cooked)(p);
+
+ physical_ReallyClose(p);
+}
+
+void
+physical_Destroy(struct physical *p)
+{
+ physical_Close(p);
+ free(p);
+}
+
+static int
+physical_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
+ const fd_set *fdset)
+{
+ struct physical *p = descriptor2physical(d);
+ int nw, result = 0;
+
+ if (p->out == NULL)
+ p->out = link_Dequeue(&p->link);
+
+ if (p->out) {
+ nw = physical_Write(p, MBUF_CTOP(p->out), p->out->cnt);
+ log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%d) to %d\n",
+ p->link.name, nw, p->out->cnt, p->fd);
+ if (nw > 0) {
+ p->out->cnt -= nw;
+ p->out->offset += nw;
+ if (p->out->cnt == 0)
+ p->out = mbuf_FreeSeg(p->out);
+ result = 1;
+ } else if (nw < 0) {
+ if (errno != EAGAIN) {
+ log_Printf(LogPHASE, "%s: write (%d): %s\n", p->link.name,
+ p->fd, strerror(errno));
+ datalink_Down(p->dl, CLOSE_NORMAL);
+ }
+ result = 1;
+ }
+ /* else we shouldn't really have been called ! select() is broken ! */
+ }
+
+ return result;
+}
+
+int
+physical_ShowStatus(struct cmdargs const *arg)
+{
+ struct physical *p = arg->cx->physical;
+ const char *dev;
+ int n;
+
+ prompt_Printf(arg->prompt, "Name: %s\n", p->link.name);
+ prompt_Printf(arg->prompt, " State: ");
+ if (p->fd < 0)
+ prompt_Printf(arg->prompt, "closed\n");
+ else if (p->handler && p->handler->openinfo)
+ prompt_Printf(arg->prompt, "open (%s)\n", (*p->handler->openinfo)(p));
+ else
+ prompt_Printf(arg->prompt, "open\n");
+
+ prompt_Printf(arg->prompt, " Device: %s",
+ *p->name.full ? p->name.full :
+ p->type == PHYS_DIRECT ? "unknown" : "N/A");
+ if (p->session_owner != (pid_t)-1)
+ prompt_Printf(arg->prompt, " (session owner: %d)", (int)p->session_owner);
+
+ prompt_Printf(arg->prompt, "\n Link Type: %s\n", mode2Nam(p->type));
+ prompt_Printf(arg->prompt, " Connect Count: %d\n", p->connect_count);
+#ifdef TIOCOUTQ
+ if (p->fd >= 0 && ioctl(p->fd, TIOCOUTQ, &n) >= 0)
+ 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, " Phone Number: %s\n", arg->cx->phone.chosen);
+
+ prompt_Printf(arg->prompt, "\nDefaults:\n");
+
+ prompt_Printf(arg->prompt, " Device List: ");
+ dev = p->cfg.devlist;
+ for (n = 0; n < p->cfg.ndev; n++) {
+ if (n)
+ prompt_Printf(arg->prompt, ", ");
+ prompt_Printf(arg->prompt, "\"%s\"", dev);
+ dev += strlen(dev) + 1;
+ }
+
+ prompt_Printf(arg->prompt, "\n Characteristics: ");
+ if (physical_IsSync(arg->cx->physical))
+ prompt_Printf(arg->prompt, "sync");
+ else
+ prompt_Printf(arg->prompt, "%dbps", p->cfg.speed);
+
+ switch (p->cfg.parity & CSIZE) {
+ case CS7:
+ prompt_Printf(arg->prompt, ", cs7");
+ break;
+ case CS8:
+ prompt_Printf(arg->prompt, ", cs8");
+ break;
+ }
+ if (p->cfg.parity & PARENB) {
+ if (p->cfg.parity & PARODD)
+ prompt_Printf(arg->prompt, ", odd parity");
+ else
+ prompt_Printf(arg->prompt, ", even parity");
+ } else
+ prompt_Printf(arg->prompt, ", no parity");
+
+ 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");
+
+ throughput_disp(&p->link.throughput, arg->prompt);
+
+ return 0;
+}
+
+static void
+physical_DescriptorRead(struct descriptor *d, struct bundle *bundle,
+ const fd_set *fdset)
+{
+ struct physical *p = descriptor2physical(d);
+ u_char *rbuff;
+ int n, found;
+
+ rbuff = p->input.buf + p->input.sz;
+
+ /* something to read */
+ n = physical_Read(p, rbuff, sizeof p->input.buf - p->input.sz);
+ log_Printf(LogDEBUG, "%s: DescriptorRead: read %d/%d from %d\n",
+ p->link.name, n, (int)(sizeof p->input.buf - p->input.sz), p->fd);
+ if (n <= 0) {
+ if (n < 0)
+ log_Printf(LogPHASE, "%s: read (%d): %s\n", p->link.name, p->fd,
+ strerror(errno));
+ else
+ log_Printf(LogPHASE, "%s: read (%d): Got zero bytes\n",
+ p->link.name, p->fd);
+ datalink_Down(p->dl, CLOSE_NORMAL);
+ return;
+ }
+
+ log_DumpBuff(LogASYNC, "ReadFromModem", rbuff, n);
+ rbuff -= p->input.sz;
+ n += p->input.sz;
+
+ if (p->link.lcp.fsm.state <= ST_CLOSED) {
+ if (p->type != PHYS_DEDICATED) {
+ found = hdlc_Detect((u_char const **)&rbuff, n, physical_IsSync(p));
+ if (rbuff != p->input.buf)
+ log_WritePrompts(p->dl, "%.*s", (int)(rbuff - p->input.buf),
+ p->input.buf);
+ p->input.sz = n - (rbuff - p->input.buf);
+
+ if (found) {
+ /* LCP packet is detected. Turn ourselves into packet mode */
+ log_Printf(LogPHASE, "%s: PPP packet detected, coming up\n",
+ p->link.name);
+ log_SetTtyCommandMode(p->dl);
+ datalink_Up(p->dl, 0, 1);
+ link_PullPacket(&p->link, rbuff, p->input.sz, bundle);
+ p->input.sz = 0;
+ } else
+ bcopy(rbuff, p->input.buf, p->input.sz);
+ } else
+ /* In -dedicated mode, we just discard input until LCP is started */
+ p->input.sz = 0;
+ } else if (n > 0)
+ link_PullPacket(&p->link, rbuff, n, bundle);
+}
+
+struct physical *
+iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
+ int fd)
+{
+ struct physical *p;
+ int len, h;
+
+ p = (struct physical *)iov[(*niov)++].iov_base;
+ p->link.name = dl->name;
+ throughput_init(&p->link.throughput);
+ memset(&p->Timer, '\0', sizeof p->Timer);
+ memset(p->link.Queue, '\0', sizeof p->link.Queue);
+
+ p->desc.UpdateSet = physical_UpdateSet;
+ p->desc.IsSet = physical_IsSet;
+ p->desc.Read = physical_DescriptorRead;
+ p->desc.Write = physical_DescriptorWrite;
+ p->type = PHYS_DIRECT;
+ p->dl = dl;
+ len = strlen(_PATH_DEV);
+ p->name.base = strncmp(p->name.full, _PATH_DEV, len) ?
+ p->name.full : p->name.full + len;
+ p->out = NULL;
+ p->connect_count = 1;
+
+ if (p->handler) {
+ for (h = 0; h < NHANDLERS; h++)
+ if (p->handler == (const struct device *)(long)handlers[h]->type) {
+ p->handler = handlers[h];
+ break;
+ }
+ if (h == NHANDLERS) {
+ log_Printf(LogERROR, "iov2physical: Can't find device hander !\n");
+ p->handler = NULL;
+ }
+ }
+
+ p->link.lcp.fsm.bundle = dl->bundle;
+ p->link.lcp.fsm.link = &p->link;
+ memset(&p->link.lcp.fsm.FsmTimer, '\0', sizeof p->link.lcp.fsm.FsmTimer);
+ memset(&p->link.lcp.fsm.OpenTimer, '\0', sizeof p->link.lcp.fsm.OpenTimer);
+ memset(&p->link.lcp.fsm.StoppedTimer, '\0',
+ sizeof p->link.lcp.fsm.StoppedTimer);
+ p->link.lcp.fsm.parent = &dl->fsmp;
+ lcp_SetupCallbacks(&p->link.lcp);
+
+ p->link.ccp.fsm.bundle = dl->bundle;
+ p->link.ccp.fsm.link = &p->link;
+ /* Our in.state & out.state are NULL (no link-level ccp yet) */
+ memset(&p->link.ccp.fsm.FsmTimer, '\0', sizeof p->link.ccp.fsm.FsmTimer);
+ memset(&p->link.ccp.fsm.OpenTimer, '\0', sizeof p->link.ccp.fsm.OpenTimer);
+ memset(&p->link.ccp.fsm.StoppedTimer, '\0',
+ sizeof p->link.ccp.fsm.StoppedTimer);
+ p->link.ccp.fsm.parent = &dl->fsmp;
+ ccp_SetupCallbacks(&p->link.ccp);
+
+ p->hdlc.lqm.owner = &p->link.lcp;
+ p->hdlc.ReportTimer.state = TIMER_STOPPED;
+ p->hdlc.lqm.timer.state = TIMER_STOPPED;
+
+ p->fd = fd;
+
+ if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
+ lqr_reStart(&p->link.lcp);
+ hdlc_StartTimer(&p->hdlc);
+
+ throughput_start(&p->link.throughput, "physical throughput",
+ Enabled(dl->bundle, OPT_THROUGHPUT));
+ if (p->handler && p->handler->restored)
+ (*p->handler->restored)(p);
+
+ return p;
+}
+
+int
+physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
+ pid_t newpid)
+{
+ if (p) {
+ hdlc_StopTimer(&p->hdlc);
+ lqr_StopTimer(p);
+ timer_Stop(&p->link.lcp.fsm.FsmTimer);
+ timer_Stop(&p->link.ccp.fsm.FsmTimer);
+ timer_Stop(&p->link.lcp.fsm.OpenTimer);
+ timer_Stop(&p->link.ccp.fsm.OpenTimer);
+ timer_Stop(&p->link.lcp.fsm.StoppedTimer);
+ timer_Stop(&p->link.ccp.fsm.StoppedTimer);
+ if (p->handler)
+ p->handler = (const struct device *)(long)p->handler->type;
+ if (p->Timer.state != TIMER_STOPPED) {
+ timer_Stop(&p->Timer);
+ p->Timer.state = TIMER_RUNNING; /* Special - see iov2physical() */
+ }
+ if (tcgetpgrp(p->fd) == getpgrp())
+ p->session_owner = getpid(); /* So I'll eventually get HUP'd */
+ timer_Stop(&p->link.throughput.Timer);
+ physical_ChangedPid(p, newpid);
+ }
+
+ if (*niov >= maxiov) {
+ log_Printf(LogERROR, "physical2iov: No room for physical !\n");
+ if (p)
+ free(p);
+ return -1;
+ }
+
+ iov[*niov].iov_base = p ? p : malloc(sizeof *p);
+ iov[*niov].iov_len = sizeof *p;
+ (*niov)++;
+
+ return p ? p->fd : 0;
+}
+
+void
+physical_ChangedPid(struct physical *p, pid_t newpid)
+{
+ if (p->fd >= 0 && p->type != PHYS_DIRECT) {
+ int res;
+
+ if ((res = ID0uu_lock_txfr(p->name.base, newpid)) != UU_LOCK_OK)
+ log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
+ }
+}
+
+int
+physical_IsSync(struct physical *p)
+{
+ return p->cfg.speed == 0;
+}
+
+const char *physical_GetDevice(struct physical *p)
+{
+ return p->name.full;
}
void
@@ -78,44 +620,36 @@ physical_SetDeviceList(struct physical *p, int argc, const char *const *argv)
p->cfg.ndev = f;
}
-
-int
-physical_SetSpeed(struct physical *phys, int speed) {
- if (IntToSpeed(speed) != B0) {
- phys->cfg.speed = speed;
- return 1;
- } else {
- return 0;
- }
-}
-
void
-physical_SetSync(struct physical *phys) {
- phys->cfg.speed = 0;
+physical_SetSync(struct physical *p)
+{
+ p->cfg.speed = 0;
}
-
int
-physical_SetRtsCts(struct physical *phys, int enable) {
- phys->cfg.rts_cts = enable ? 1 : 0;
+physical_SetRtsCts(struct physical *p, int enable)
+{
+ p->cfg.rts_cts = enable ? 1 : 0;
return 1;
}
/* Encapsulation for a read on the FD. Avoids some exposure, and
concentrates control. */
ssize_t
-physical_Read(struct physical *phys, void *buf, size_t nbytes) {
- return read(phys->fd, buf, nbytes);
+physical_Read(struct physical *p, void *buf, size_t nbytes)
+{
+ return read(p->fd, buf, nbytes);
}
ssize_t
-physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
- return write(phys->fd, buf, nbytes);
+physical_Write(struct physical *p, const void *buf, size_t nbytes)
+{
+ return write(p->fd, buf, nbytes);
}
int
-physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
- int *n, int force)
+physical_doUpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
+ int *n, int force)
{
struct physical *p = descriptor2physical(d);
int sets;
@@ -179,34 +713,21 @@ physical_IsSet(struct descriptor *d, const fd_set *fdset)
}
void
-physical_Login(struct physical *phys, const char *name)
-{
- if (phys->type == PHYS_DIRECT && phys->isatty) {
- if (phys->Utmp)
- log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base);
- else {
- struct utmp ut;
- const char *connstr;
-
- memset(&ut, 0, sizeof ut);
- time(&ut.ut_time);
- strncpy(ut.ut_name, name, sizeof ut.ut_name);
- strncpy(ut.ut_line, phys->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);
- phys->Utmp = 1;
- }
- }
-}
-
-void
-physical_Logout(struct physical *phys)
+physical_Login(struct physical *p, const char *name)
{
- if (phys->Utmp) {
- ID0logout(phys->name.base);
- phys->Utmp = 0;
+ if (p->type == PHYS_DIRECT && !p->Utmp) {
+ struct utmp ut;
+ const char *connstr;
+
+ 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 ((connstr = getenv("CONNECT")))
+ /* mgetty sets this to the connection speed */
+ strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
+ ID0login(&ut);
+ p->Utmp = 1;
}
}
@@ -233,3 +754,94 @@ physical_DeleteQueue(struct physical *p)
}
link_DeleteQueue(&p->link);
}
+
+void
+physical_SetDevice(struct physical *p, const char *name)
+{
+ int len = strlen(_PATH_DEV);
+
+ strncpy(p->name.full, name, sizeof p->name.full - 1);
+ p->name.full[sizeof p->name.full - 1] = '\0';
+ p->name.base = *p->name.full == '!' ? p->name.full + 1 :
+ strncmp(p->name.full, _PATH_DEV, len) ?
+ p->name.full : p->name.full + len;
+}
+
+static void
+physical_Found(struct physical *p)
+{
+ throughput_start(&p->link.throughput, "physical throughput",
+ Enabled(p->dl->bundle, OPT_THROUGHPUT));
+ p->connect_count++;
+ p->input.sz = 0;
+
+ log_Printf(LogPHASE, "%s: Connected!\n", p->link.name);
+}
+
+int
+physical_Open(struct physical *p, struct bundle *bundle)
+{
+ int devno, h;
+ char *dev;
+
+ if (p->fd >= 0)
+ log_Printf(LogDEBUG, "%s: Open: Modem is already open!\n", p->link.name);
+ /* We're going back into "term" mode */
+ else if (p->type == PHYS_DIRECT) {
+ if (tty_OpenStdin(p)) {
+ physical_Found(p);
+ p->handler = &ttydevice;
+ } else {
+ log_Printf(LogDEBUG, "%s: physical_Open: stdin is not a tty\n",
+ p->link.name);
+ physical_SetDevice(p, "");
+ physical_SetupStack(p, 0);
+ physical_Found(p);
+ return p->fd = STDIN_FILENO;
+ }
+ } else {
+ dev = p->cfg.devlist;
+ devno = 0;
+ while (devno < p->cfg.ndev && p->fd < 0) {
+ physical_SetDevice(p, dev);
+
+ for (h = 0; h < NHANDLERS; h++)
+ if (handlers[h]->open && (*handlers[h]->open)(p)) {
+ p->handler = handlers[h];
+ physical_Found(p);
+ }
+
+ if (p->fd < 0)
+ log_Printf(LogWARN, "%s: Device (%s) must begin with a '/',"
+ " a '!' or be a host:port pair\n", p->link.name,
+ p->name.full);
+ dev += strlen(dev) + 1;
+ devno++;
+ }
+ }
+
+ return p->fd;
+}
+
+void
+physical_SetupStack(struct physical *p, int forceasync)
+{
+ link_EmptyStack(&p->link);
+ if (!forceasync && physical_IsSync(p))
+ link_Stack(&p->link, &synclayer);
+ else {
+ link_Stack(&p->link, &asynclayer);
+ link_Stack(&p->link, &hdlclayer);
+ }
+ 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);
+#endif
+ if (forceasync && physical_IsSync(p))
+ log_Printf(LogWARN, "Sync device setting ignored for ``%s'' device\n",
+ p->handler ? p->handler->name : "unknown");
+}
diff --git a/usr.sbin/ppp/physical.h b/usr.sbin/ppp/physical.h
index b6f95bb..bad8926 100644
--- a/usr.sbin/ppp/physical.h
+++ b/usr.sbin/ppp/physical.h
@@ -16,11 +16,34 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: physical.h,v 1.7 1999/04/03 11:54:00 brian Exp $
+ * $Id: physical.h,v 1.8 1999/04/27 00:23:57 brian Exp $
*
*/
+struct datalink;
struct bundle;
+struct iovec;
+struct physical;
+struct bundle;
+struct ccp;
+struct cmdargs;
+
+#define TTY_DEVICE 1
+#define TCP_DEVICE 2
+#define EXEC_DEVICE 3
+
+struct device {
+ int type;
+ const char *name;
+ int (*open)(struct physical *);
+ int (*raw)(struct physical *);
+ void (*offline)(struct physical *);
+ void (*cooked)(struct physical *);
+ void (*postclose)(struct physical *);
+ void (*restored)(struct physical *);
+ int (*speed)(struct physical *);
+ const char *(*openinfo)(struct physical *);
+};
struct physical {
struct link link;
@@ -30,7 +53,6 @@ struct physical {
struct hdlc hdlc; /* Our hdlc state */
int fd; /* File descriptor for this device */
int mbits; /* Current DCD status */
- unsigned isatty : 1;
struct mbuf *out; /* mbuf that suffered a short write */
int connect_count;
struct datalink *dl; /* my owner */
@@ -41,20 +63,18 @@ struct physical {
} input;
struct {
- char full[40];
+ char full[40]; /* Our current device name */
char *base;
} name;
unsigned Utmp : 1; /* Are we in utmp ? */
pid_t session_owner; /* HUP this when closing the link */
- /* XXX-ML Most of the below is device specific, and probably do not
- belong in the generic physical struct. It comes from modem.c. */
-
struct {
- unsigned rts_cts : 1; /* Is rts/cts enabled? */
- unsigned parity; /* What parity is enabled? (TTY flags) */
- unsigned speed; /* Modem speed */
+ unsigned rts_cts : 1; /* Is rts/cts enabled ? */
+ unsigned parity; /* What parity is enabled? (tty flags) */
+ unsigned speed; /* tty speed */
+
char devlist[LINE_LEN]; /* NUL separated list of devices */
int ndev; /* number of devices in list */
struct {
@@ -66,6 +86,8 @@ struct physical {
struct termios ios; /* To be able to reset from raw mode */
struct pppTimer Timer; /* CD checks */
+
+ const struct device *handler; /* device specific handlers */
};
#define field2phys(fp, name) \
@@ -77,32 +99,36 @@ struct physical {
#define descriptor2physical(d) \
((d)->type == PHYSICAL_DESCRIPTOR ? field2phys(d, desc) : NULL)
-extern int physical_GetFD(struct physical *);
-extern int physical_IsSync(struct physical *);
-extern const char *physical_GetDevice(struct physical *);
-extern void physical_SetDeviceList(struct physical *, int, const char *const *);
+extern struct physical *physical_Create(struct datalink *, int);
+extern int physical_Open(struct physical *, struct bundle *);
+extern int physical_Raw(struct physical *);
+extern int physical_GetSpeed(struct physical *);
extern int physical_SetSpeed(struct physical *, int);
-
-/*
- * XXX-ML I'm not certain this is the right way to handle this, but we
- * can solve that later.
- */
+extern int physical_SetParity(struct physical *, const char *);
+extern int physical_SetRtsCts(struct physical *, int);
extern void physical_SetSync(struct physical *);
+extern int physical_ShowStatus(struct cmdargs const *);
+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);
+extern void physical_ChangedPid(struct physical *, pid_t);
-/*
- * Can this be set? (Might not be a relevant attribute for this
- * device, for instance)
- */
-extern int physical_SetRtsCts(struct physical *, int);
+extern int physical_IsSync(struct physical *);
+extern const char *physical_GetDevice(struct physical *);
+extern void physical_SetDeviceList(struct physical *, int, const char *const *);
+extern void physical_SetDevice(struct physical *, const char *);
extern ssize_t physical_Read(struct physical *, void *, size_t);
extern ssize_t physical_Write(struct physical *, const void *, size_t);
-extern int physical_UpdateSet(struct descriptor *, fd_set *, fd_set *,
- fd_set *, int *, int);
+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_Login(struct physical *, const char *);
-extern void physical_Logout(struct physical *);
extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *,
fd_set *);
extern int physical_SetMode(struct physical *, int);
extern void physical_DeleteQueue(struct physical *);
+extern void physical_SetupStack(struct physical *, int);
diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8
index 05c20bf..eff30c2 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp.8
@@ -1,4 +1,4 @@
-.\" $Id: ppp.8,v 1.165 1999/04/23 13:45:50 brian Exp $
+.\" $Id: ppp.8,v 1.166 1999/05/02 08:52:50 brian Exp $
.Dd 20 September 1995
.nr XX \w'\fC00'
.Os FreeBSD
@@ -40,8 +40,8 @@ also be optionally password protected for security.
.It Supports both manual and automatic dialing.
Interactive mode has a
.Dq term
-command which enables you to talk to your modem directly. When your
-modem is connected to the remote peer and it starts to talk
+command which enables you to talk to the device directly. When you
+are connected to the remote peer and it starts to talk
.Em PPP ,
.Nm
detects it and switches to packet mode automatically. Once you have
@@ -490,9 +490,9 @@ on even parity when logging in:
ppp ON awfulhak> set parity even
.Ed
.Pp
-You can now see what your current modem settings look like:
+You can now see what your current device settings look like:
.Bd -literal -offset indent
-ppp ON awfulhak> show modem
+ppp ON awfulhak> show physical
Name: deflink
State: closed
Device: N/A
@@ -511,7 +511,7 @@ Overall 0 bytes/sec
ppp ON awfulhak>
.Ed
.Pp
-The term command can now be used to talk directly to your modem:
+The term command can now be used to talk directly to the device:
.Bd -literal -offset indent
ppp ON awfulhak> term
at
@@ -590,7 +590,7 @@ to help you.
When the link is established, the show command can be used to see how
things are going:
.Bd -literal -offset indent
-PPP ON awfulhak> show modem
+PPP ON awfulhak> show physical
* Modem related information is shown here *
PPP ON awfulhak> show ccp
* CCP (compression) related information is shown here *
@@ -2527,7 +2527,7 @@ layer shuts down, and is also available using the
command. Throughput statistics are available at the
.Dq IPCP
and
-.Dq modem
+.Dq physical
levels.
.It utmp
Default: Enabled. Normally, when a user is authenticated using PAP or
@@ -2863,13 +2863,13 @@ If you wish to pause
while the command executes, use the
.Dq shell
command instead.
-.It clear modem|ipcp Op current|overall|peak...
+.It clear physical|ipcp Op current|overall|peak...
Clear the specified throughput values at either the
-.Dq modem
+.Dq physical
or
.Dq ipcp
level. If
-.Dq modem
+.Dq physical
is specified, context must be given (see the
.Dq link
command below). If no second argument is given, all values are
@@ -2956,7 +2956,7 @@ are terminated). If
.Sq lcp
is specified, the
.Em LCP
-layer is terminated but the modem is not brought offline and the link
+layer is terminated but the device is not brought offline and the link
is not closed. If
.Sq ccp
is specified, only the relevant compression layer(s) are terminated.
@@ -3587,7 +3587,7 @@ To do this, the first character of the expect or send string is an
exclamation mark
.Pq Dq \&! .
When the command is executed, standard input and standard output are
-directed to the modem device (see the
+directed to the open device (see the
.Dq set device
command), and standard error is read by
.Nm
@@ -3750,7 +3750,7 @@ section on
.Sx PACKET FILTERING
above for further details.
.It set hangup Ar chat-script
-This specifies the chat script that will be used to reset the modem
+This specifies the chat script that will be used to reset the device
before it is closed. It should not normally be necessary, but can
be used for devices that fail to reset themselves properly on close.
.It set help|? Op Ar command
@@ -4351,7 +4351,7 @@ Show a list of available logical links.
Show the current log values.
.It show mem
Show current memory statistics.
-.It show modem
+.It show physical
Show low level link information.
.It show mp
Show Multi-link information.
@@ -4370,10 +4370,10 @@ Show the current version number of
.Pp
.It term
Go into terminal mode. Characters typed at the keyboard are sent to
-the modem. Characters read from the modem are displayed on the
-screen. When a
-.Nm
-peer is detected on the other side of the modem,
+the device. Characters read from the device are displayed on the
+screen. When a remote
+.Em PPP
+peer is detected,
.Nm
automatically enables Packet Mode and goes back into command mode.
.El
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index 05c20bf..eff30c2 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -1,4 +1,4 @@
-.\" $Id: ppp.8,v 1.165 1999/04/23 13:45:50 brian Exp $
+.\" $Id: ppp.8,v 1.166 1999/05/02 08:52:50 brian Exp $
.Dd 20 September 1995
.nr XX \w'\fC00'
.Os FreeBSD
@@ -40,8 +40,8 @@ also be optionally password protected for security.
.It Supports both manual and automatic dialing.
Interactive mode has a
.Dq term
-command which enables you to talk to your modem directly. When your
-modem is connected to the remote peer and it starts to talk
+command which enables you to talk to the device directly. When you
+are connected to the remote peer and it starts to talk
.Em PPP ,
.Nm
detects it and switches to packet mode automatically. Once you have
@@ -490,9 +490,9 @@ on even parity when logging in:
ppp ON awfulhak> set parity even
.Ed
.Pp
-You can now see what your current modem settings look like:
+You can now see what your current device settings look like:
.Bd -literal -offset indent
-ppp ON awfulhak> show modem
+ppp ON awfulhak> show physical
Name: deflink
State: closed
Device: N/A
@@ -511,7 +511,7 @@ Overall 0 bytes/sec
ppp ON awfulhak>
.Ed
.Pp
-The term command can now be used to talk directly to your modem:
+The term command can now be used to talk directly to the device:
.Bd -literal -offset indent
ppp ON awfulhak> term
at
@@ -590,7 +590,7 @@ to help you.
When the link is established, the show command can be used to see how
things are going:
.Bd -literal -offset indent
-PPP ON awfulhak> show modem
+PPP ON awfulhak> show physical
* Modem related information is shown here *
PPP ON awfulhak> show ccp
* CCP (compression) related information is shown here *
@@ -2527,7 +2527,7 @@ layer shuts down, and is also available using the
command. Throughput statistics are available at the
.Dq IPCP
and
-.Dq modem
+.Dq physical
levels.
.It utmp
Default: Enabled. Normally, when a user is authenticated using PAP or
@@ -2863,13 +2863,13 @@ If you wish to pause
while the command executes, use the
.Dq shell
command instead.
-.It clear modem|ipcp Op current|overall|peak...
+.It clear physical|ipcp Op current|overall|peak...
Clear the specified throughput values at either the
-.Dq modem
+.Dq physical
or
.Dq ipcp
level. If
-.Dq modem
+.Dq physical
is specified, context must be given (see the
.Dq link
command below). If no second argument is given, all values are
@@ -2956,7 +2956,7 @@ are terminated). If
.Sq lcp
is specified, the
.Em LCP
-layer is terminated but the modem is not brought offline and the link
+layer is terminated but the device is not brought offline and the link
is not closed. If
.Sq ccp
is specified, only the relevant compression layer(s) are terminated.
@@ -3587,7 +3587,7 @@ To do this, the first character of the expect or send string is an
exclamation mark
.Pq Dq \&! .
When the command is executed, standard input and standard output are
-directed to the modem device (see the
+directed to the open device (see the
.Dq set device
command), and standard error is read by
.Nm
@@ -3750,7 +3750,7 @@ section on
.Sx PACKET FILTERING
above for further details.
.It set hangup Ar chat-script
-This specifies the chat script that will be used to reset the modem
+This specifies the chat script that will be used to reset the device
before it is closed. It should not normally be necessary, but can
be used for devices that fail to reset themselves properly on close.
.It set help|? Op Ar command
@@ -4351,7 +4351,7 @@ Show a list of available logical links.
Show the current log values.
.It show mem
Show current memory statistics.
-.It show modem
+.It show physical
Show low level link information.
.It show mp
Show Multi-link information.
@@ -4370,10 +4370,10 @@ Show the current version number of
.Pp
.It term
Go into terminal mode. Characters typed at the keyboard are sent to
-the modem. Characters read from the modem are displayed on the
-screen. When a
-.Nm
-peer is detected on the other side of the modem,
+the device. Characters read from the device are displayed on the
+screen. When a remote
+.Em PPP
+peer is detected,
.Nm
automatically enables Packet Mode and goes back into command mode.
.El
diff --git a/usr.sbin/ppp/pred.c b/usr.sbin/ppp/pred.c
index 1919a8e..7e233b9 100644
--- a/usr.sbin/ppp/pred.c
+++ b/usr.sbin/ppp/pred.c
@@ -26,15 +26,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pred.c,v 1.23 1999/03/11 01:49:15 brian Exp $
+ * $Id: pred.c,v 1.24 1999/03/16 01:24:23 brian Exp $
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include "defs.h"
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
@@ -166,8 +168,8 @@ Pred1InitOutput(struct lcp_opt *o)
return state;
}
-static int
-Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
+static struct mbuf *
+Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
struct mbuf *bp)
{
struct pred1_state *state = (struct pred1_state *)v;
@@ -183,10 +185,10 @@ Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
cp = bufp;
*wp++ = *cp++ = orglen >> 8;
*wp++ = *cp++ = orglen & 0377;
- *cp++ = proto >> 8;
- *cp++ = proto & 0377;
+ *cp++ = *proto >> 8;
+ *cp++ = *proto & 0377;
mbuf_Read(bp, cp, orglen - 2);
- fcs = hdlc_Fcs(INITFCS, bufp, 2 + orglen);
+ fcs = hdlc_Fcs(bufp, 2 + orglen);
fcs = ~fcs;
len = compress(state, bufp + 2, wp, orglen);
@@ -205,8 +207,8 @@ 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);
- hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mwp);
- return 1;
+ *proto = ccp_Proto(ccp);
+ return mwp;
}
static struct mbuf *
@@ -255,7 +257,7 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp)
}
*pp++ = *cp++; /* CRC */
*pp++ = *cp++;
- fcs = hdlc_Fcs(INITFCS, bufp, wp->cnt = pp - bufp);
+ fcs = hdlc_Fcs(bufp, wp->cnt = pp - bufp);
if (fcs == GOODFCS) {
wp->offset += 2; /* skip length */
wp->cnt -= 4; /* skip length & CRC */
diff --git a/usr.sbin/ppp/prompt.c b/usr.sbin/ppp/prompt.c
index 1cd5f7b..38ebcd5 100644
--- a/usr.sbin/ppp/prompt.c
+++ b/usr.sbin/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.13 1999/01/28 01:56:34 brian Exp $
+ * $Id: prompt.c,v 1.14 1999/04/03 11:54:00 brian Exp $
*/
#include <sys/param.h>
@@ -41,6 +41,7 @@
#include <termios.h>
#include <unistd.h>
+#include "layer.h"
#include "defs.h"
#include "timer.h"
#include "command.h"
diff --git a/usr.sbin/ppp/proto.c b/usr.sbin/ppp/proto.c
new file mode 100644
index 0000000..7ef2d47
--- /dev/null
+++ b/usr.sbin/ppp/proto.c
@@ -0,0 +1,110 @@
+/*-
+ * 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:$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <termios.h>
+
+#include "layer.h"
+#include "acf.h"
+#include "defs.h"
+#include "timer.h"
+#include "fsm.h"
+#include "mbuf.h"
+#include "proto.h"
+#include "lcp.h"
+#include "throughput.h"
+#include "lqr.h"
+#include "hdlc.h"
+#include "ccp.h"
+#include "link.h"
+
+int
+proto_WrapperOctets(struct lcp *lcp, u_short proto)
+{
+ return (lcp->his_protocomp && !(proto & 0xff00)) ? 1 : 2;
+}
+
+struct mbuf *
+proto_Prepend(struct mbuf *bp, u_short proto, unsigned comp, int extra)
+{
+ u_char cp[2];
+
+ cp[0] = proto >> 8;
+ cp[1] = proto & 0xff;
+
+ if (comp && cp[0] == 0)
+ bp = mbuf_Prepend(bp, cp + 1, 1, extra);
+ else
+ bp = mbuf_Prepend(bp, cp, 2, extra);
+
+ return bp;
+}
+
+static struct mbuf *
+proto_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ bp = proto_Prepend(bp, *proto, l->lcp.his_protocomp,
+ acf_WrapperOctets(&l->lcp, *proto));
+ link_ProtocolRecord(l, *proto, PROTO_OUT);
+
+ return bp;
+}
+
+static struct mbuf *
+proto_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
+ u_short *proto)
+{
+ u_char cp[2];
+ size_t got;
+
+ if ((got = mbuf_View(bp, cp, 2)) == 0) {
+ mbuf_Free(bp);
+ return NULL;
+ }
+
+ *proto = cp[0];
+ if (!(*proto & 1)) {
+ if (got == 1) {
+ mbuf_Free(bp);
+ return NULL;
+ }
+ bp = mbuf_Read(bp, cp, 2);
+ *proto = (*proto << 8) | cp[1];
+ } else
+ bp = mbuf_Read(bp, cp, 1);
+
+ link_ProtocolRecord(l, *proto, PROTO_IN);
+
+ return bp;
+}
+
+struct layer protolayer =
+ { LAYER_PROTO, "proto", proto_LayerPush, proto_LayerPull };
diff --git a/usr.sbin/ppp/lcpproto.h b/usr.sbin/ppp/proto.h
index 8434822..d982411 100644
--- a/usr.sbin/ppp/lcpproto.h
+++ b/usr.sbin/ppp/proto.h
@@ -15,9 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lcpproto.h,v 1.11 1998/05/21 21:46:05 brian Exp $
- *
- * TODO:
+ * $Id:$
*/
/*
@@ -41,3 +39,10 @@
#define PROTO_CBCP 0xc029
#define PROTO_LQR 0xc025
#define PROTO_CHAP 0xc223
+
+struct lcp;
+
+extern int proto_WrapperOctets(struct lcp *, u_short);
+struct mbuf *proto_Prepend(struct mbuf *, u_short, unsigned, int);
+
+extern struct layer protolayer;
diff --git a/usr.sbin/ppp/radius.c b/usr.sbin/ppp/radius.c
index 3da276d..6e86e95 100644
--- a/usr.sbin/ppp/radius.c
+++ b/usr.sbin/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/03/03 23:00:41 brian Exp $
+ * $Id: radius.c,v 1.5 1999/04/21 08:13:09 brian Exp $
*
*/
@@ -42,6 +42,7 @@
#include <sys/time.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "log.h"
#include "descriptor.h"
diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c
index 5b366d2..a20ec2a 100644
--- a/usr.sbin/ppp/route.c
+++ b/usr.sbin/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.54 1998/10/22 02:32:50 brian Exp $
+ * $Id: route.c,v 1.55 1999/01/28 01:56:34 brian Exp $
*
*/
@@ -40,6 +40,7 @@
#include <sys/sysctl.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
diff --git a/usr.sbin/ppp/slcompress.c b/usr.sbin/ppp/slcompress.c
index 881006f..4a237da 100644
--- a/usr.sbin/ppp/slcompress.c
+++ b/usr.sbin/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.23 1999/03/31 13:33:43 brian Exp $
+ * $Id: slcompress.c,v 1.24 1999/03/31 13:44:07 brian Exp $
*
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
* - Initial distribution.
@@ -34,6 +34,7 @@
#include <string.h>
#include <termios.h>
+#include "layer.h"
#include "defs.h"
#include "command.h"
#include "mbuf.h"
@@ -459,9 +460,8 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp,
* Make sure the state index is in range, then grab the state. If we have
* a good state index, clear the 'discard' flag.
*/
- if (*cp > max_state || comp->last_recv == 255) {
+ if (*cp > max_state || comp->last_recv == 255)
goto bad;
- }
comp->flags &= ~SLF_TOSS;
comp->last_recv = *cp++;
@@ -478,8 +478,6 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp,
}
cs = &comp->rstate[comp->last_recv];
hlen = cs->cs_ip.ip_hl << 2;
- if (hlen == 0)
- goto bad; /* We've been pointed at a not-yet-used slot ! */
th = (struct tcphdr *) & ((u_char *) & cs->cs_ip)[hlen];
th->th_sum = htons((*cp << 8) | cp[1]);
cp += 2;
diff --git a/usr.sbin/ppp/sync.c b/usr.sbin/ppp/sync.c
new file mode 100644
index 0000000..155978a
--- /dev/null
+++ b/usr.sbin/ppp/sync.c
@@ -0,0 +1,68 @@
+/*-
+ * 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:$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <termios.h>
+
+#include "layer.h"
+#include "defs.h"
+#include "mbuf.h"
+#include "log.h"
+#include "sync.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"
+
+static struct mbuf *
+sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
+ u_short *proto)
+{
+ struct physical *p = link2physical(l);
+
+ if (!p)
+ log_Printf(LogERROR, "Can't Pull a sync packet from a logical link\n");
+ else {
+ /* Normally done by the HDLC layer */
+ p->hdlc.lqm.SaveInOctets += mbuf_Length(bp) + 1;
+ p->hdlc.lqm.SaveInPackets++;
+ }
+
+ return bp;
+}
+
+struct layer synclayer = { LAYER_SYNC, "sync", NULL, sync_LayerPull };
diff --git a/usr.sbin/ppp/sync.h b/usr.sbin/ppp/sync.h
new file mode 100644
index 0000000..334555d
--- /dev/null
+++ b/usr.sbin/ppp/sync.h
@@ -0,0 +1,29 @@
+/*-
+ * 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:$
+ */
+
+extern struct layer synclayer;
diff --git a/usr.sbin/ppp/systems.c b/usr.sbin/ppp/systems.c
index 0e26711..1b3b07b 100644
--- a/usr.sbin/ppp/systems.c
+++ b/usr.sbin/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.41 1999/02/02 09:35:30 brian Exp $
+ * $Id: systems.c,v 1.42 1999/03/09 20:39:03 brian Exp $
*
* TODO:
*/
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
#include "defs.h"
diff --git a/usr.sbin/ppp/tcp.c b/usr.sbin/ppp/tcp.c
new file mode 100644
index 0000000..187462a
--- /dev/null
+++ b/usr.sbin/ppp/tcp.c
@@ -0,0 +1,134 @@
+/*-
+ * 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:$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "layer.h"
+#include "defs.h"
+#include "mbuf.h"
+#include "log.h"
+#include "sync.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 "tcp.h"
+
+static int
+OpenConnection(const char *name, char *host, char *port)
+{
+ struct sockaddr_in dest;
+ int sock;
+ struct servent *sp;
+
+ dest.sin_family = AF_INET;
+ dest.sin_addr.s_addr = inet_addr(host);
+ dest.sin_addr = GetIpAddr(host);
+ if (dest.sin_addr.s_addr == INADDR_NONE) {
+ log_Printf(LogWARN, "%s: %s: unknown host\n", name, host);
+ return (-1);
+ }
+ dest.sin_port = htons(atoi(port));
+ if (dest.sin_port == 0) {
+ sp = getservbyname(port, "tcp");
+ if (sp) {
+ dest.sin_port = sp->s_port;
+ } else {
+ log_Printf(LogWARN, "%s: %s: unknown service\n", name, port);
+ return (-1);
+ }
+ }
+ log_Printf(LogPHASE, "%s: Connecting to %s:%s\n", name, host, port);
+
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ return (sock);
+ }
+ if (connect(sock, (struct sockaddr *)&dest, sizeof dest) < 0) {
+ log_Printf(LogWARN, "%s: connect: %s\n", name, strerror(errno));
+ close(sock);
+ return (-1);
+ }
+ return (sock);
+}
+
+static int
+tcp_Open(struct physical *p)
+{
+ char *cp, *host, *port;
+
+ if ((cp = strchr(p->name.full, ':')) != NULL) {
+ *cp = '\0';
+ host = p->name.full;
+ port = cp + 1;
+ if (*host && *port) {
+ p->fd = OpenConnection(p->link.name, host, port);
+ *cp = ':'; /* Don't destroy name.full */
+ if (p->fd >= 0) {
+ log_Printf(LogDEBUG, "%s: Opened socket %s\n", p->link.name,
+ p->name.full);
+ physical_SetupStack(p, 1);
+ return 1;
+ }
+ } else
+ *cp = ':'; /* Don't destroy name.full */
+ }
+
+ return 0;
+}
+
+const struct device tcpdevice = {
+ TTY_DEVICE,
+ "tcp",
+ tcp_Open,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/usr.sbin/ppp/tcp.h b/usr.sbin/ppp/tcp.h
new file mode 100644
index 0000000..9780b06
--- /dev/null
+++ b/usr.sbin/ppp/tcp.h
@@ -0,0 +1,29 @@
+/*-
+ * 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:$
+ */
+
+extern const struct device tcpdevice;
diff --git a/usr.sbin/ppp/throughput.c b/usr.sbin/ppp/throughput.c
index 6773f2e..de9d20f 100644
--- a/usr.sbin/ppp/throughput.c
+++ b/usr.sbin/ppp/throughput.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: throughput.c,v 1.7 1998/06/12 17:45:41 brian Exp $
+ * $Id: throughput.c,v 1.8 1998/06/12 20:12:26 brian Exp $
*/
#include <sys/types.h>
@@ -65,16 +65,16 @@ throughput_disp(struct pppThroughput *t, struct prompt *prompt)
prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
if (secs_up == 0)
secs_up = 1;
- prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
+ prompt_Printf(prompt, "%qu octets in, %qu octets out\n",
t->OctetsIn, t->OctetsOut);
if (t->rolling) {
- prompt_Printf(prompt, " overall %5ld bytes/sec\n",
+ prompt_Printf(prompt, " overall %6qu bytes/sec\n",
(t->OctetsIn+t->OctetsOut)/secs_up);
- prompt_Printf(prompt, " currently %5d bytes/sec\n", t->OctetsPerSecond);
- prompt_Printf(prompt, " peak %5d bytes/sec on %s",
+ prompt_Printf(prompt, " currently %6qu bytes/sec\n", t->OctetsPerSecond);
+ prompt_Printf(prompt, " peak %6qu bytes/sec on %s",
t->BestOctetsPerSecond, ctime(&t->BestOctetsPerSecondTime));
} else
- prompt_Printf(prompt, "Overall %ld bytes/sec\n",
+ prompt_Printf(prompt, "Overall %qu bytes/sec\n",
(t->OctetsIn+t->OctetsOut)/secs_up);
}
@@ -87,19 +87,19 @@ throughput_log(struct pppThroughput *t, int level, const char *title)
secs_up = t->uptime ? time(NULL) - t->uptime : 0;
if (title)
- log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
+ log_Printf(level, "%s: Connect time: %d secs: %qu octets in, %qu octets"
" out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
else
- log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
+ log_Printf(level, "Connect time: %d secs: %qu octets in, %qu octets out\n",
secs_up, t->OctetsIn, t->OctetsOut);
if (secs_up == 0)
secs_up = 1;
if (t->rolling)
- log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec on %s",
+ log_Printf(level, " total %qu bytes/sec, peak %qu bytes/sec on %s",
(t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond,
ctime(&t->BestOctetsPerSecondTime));
else
- log_Printf(level, " total %ld bytes/sec\n",
+ log_Printf(level, " total %qu bytes/sec\n",
(t->OctetsIn+t->OctetsOut)/secs_up);
}
}
@@ -108,7 +108,7 @@ static void
throughput_sampler(void *v)
{
struct pppThroughput *t = (struct pppThroughput *)v;
- u_long old;
+ unsigned long long old;
timer_Stop(&t->Timer);
@@ -148,13 +148,13 @@ throughput_stop(struct pppThroughput *t)
}
void
-throughput_addin(struct pppThroughput *t, int n)
+throughput_addin(struct pppThroughput *t, long long n)
{
t->OctetsIn += n;
}
void
-throughput_addout(struct pppThroughput *t, int n)
+throughput_addout(struct pppThroughput *t, long long n)
{
t->OctetsOut += n;
}
@@ -174,14 +174,14 @@ throughput_clear(struct pppThroughput *t, int clear_type, struct prompt *prompt)
int secs_up;
secs_up = t->uptime ? time(NULL) - t->uptime : 1;
- prompt_Printf(prompt, "overall cleared (was %5ld bytes/sec)\n",
+ prompt_Printf(prompt, "overall cleared (was %6qu bytes/sec)\n",
(t->OctetsIn + t->OctetsOut)/secs_up);
t->OctetsIn = t->OctetsOut = 0;
t->uptime = time(NULL);
}
if (clear_type & THROUGHPUT_CURRENT) {
- prompt_Printf(prompt, "current cleared (was %5d bytes/sec)\n",
+ prompt_Printf(prompt, "current cleared (was %6qu bytes/sec)\n",
t->OctetsPerSecond);
t->OctetsPerSecond = 0;
}
@@ -193,7 +193,7 @@ throughput_clear(struct pppThroughput *t, int clear_type, struct prompt *prompt)
last = time_buf + strlen(time_buf);
if (last > time_buf && *--last == '\n')
*last = '\0';
- prompt_Printf(prompt, "peak cleared (was %5d bytes/sec on %s)\n",
+ prompt_Printf(prompt, "peak cleared (was %6qu bytes/sec on %s)\n",
t->BestOctetsPerSecond, time_buf);
t->BestOctetsPerSecond = 0;
t->BestOctetsPerSecondTime = time(NULL);
diff --git a/usr.sbin/ppp/throughput.h b/usr.sbin/ppp/throughput.h
index bdeac1e..85003f5 100644
--- a/usr.sbin/ppp/throughput.h
+++ b/usr.sbin/ppp/throughput.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: throughput.h,v 1.4 1998/06/09 18:49:10 brian Exp $
+ * $Id: throughput.h,v 1.5 1998/06/12 20:12:26 brian Exp $
*/
#define SAMPLE_PERIOD 5
@@ -36,11 +36,11 @@
struct pppThroughput {
time_t uptime;
- u_long OctetsIn;
- u_long OctetsOut;
- u_long SampleOctets[SAMPLE_PERIOD];
- int OctetsPerSecond;
- int BestOctetsPerSecond;
+ unsigned long long OctetsIn;
+ unsigned long long OctetsOut;
+ unsigned long long SampleOctets[SAMPLE_PERIOD];
+ unsigned long long OctetsPerSecond;
+ unsigned long long BestOctetsPerSecond;
time_t BestOctetsPerSecondTime;
int nSample;
unsigned rolling : 1;
@@ -52,6 +52,6 @@ extern void throughput_disp(struct pppThroughput *, struct prompt *);
extern void throughput_log(struct pppThroughput *, int, const char *);
extern void throughput_start(struct pppThroughput *, const char *, int);
extern void throughput_stop(struct pppThroughput *);
-extern void throughput_addin(struct pppThroughput *, int);
-extern void throughput_addout(struct pppThroughput *, int);
+extern void throughput_addin(struct pppThroughput *, long long);
+extern void throughput_addout(struct pppThroughput *, long long);
extern void throughput_clear(struct pppThroughput *, int, struct prompt *);
diff --git a/usr.sbin/ppp/tty.c b/usr.sbin/ppp/tty.c
new file mode 100644
index 0000000..54cc6bc
--- /dev/null
+++ b/usr.sbin/ppp/tty.c
@@ -0,0 +1,446 @@
+/*-
+ * 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:$
+ */
+
+#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 <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "layer.h"
+#include "defs.h"
+#include "mbuf.h"
+#include "log.h"
+#include "id.h"
+#include "sync.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 "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 "tty.h"
+
+#define Online(p) ((p)->mbits & TIOCM_CD)
+
+static int
+tty_Lock(struct physical *p, int tunno)
+{
+ int res;
+ FILE *lockfile;
+ char fn[MAXPATHLEN];
+
+ if (*p->name.full != '/')
+ return 0;
+
+ if (p->type != PHYS_DIRECT &&
+ (res = ID0uu_lock(p->name.base)) != UU_LOCK_OK) {
+ if (res == UU_LOCK_INUSE)
+ log_Printf(LogPHASE, "%s: %s is in use\n", p->link.name, p->name.full);
+ else
+ log_Printf(LogPHASE, "%s: %s is in use: uu_lock: %s\n",
+ p->link.name, p->name.full, uu_lockerr(res));
+ return (-1);
+ }
+
+ snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base);
+ lockfile = ID0fopen(fn, "w");
+ if (lockfile != NULL) {
+ fprintf(lockfile, "%s%d\n", TUN_NAME, tunno);
+ fclose(lockfile);
+ }
+#ifndef RELEASE_CRUNCH
+ else
+ log_Printf(LogALERT, "%s: Can't create %s: %s\n",
+ p->link.name, fn, strerror(errno));
+#endif
+
+ return 0;
+}
+
+static void
+tty_Unlock(struct physical *p)
+{
+ char fn[MAXPATHLEN];
+
+ if (*p->name.full != '/')
+ return;
+
+ snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base);
+#ifndef RELEASE_CRUNCH
+ if (ID0unlink(fn) == -1)
+ log_Printf(LogALERT, "%s: Can't remove %s: %s\n",
+ p->link.name, fn, strerror(errno));
+#else
+ ID0unlink(fn);
+#endif
+
+ if (p->type != PHYS_DIRECT && ID0uu_unlock(p->name.base) == -1)
+ log_Printf(LogALERT, "%s: Can't uu_unlock %s\n", p->link.name, fn);
+}
+
+static void
+tty_SetupDevice(struct physical *p)
+{
+ struct termios rstio;
+ int oldflag;
+
+ tcgetattr(p->fd, &rstio);
+ p->ios = rstio;
+
+ log_Printf(LogDEBUG, "%s: tty_SetupDevice: physical (get): fd = %d,"
+ " iflag = %lx, oflag = %lx, cflag = %lx\n", p->link.name, p->fd,
+ (u_long)rstio.c_iflag, (u_long)rstio.c_oflag,
+ (u_long)rstio.c_cflag);
+
+ cfmakeraw(&rstio);
+ if (p->cfg.rts_cts)
+ rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
+ else {
+ rstio.c_cflag |= CLOCAL;
+ rstio.c_iflag |= IXOFF;
+ }
+ rstio.c_iflag |= IXON;
+ if (p->type != PHYS_DEDICATED)
+ rstio.c_cflag |= HUPCL;
+
+ if (p->type != PHYS_DIRECT) {
+ /* Change tty speed when we're not in -direct mode */
+ rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
+ rstio.c_cflag |= p->cfg.parity;
+ if (cfsetspeed(&rstio, IntToSpeed(p->cfg.speed)) == -1)
+ log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
+ p->link.name, p->name.full, p->cfg.speed);
+ }
+ tcsetattr(p->fd, TCSADRAIN, &rstio);
+ log_Printf(LogDEBUG, "%s: physical (put): iflag = %lx, oflag = %lx, "
+ "cflag = %lx\n", p->link.name, (u_long)rstio.c_iflag,
+ (u_long)rstio.c_oflag, (u_long)rstio.c_cflag);
+
+ if (ioctl(p->fd, TIOCMGET, &p->mbits) == -1) {
+ if (p->type != PHYS_DIRECT) {
+ log_Printf(LogWARN, "%s: Open: Cannot get physical status: %s\n",
+ p->link.name, strerror(errno));
+ physical_Close(p);
+ return;
+ } else
+ p->mbits = TIOCM_CD;
+ }
+ log_Printf(LogDEBUG, "%s: Open: physical control = %o\n",
+ p->link.name, p->mbits);
+
+ oldflag = fcntl(p->fd, F_GETFL, 0);
+ if (oldflag < 0) {
+ log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n",
+ p->link.name, strerror(errno));
+ physical_Close(p);
+ return;
+ } else
+ fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
+
+ physical_SetupStack(p, 0);
+}
+
+static int
+tty_Open(struct physical *p)
+{
+ if (*p->name.full == '/') {
+ p->mbits = 0;
+ if (tty_Lock(p, p->dl->bundle->unit) != -1) {
+ p->fd = ID0open(p->name.full, O_RDWR | O_NONBLOCK);
+ if (p->fd < 0) {
+ log_Printf(LogPHASE, "%s: Open(\"%s\"): %s\n",
+ p->link.name, p->name.full, strerror(errno));
+ tty_Unlock(p);
+ } else if (!isatty(p->fd)) {
+ log_Printf(LogPHASE, "%s: Open(\"%s\"): Not a tty\n",
+ p->link.name, p->name.full);
+ close(p->fd);
+ p->fd = -1;
+ tty_Unlock(p);
+ } else {
+ log_Printf(LogDEBUG, "%s: Opened %s\n", p->link.name, p->name.full);
+ tty_SetupDevice(p);
+ }
+ }
+ }
+
+ return p->fd >= 0;
+}
+
+int
+tty_OpenStdin(struct physical *p)
+{
+ if (isatty(STDIN_FILENO)) {
+ p->mbits = 0;
+ log_Printf(LogDEBUG, "%s: tty_Open: stdin is a tty\n", p->link.name);
+ physical_SetDevice(p, ttyname(STDIN_FILENO));
+ if (tty_Lock(p, p->dl->bundle->unit) == -1)
+ close(STDIN_FILENO);
+ else {
+ p->fd = STDIN_FILENO;
+ tty_SetupDevice(p);
+ }
+ }
+
+ return p->fd >= 0;
+}
+
+/*
+ * tty_Timeout() watches the DCD signal and mentions it if it's status
+ * changes.
+ */
+static void
+tty_Timeout(void *data)
+{
+ struct physical *p = data;
+ int ombits, change;
+
+ timer_Stop(&p->Timer);
+ p->Timer.load = SECTICKS; /* Once a second please */
+ timer_Start(&p->Timer);
+ ombits = p->mbits;
+
+ if (p->fd >= 0) {
+ if (ioctl(p->fd, TIOCMGET, &p->mbits) < 0) {
+ log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
+ strerror(errno));
+ datalink_Down(p->dl, CLOSE_NORMAL);
+ timer_Stop(&p->Timer);
+ return;
+ }
+ } else
+ p->mbits = 0;
+
+ if (ombits == -1) {
+ /* First time looking for carrier */
+ if (Online(p))
+ 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);
+ timer_Stop(&p->Timer);
+ p->mbits = TIOCM_CD;
+ }
+ } else {
+ change = ombits ^ p->mbits;
+ if (change & TIOCM_CD) {
+ if (p->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(&p->Timer);
+ }
+ } else
+ log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
+ Online(p) ? "on" : "off");
+ }
+}
+
+static void
+tty_StartTimer(struct physical *p)
+{
+ timer_Stop(&p->Timer);
+ p->Timer.load = SECTICKS * p->cfg.cd.delay;
+ p->Timer.func = tty_Timeout;
+ p->Timer.name = "tty CD";
+ p->Timer.arg = p;
+ log_Printf(LogDEBUG, "%s: Using tty_Timeout [%p]\n",
+ p->link.name, tty_Timeout);
+ p->mbits = -1; /* So we know it's the first time */
+ timer_Start(&p->Timer);
+}
+
+static int
+tty_Raw(struct physical *p)
+{
+ struct termios rstio;
+ int oldflag;
+
+ if (physical_IsSync(p))
+ return 1;
+
+ log_Printf(LogDEBUG, "%s: Entering physical_Raw\n", p->link.name);
+
+ if (p->type != PHYS_DIRECT && p->fd >= 0 && !Online(p))
+ log_Printf(LogDEBUG, "%s: Raw: descriptor = %d, mbits = %x\n",
+ p->link.name, p->fd, p->mbits);
+
+ tcgetattr(p->fd, &rstio);
+ cfmakeraw(&rstio);
+ if (p->cfg.rts_cts)
+ rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
+ else
+ rstio.c_cflag |= CLOCAL;
+
+ if (p->type != PHYS_DEDICATED)
+ rstio.c_cflag |= HUPCL;
+
+ tcsetattr(p->fd, TCSANOW, &rstio);
+
+ 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, &p->mbits) == 0)
+ tty_StartTimer(p);
+
+ return 1;
+}
+
+static void
+tty_Offline(struct physical *p)
+{
+ if (p->fd >= 0) {
+ timer_Stop(&p->Timer);
+ p->mbits &= ~TIOCM_DTR;
+ if (Online(p)) {
+ struct termios tio;
+
+ tcgetattr(p->fd, &tio);
+ if (cfsetspeed(&tio, B0) == -1)
+ log_Printf(LogWARN, "%s: Unable to set physical to speed 0\n",
+ p->link.name);
+ else
+ tcsetattr(p->fd, TCSANOW, &tio);
+ }
+ }
+}
+
+static void
+tty_Cooked(struct physical *p)
+{
+ int oldflag;
+
+ tcflush(p->fd, TCIOFLUSH);
+ if (!physical_IsSync(p)) {
+ tcsetattr(p->fd, TCSAFLUSH, &p->ios);
+ oldflag = fcntl(p->fd, F_GETFL, 0);
+ if (oldflag == 0)
+ fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
+ }
+}
+
+static void
+tty_Close(struct physical *p)
+{
+ tty_Unlock(p);
+}
+
+static void
+tty_Restored(struct physical *p)
+{
+ if (p->Timer.state != TIMER_STOPPED) {
+ p->Timer.state = TIMER_STOPPED; /* Special - see physical2iov() */
+ tty_StartTimer(p);
+ }
+}
+
+static int
+tty_Speed(struct physical *p)
+{
+ struct termios rstio;
+
+ if (tcgetattr(p->fd, &rstio) == -1)
+ return 0;
+
+ return SpeedToInt(cfgetispeed(&rstio));
+}
+
+static const char *
+tty_OpenInfo(struct physical *p)
+{
+ static char buf[13];
+
+ if (Online(p))
+ strcpy(buf, "with");
+ else
+ strcpy(buf, "no");
+ strcat(buf, " carrier");
+ return buf;
+}
+
+const struct device ttydevice = {
+ TTY_DEVICE,
+ "tty",
+ tty_Open,
+ tty_Raw,
+ tty_Offline,
+ tty_Cooked,
+ tty_Close,
+ tty_Restored,
+ tty_Speed,
+ tty_OpenInfo
+};
diff --git a/usr.sbin/ppp/tty.h b/usr.sbin/ppp/tty.h
new file mode 100644
index 0000000..b651cd7
--- /dev/null
+++ b/usr.sbin/ppp/tty.h
@@ -0,0 +1,33 @@
+/*-
+ * 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:$
+ */
+
+struct physical;
+
+extern int tty_OpenStdin(struct physical *);
+
+extern const struct device ttydevice;
diff --git a/usr.sbin/ppp/tun.c b/usr.sbin/ppp/tun.c
index 90a3665..179c8b2 100644
--- a/usr.sbin/ppp/tun.c
+++ b/usr.sbin/ppp/tun.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: tun.c,v 1.12 1999/04/26 08:54:25 brian Exp $
+ * $Id: tun.c,v 1.13 1999/04/26 08:54:34 brian Exp $
*/
#include <sys/param.h>
@@ -39,11 +39,13 @@
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
+#include <termios.h>
#ifdef __NetBSD__
#include <stdio.h>
#include <unistd.h>
#endif
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
diff --git a/usr.sbin/ppp/vjcomp.c b/usr.sbin/ppp/vjcomp.c
index 269ff95..48a82d6 100644
--- a/usr.sbin/ppp/vjcomp.c
+++ b/usr.sbin/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.26 1999/03/29 08:21:28 brian Exp $
+ * $Id: vjcomp.c,v 1.27 1999/03/31 14:21:46 brian Exp $
*
* TODO:
*/
@@ -29,12 +29,14 @@
#include <stdio.h>
#include <string.h>
+#include <termios.h>
+#include "layer.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
#include "fsm.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "slcompress.h"
#include "lqr.h"
#include "hdlc.h"
@@ -56,43 +58,44 @@
#define MAX_VJHEADER 16 /* Maximum size of compressed header */
-void
-vj_SendFrame(struct link *l, struct mbuf * bp, struct bundle *bundle)
+static struct mbuf *
+vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri,
+ u_short *proto)
{
int type;
- u_short proto;
struct ip *pip;
u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16;
- log_Printf(LogDEBUG, "vj_SendFrame: COMPPROTO = %x\n",
+ log_Printf(LogDEBUG, "vj_LayerWrite: COMPPROTO = %x\n",
bundle->ncp.ipcp.peer_compproto);
bp = mbuf_Contiguous(bp);
pip = (struct ip *)MBUF_CTOP(bp);
- if (pip->ip_p == IPPROTO_TCP && cproto == PROTO_VJCOMP) {
+ if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP &&
+ cproto == PROTO_VJCOMP) {
type = sl_compress_tcp(bp, pip, &bundle->ncp.ipcp.vj.cslc,
&bundle->ncp.ipcp.vj.slstat,
bundle->ncp.ipcp.peer_compproto & 0xff);
- log_Printf(LogDEBUG, "vj_SendFrame: type = %x\n", type);
+ log_Printf(LogDEBUG, "vj_LayerWrite: type = %x\n", type);
switch (type) {
case TYPE_IP:
- proto = PROTO_IP;
break;
+
case TYPE_UNCOMPRESSED_TCP:
- proto = PROTO_VJUNCOMP;
+ *proto = PROTO_VJUNCOMP;
break;
+
case TYPE_COMPRESSED_TCP:
- proto = PROTO_VJCOMP;
+ *proto = PROTO_VJCOMP;
break;
+
default:
- log_Printf(LogALERT, "Unknown frame type %x\n", type);
+ log_Printf(LogERROR, "Unknown frame type %x\n", type);
mbuf_Free(bp);
- return;
+ return NULL;
}
- } else
- proto = PROTO_IP;
+ }
- if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, proto, bp))
- hdlc_Output(l, PRI_NORMAL, proto, bp);
+ return bp;
}
static struct mbuf *
@@ -106,7 +109,6 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
bp = mbuf_Contiguous(bp);
olen = len = mbuf_Length(bp);
if (type == TYPE_UNCOMPRESSED_TCP) {
-
/*
* Uncompressed packet does NOT change its size, so that we can use mbuf
* space for uncompression job.
@@ -118,7 +120,7 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
mbuf_Free(bp);
bp = NULL;
}
- return (bp);
+ return bp;
}
/*
@@ -142,18 +144,19 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
nbp = mbuf_Alloc(len, MB_VJCOMP);
memcpy(MBUF_CTOP(nbp), bufp, len);
nbp->next = bp;
- return (nbp);
+ return nbp;
}
-struct mbuf *
-vj_Input(struct ipcp *ipcp, struct mbuf *bp, int proto)
+static struct mbuf *
+vj_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ u_short *proto)
{
u_char type;
- log_Printf(LogDEBUG, "vj_Input: proto %02x\n", proto);
+ log_Printf(LogDEBUG, "vj_LayerPull: proto %02x\n", *proto);
log_DumpBp(LogDEBUG, "Raw packet info:", bp);
- switch (proto) {
+ switch (*proto) {
case PROTO_VJCOMP:
type = TYPE_COMPRESSED_TCP;
break;
@@ -161,11 +164,11 @@ vj_Input(struct ipcp *ipcp, struct mbuf *bp, int proto)
type = TYPE_UNCOMPRESSED_TCP;
break;
default:
- log_Printf(LogWARN, "vj_Input...???\n");
- return (bp);
+ return bp;
}
- bp = VjUncompressTcp(ipcp, bp, type);
- return (bp);
+
+ *proto = PROTO_IP;
+ return VjUncompressTcp(&bundle->ncp.ipcp, bp, type);
}
const char *
@@ -174,9 +177,11 @@ vj2asc(u_int32_t val)
static char asc[50]; /* The return value is used immediately */
if (val)
- snprintf(asc, sizeof asc, "%d VJ slots %s slot compression",
- (int)((val>>8)&15)+1, val & 1 ? "with" : "without");
+ snprintf(asc, sizeof asc, "%d VJ slots with%s slot compression",
+ (int)((val>>8)&15)+1, val & 1 ? "" : "out");
else
strcpy(asc, "VJ disabled");
return asc;
}
+
+struct layer vjlayer = { LAYER_VJ, "vj", vj_LayerPush, vj_LayerPull };
diff --git a/usr.sbin/ppp/vjcomp.h b/usr.sbin/ppp/vjcomp.h
index b33436e..6c1206c 100644
--- a/usr.sbin/ppp/vjcomp.h
+++ b/usr.sbin/ppp/vjcomp.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: vjcomp.h,v 1.5.4.6 1998/05/01 19:26:12 brian Exp $
+ * $Id: vjcomp.h,v 1.6 1998/05/21 21:49:08 brian Exp $
*/
struct mbuf;
@@ -31,6 +31,6 @@ struct link;
struct ipcp;
struct bundle;
-extern void vj_SendFrame(struct link *, struct mbuf *, struct bundle *);
-extern struct mbuf *vj_Input(struct ipcp *, struct mbuf *, int);
extern const char *vj2asc(u_int32_t);
+
+extern struct layer vjlayer;
OpenPOWER on IntegriCloud