summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/async.c
diff options
context:
space:
mode:
authoramurai <amurai@FreeBSD.org>1995-01-31 06:29:58 +0000
committeramurai <amurai@FreeBSD.org>1995-01-31 06:29:58 +0000
commit21ef2761fd1e5a4beb483da8bddf767d36540dce (patch)
tree3aecd1251d1647032ad1455f304eaeeaab4987d0 /usr.sbin/ppp/async.c
parent0487956fcf018d602bfe99b0e3398c6f4d55680a (diff)
downloadFreeBSD-src-21ef2761fd1e5a4beb483da8bddf767d36540dce.zip
FreeBSD-src-21ef2761fd1e5a4beb483da8bddf767d36540dce.tar.gz
Diffstat (limited to 'usr.sbin/ppp/async.c')
-rw-r--r--usr.sbin/ppp/async.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/usr.sbin/ppp/async.c b/usr.sbin/ppp/async.c
new file mode 100644
index 0000000..d518162
--- /dev/null
+++ b/usr.sbin/ppp/async.c
@@ -0,0 +1,185 @@
+/*
+ * PPP Async HDLC 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:$
+ *
+ */
+#include "fsm.h"
+#include "hdlc.h"
+#include "lcp.h"
+#include "lcpproto.h"
+#include "modem.h"
+
+#define HDLCSIZE (MAX_MRU*2+6)
+
+struct async_state {
+ int mode;
+ int length;
+ struct mbuf *hpacket;
+ u_char hbuff[HDLCSIZE]; /* recv buffer */
+ u_char xbuff[HDLCSIZE]; /* xmit buffer */
+ u_long my_accmap;
+ u_long his_accmap;
+} AsyncState;
+
+#define MODE_HUNT 0x01
+#define MODE_ESC 0x02
+
+void
+AsyncInit()
+{
+ struct async_state *stp = &AsyncState;
+
+ stp->mode = MODE_HUNT;
+ stp->my_accmap = stp->his_accmap = 0xffffffff;
+}
+
+void
+SetLinkParams(lcp)
+struct lcpstate *lcp;
+{
+ struct async_state *stp = &AsyncState;
+
+ stp->my_accmap = lcp->want_accmap;
+ stp->his_accmap = lcp->his_accmap;
+}
+
+/*
+ * Encode into async HDLC byte code if necessary
+ */
+static void
+HdlcPutByte(cp, c, proto)
+u_char **cp;
+u_char c;
+int proto;
+{
+ u_char *wp;
+
+ wp = *cp;
+ if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c))))
+ || (c == HDLC_ESC) || (c == HDLC_SYN)) {
+ *wp++ = HDLC_ESC;
+ c ^= HDLC_XOR;
+ }
+ if (EscMap[32] && EscMap[c >> 3] & (c&7)) {
+ *wp++ = HDLC_ESC;
+ c ^= HDLC_XOR;
+ }
+ *wp++ = c;
+ *cp = wp;
+}
+
+void
+AsyncOutput(pri, bp, proto)
+int pri;
+struct mbuf *bp;
+int proto;
+{
+ struct async_state *hs = &AsyncState;
+ u_char *cp, *sp, *ep;
+ struct mbuf *wp;
+ int cnt;
+
+ if (plength(bp) > HDLCSIZE) {
+ pfree(bp);
+ return;
+ }
+ cp = hs->xbuff;
+ ep = cp + HDLCSIZE - 10;
+ wp = bp;
+ *cp ++ = HDLC_SYN;
+ while (wp) {
+ sp = MBUF_CTOP(wp);
+ for (cnt = wp->cnt; cnt > 0; cnt--) {
+ HdlcPutByte(&cp, *sp++, proto);
+ if (cp >= ep) {
+ pfree(bp);
+ return;
+ }
+ }
+ wp = wp->next;
+ }
+ *cp ++ = HDLC_SYN;
+
+ cnt = cp - hs->xbuff;
+ LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt);
+ WriteModem(pri, (char *)hs->xbuff, cnt);
+ OsAddOutOctets(cnt);
+ pfree(bp);
+}
+
+struct mbuf *
+AsyncDecode(c)
+u_char c;
+{
+ struct async_state *hs = &AsyncState;
+ struct mbuf *bp;
+
+ if ((hs->mode & MODE_HUNT) && c != HDLC_SYN)
+ return(NULLBUFF);
+
+ switch (c) {
+ case HDLC_SYN:
+ hs->mode &= ~MODE_HUNT;
+ if (hs->length) { /* packet is ready. */
+ bp = mballoc(hs->length, MB_ASYNC);
+ mbwrite(bp, hs->hbuff, hs->length);
+ hs->length = 0;
+ return(bp);
+ }
+ break;
+ case HDLC_ESC:
+ if (!(hs->mode & MODE_ESC)) {
+ hs->mode |= MODE_ESC;
+ break;
+ }
+ /* Fall into ... */
+ default:
+ if (hs->length >= HDLCSIZE) {
+ /* packet is too large, discard it */
+ logprintf("too large, diacarding.\n");
+ hs->length = 0;
+ hs->mode = MODE_HUNT;
+ break;
+ }
+ if (hs->mode & MODE_ESC) {
+ c ^= HDLC_XOR;
+ hs->mode &= ~MODE_ESC;
+ }
+ hs->hbuff[hs->length++] = c;
+ break;
+ }
+ return NULLBUFF;
+}
+
+void
+AsyncInput(buff, cnt)
+u_char *buff;
+int cnt;
+{
+ struct mbuf *bp;
+
+ OsAddInOctets(cnt);
+ while (cnt > 0) {
+ bp = AsyncDecode(*buff++);
+ if (bp)
+ HdlcInput(bp);
+ cnt--;
+ }
+}
OpenPOWER on IntegriCloud