1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Async HDLC Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 2075240ed1SBrian Somers * $Id: async.c,v 1.11 1997/08/25 00:29:05 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai */ 2375240ed1SBrian Somers #include <sys/param.h> 2475240ed1SBrian Somers #include <netinet/in.h> 2575240ed1SBrian Somers 2675240ed1SBrian Somers #include <stdio.h> 2775240ed1SBrian Somers #include <string.h> 2875240ed1SBrian Somers #include <termios.h> 2975240ed1SBrian Somers 3075240ed1SBrian Somers #include "mbuf.h" 3175240ed1SBrian Somers #include "log.h" 3275240ed1SBrian Somers #include "defs.h" 3375240ed1SBrian Somers #include "timer.h" 34af57ed9fSAtsushi Murai #include "fsm.h" 35af57ed9fSAtsushi Murai #include "hdlc.h" 36af57ed9fSAtsushi Murai #include "lcp.h" 37af57ed9fSAtsushi Murai #include "lcpproto.h" 38af57ed9fSAtsushi Murai #include "modem.h" 396ed9fb2fSBrian Somers #include "loadalias.h" 4075240ed1SBrian Somers #include "command.h" 4153c9f6c0SAtsushi Murai #include "vars.h" 42ed6a16c1SPoul-Henning Kamp #include "os.h" 4375240ed1SBrian Somers #include "async.h" 44af57ed9fSAtsushi Murai 45af57ed9fSAtsushi Murai #define HDLCSIZE (MAX_MRU*2+6) 46af57ed9fSAtsushi Murai 4775240ed1SBrian Somers static struct async_state { 48af57ed9fSAtsushi Murai int mode; 49af57ed9fSAtsushi Murai int length; 50af57ed9fSAtsushi Murai u_char hbuff[HDLCSIZE]; /* recv buffer */ 51af57ed9fSAtsushi Murai u_char xbuff[HDLCSIZE]; /* xmit buffer */ 52af57ed9fSAtsushi Murai u_long my_accmap; 53af57ed9fSAtsushi Murai u_long his_accmap; 54af57ed9fSAtsushi Murai } AsyncState; 55af57ed9fSAtsushi Murai 56af57ed9fSAtsushi Murai #define MODE_HUNT 0x01 57af57ed9fSAtsushi Murai #define MODE_ESC 0x02 58af57ed9fSAtsushi Murai 59af57ed9fSAtsushi Murai void 60af57ed9fSAtsushi Murai AsyncInit() 61af57ed9fSAtsushi Murai { 62af57ed9fSAtsushi Murai struct async_state *stp = &AsyncState; 63af57ed9fSAtsushi Murai 64af57ed9fSAtsushi Murai stp->mode = MODE_HUNT; 6553c9f6c0SAtsushi Murai stp->length = 0; 66af57ed9fSAtsushi Murai stp->my_accmap = stp->his_accmap = 0xffffffff; 67af57ed9fSAtsushi Murai } 68af57ed9fSAtsushi Murai 69af57ed9fSAtsushi Murai void 70944f7098SBrian Somers SetLinkParams(struct lcpstate *lcp) 71af57ed9fSAtsushi Murai { 72af57ed9fSAtsushi Murai struct async_state *stp = &AsyncState; 73af57ed9fSAtsushi Murai 74af57ed9fSAtsushi Murai stp->my_accmap = lcp->want_accmap; 75af57ed9fSAtsushi Murai stp->his_accmap = lcp->his_accmap; 76af57ed9fSAtsushi Murai } 77af57ed9fSAtsushi Murai 78af57ed9fSAtsushi Murai /* 79af57ed9fSAtsushi Murai * Encode into async HDLC byte code if necessary 80af57ed9fSAtsushi Murai */ 81af57ed9fSAtsushi Murai static void 82944f7098SBrian Somers HdlcPutByte(u_char **cp, u_char c, int proto) 83af57ed9fSAtsushi Murai { 84af57ed9fSAtsushi Murai u_char *wp; 85af57ed9fSAtsushi Murai 86af57ed9fSAtsushi Murai wp = *cp; 87af57ed9fSAtsushi Murai if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1 << c)))) 88af57ed9fSAtsushi Murai || (c == HDLC_ESC) || (c == HDLC_SYN)) { 89af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 90af57ed9fSAtsushi Murai c ^= HDLC_XOR; 91af57ed9fSAtsushi Murai } 9210b74897SAtsushi Murai if (EscMap[32] && EscMap[c >> 3] & (1 << (c & 7))) { 93af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 94af57ed9fSAtsushi Murai c ^= HDLC_XOR; 95af57ed9fSAtsushi Murai } 96af57ed9fSAtsushi Murai *wp++ = c; 97af57ed9fSAtsushi Murai *cp = wp; 98af57ed9fSAtsushi Murai } 99af57ed9fSAtsushi Murai 100af57ed9fSAtsushi Murai void 101944f7098SBrian Somers AsyncOutput(int pri, struct mbuf *bp, int proto) 102af57ed9fSAtsushi Murai { 103af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 104af57ed9fSAtsushi Murai u_char *cp, *sp, *ep; 105af57ed9fSAtsushi Murai struct mbuf *wp; 106af57ed9fSAtsushi Murai int cnt; 107af57ed9fSAtsushi Murai 108af57ed9fSAtsushi Murai if (plength(bp) > HDLCSIZE) { 109af57ed9fSAtsushi Murai pfree(bp); 110af57ed9fSAtsushi Murai return; 111af57ed9fSAtsushi Murai } 112af57ed9fSAtsushi Murai cp = hs->xbuff; 113af57ed9fSAtsushi Murai ep = cp + HDLCSIZE - 10; 114af57ed9fSAtsushi Murai wp = bp; 115af57ed9fSAtsushi Murai *cp++ = HDLC_SYN; 116af57ed9fSAtsushi Murai while (wp) { 117af57ed9fSAtsushi Murai sp = MBUF_CTOP(wp); 118af57ed9fSAtsushi Murai for (cnt = wp->cnt; cnt > 0; cnt--) { 119af57ed9fSAtsushi Murai HdlcPutByte(&cp, *sp++, proto); 120af57ed9fSAtsushi Murai if (cp >= ep) { 121af57ed9fSAtsushi Murai pfree(bp); 122af57ed9fSAtsushi Murai return; 123af57ed9fSAtsushi Murai } 124af57ed9fSAtsushi Murai } 125af57ed9fSAtsushi Murai wp = wp->next; 126af57ed9fSAtsushi Murai } 127af57ed9fSAtsushi Murai *cp++ = HDLC_SYN; 128af57ed9fSAtsushi Murai 129af57ed9fSAtsushi Murai cnt = cp - hs->xbuff; 130927145beSBrian Somers LogDumpBuff(LogASYNC, "WriteModem", hs->xbuff, cnt); 131af57ed9fSAtsushi Murai WriteModem(pri, (char *) hs->xbuff, cnt); 132af57ed9fSAtsushi Murai OsAddOutOctets(cnt); 133af57ed9fSAtsushi Murai pfree(bp); 134af57ed9fSAtsushi Murai } 135af57ed9fSAtsushi Murai 13675240ed1SBrian Somers static struct mbuf * 137944f7098SBrian Somers AsyncDecode(u_char c) 138af57ed9fSAtsushi Murai { 139af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 140af57ed9fSAtsushi Murai struct mbuf *bp; 141af57ed9fSAtsushi Murai 142af57ed9fSAtsushi Murai if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 143af57ed9fSAtsushi Murai return (NULLBUFF); 144af57ed9fSAtsushi Murai 145af57ed9fSAtsushi Murai switch (c) { 146af57ed9fSAtsushi Murai case HDLC_SYN: 147af57ed9fSAtsushi Murai hs->mode &= ~MODE_HUNT; 148af57ed9fSAtsushi Murai if (hs->length) { /* packet is ready. */ 149af57ed9fSAtsushi Murai bp = mballoc(hs->length, MB_ASYNC); 150af57ed9fSAtsushi Murai mbwrite(bp, hs->hbuff, hs->length); 151af57ed9fSAtsushi Murai hs->length = 0; 152af57ed9fSAtsushi Murai return (bp); 153af57ed9fSAtsushi Murai } 154af57ed9fSAtsushi Murai break; 155af57ed9fSAtsushi Murai case HDLC_ESC: 156af57ed9fSAtsushi Murai if (!(hs->mode & MODE_ESC)) { 157af57ed9fSAtsushi Murai hs->mode |= MODE_ESC; 158af57ed9fSAtsushi Murai break; 159af57ed9fSAtsushi Murai } 160af57ed9fSAtsushi Murai /* Fall into ... */ 161af57ed9fSAtsushi Murai default: 162af57ed9fSAtsushi Murai if (hs->length >= HDLCSIZE) { 163af57ed9fSAtsushi Murai /* packet is too large, discard it */ 164c3a83f67SBrian Somers LogPrintf(LogERROR, "Packet too large (%d), discarding.\n", hs->length); 165af57ed9fSAtsushi Murai hs->length = 0; 166af57ed9fSAtsushi Murai hs->mode = MODE_HUNT; 167af57ed9fSAtsushi Murai break; 168af57ed9fSAtsushi Murai } 169af57ed9fSAtsushi Murai if (hs->mode & MODE_ESC) { 170af57ed9fSAtsushi Murai c ^= HDLC_XOR; 171af57ed9fSAtsushi Murai hs->mode &= ~MODE_ESC; 172af57ed9fSAtsushi Murai } 173af57ed9fSAtsushi Murai hs->hbuff[hs->length++] = c; 174af57ed9fSAtsushi Murai break; 175af57ed9fSAtsushi Murai } 176af57ed9fSAtsushi Murai return NULLBUFF; 177af57ed9fSAtsushi Murai } 178af57ed9fSAtsushi Murai 179af57ed9fSAtsushi Murai void 180944f7098SBrian Somers AsyncInput(u_char *buff, int cnt) 181af57ed9fSAtsushi Murai { 182af57ed9fSAtsushi Murai struct mbuf *bp; 183af57ed9fSAtsushi Murai 184af57ed9fSAtsushi Murai OsAddInOctets(cnt); 18553c9f6c0SAtsushi Murai if (DEV_IS_SYNC) { 18653c9f6c0SAtsushi Murai bp = mballoc(cnt, MB_ASYNC); 18775240ed1SBrian Somers memcpy(MBUF_CTOP(bp), buff, cnt); 18853c9f6c0SAtsushi Murai bp->cnt = cnt; 18953c9f6c0SAtsushi Murai HdlcInput(bp); 19053c9f6c0SAtsushi Murai } else { 191af57ed9fSAtsushi Murai while (cnt > 0) { 192af57ed9fSAtsushi Murai bp = AsyncDecode(*buff++); 193af57ed9fSAtsushi Murai if (bp) 194af57ed9fSAtsushi Murai HdlcInput(bp); 195af57ed9fSAtsushi Murai cnt--; 196af57ed9fSAtsushi Murai } 197af57ed9fSAtsushi Murai } 19853c9f6c0SAtsushi Murai } 199