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 * 20a33b2ef7SBrian Somers * $Id: async.c,v 1.16 1998/05/21 21:43:55 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai */ 232764b86aSBrian Somers #include <sys/types.h> 2475240ed1SBrian Somers 2575240ed1SBrian Somers #include <string.h> 2675240ed1SBrian Somers #include <termios.h> 2775240ed1SBrian Somers 2875240ed1SBrian Somers #include "mbuf.h" 2975240ed1SBrian Somers #include "log.h" 3075240ed1SBrian Somers #include "defs.h" 3175240ed1SBrian Somers #include "timer.h" 32af57ed9fSAtsushi Murai #include "fsm.h" 33879ed6faSBrian Somers #include "lqr.h" 34af57ed9fSAtsushi Murai #include "hdlc.h" 35af57ed9fSAtsushi Murai #include "lcp.h" 36af57ed9fSAtsushi Murai #include "lcpproto.h" 3775240ed1SBrian Somers #include "async.h" 388c07a7b2SBrian Somers #include "throughput.h" 393b0f8d2eSBrian Somers #include "ccp.h" 408c07a7b2SBrian Somers #include "link.h" 4142d4d396SBrian Somers #include "descriptor.h" 4263b73463SBrian Somers #include "physical.h" 43af57ed9fSAtsushi Murai 44af57ed9fSAtsushi Murai #define MODE_HUNT 0x01 45af57ed9fSAtsushi Murai #define MODE_ESC 0x02 46af57ed9fSAtsushi Murai 47af57ed9fSAtsushi Murai void 486140ba11SBrian Somers async_Init(struct async *async) 49af57ed9fSAtsushi Murai { 506140ba11SBrian Somers async->mode = MODE_HUNT; 516140ba11SBrian Somers async->length = 0; 526140ba11SBrian Somers async->my_accmap = async->his_accmap = 0xffffffff; 539dee069dSBrian Somers memset(async->cfg.EscMap, '\0', sizeof async->cfg.EscMap); 54af57ed9fSAtsushi Murai } 55af57ed9fSAtsushi Murai 56af57ed9fSAtsushi Murai void 57aad81d1eSBrian Somers async_SetLinkParams(struct async *async, struct lcp *lcp) 58af57ed9fSAtsushi Murai { 596140ba11SBrian Somers async->my_accmap = lcp->want_accmap; 606140ba11SBrian Somers async->his_accmap = lcp->his_accmap; 61af57ed9fSAtsushi Murai } 62af57ed9fSAtsushi Murai 63af57ed9fSAtsushi Murai /* 64af57ed9fSAtsushi Murai * Encode into async HDLC byte code if necessary 65af57ed9fSAtsushi Murai */ 66af57ed9fSAtsushi Murai static void 676140ba11SBrian Somers HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto) 68af57ed9fSAtsushi Murai { 69af57ed9fSAtsushi Murai u_char *wp; 70af57ed9fSAtsushi Murai 71af57ed9fSAtsushi Murai wp = *cp; 726140ba11SBrian Somers if ((c < 0x20 && (proto == PROTO_LCP || (async->his_accmap & (1 << c)))) 73af57ed9fSAtsushi Murai || (c == HDLC_ESC) || (c == HDLC_SYN)) { 74af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 75af57ed9fSAtsushi Murai c ^= HDLC_XOR; 76af57ed9fSAtsushi Murai } 779991562dSBrian Somers if (async->cfg.EscMap[32] && async->cfg.EscMap[c >> 3] & (1 << (c & 7))) { 78af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 79af57ed9fSAtsushi Murai c ^= HDLC_XOR; 80af57ed9fSAtsushi Murai } 81af57ed9fSAtsushi Murai *wp++ = c; 82af57ed9fSAtsushi Murai *cp = wp; 83af57ed9fSAtsushi Murai } 84af57ed9fSAtsushi Murai 85af57ed9fSAtsushi Murai void 866140ba11SBrian Somers async_Output(int pri, struct mbuf *bp, int proto, struct physical *physical) 87af57ed9fSAtsushi Murai { 88af57ed9fSAtsushi Murai u_char *cp, *sp, *ep; 89af57ed9fSAtsushi Murai struct mbuf *wp; 90af57ed9fSAtsushi Murai int cnt; 91af57ed9fSAtsushi Murai 92dd7e2610SBrian Somers if (mbuf_Length(bp) > HDLCSIZE) { 93dd7e2610SBrian Somers mbuf_Free(bp); 94af57ed9fSAtsushi Murai return; 95af57ed9fSAtsushi Murai } 966140ba11SBrian Somers cp = physical->async.xbuff; 97af57ed9fSAtsushi Murai ep = cp + HDLCSIZE - 10; 98af57ed9fSAtsushi Murai wp = bp; 99af57ed9fSAtsushi Murai *cp++ = HDLC_SYN; 100af57ed9fSAtsushi Murai while (wp) { 101af57ed9fSAtsushi Murai sp = MBUF_CTOP(wp); 102af57ed9fSAtsushi Murai for (cnt = wp->cnt; cnt > 0; cnt--) { 1036140ba11SBrian Somers HdlcPutByte(&physical->async, &cp, *sp++, proto); 104af57ed9fSAtsushi Murai if (cp >= ep) { 105dd7e2610SBrian Somers mbuf_Free(bp); 106af57ed9fSAtsushi Murai return; 107af57ed9fSAtsushi Murai } 108af57ed9fSAtsushi Murai } 109af57ed9fSAtsushi Murai wp = wp->next; 110af57ed9fSAtsushi Murai } 111af57ed9fSAtsushi Murai *cp++ = HDLC_SYN; 112af57ed9fSAtsushi Murai 1136140ba11SBrian Somers cnt = cp - physical->async.xbuff; 114dd7e2610SBrian Somers log_DumpBuff(LogASYNC, "WriteModem", physical->async.xbuff, cnt); 115dd7e2610SBrian Somers link_Write(&physical->link, pri, (char *)physical->async.xbuff, cnt); 116dd7e2610SBrian Somers link_AddOutOctets(&physical->link, cnt); 117dd7e2610SBrian Somers mbuf_Free(bp); 118af57ed9fSAtsushi Murai } 119af57ed9fSAtsushi Murai 12075240ed1SBrian Somers static struct mbuf * 1216140ba11SBrian Somers async_Decode(struct async *async, u_char c) 122af57ed9fSAtsushi Murai { 123af57ed9fSAtsushi Murai struct mbuf *bp; 124af57ed9fSAtsushi Murai 1256140ba11SBrian Somers if ((async->mode & MODE_HUNT) && c != HDLC_SYN) 126aa8e0519SBrian Somers return NULL; 127af57ed9fSAtsushi Murai 128af57ed9fSAtsushi Murai switch (c) { 129af57ed9fSAtsushi Murai case HDLC_SYN: 1306140ba11SBrian Somers async->mode &= ~MODE_HUNT; 1316140ba11SBrian Somers if (async->length) { /* packet is ready. */ 132dd7e2610SBrian Somers bp = mbuf_Alloc(async->length, MB_ASYNC); 133dd7e2610SBrian Somers mbuf_Write(bp, async->hbuff, async->length); 1346140ba11SBrian Somers async->length = 0; 135aa8e0519SBrian Somers return bp; 136af57ed9fSAtsushi Murai } 137af57ed9fSAtsushi Murai break; 138af57ed9fSAtsushi Murai case HDLC_ESC: 1396140ba11SBrian Somers if (!(async->mode & MODE_ESC)) { 1406140ba11SBrian Somers async->mode |= MODE_ESC; 141af57ed9fSAtsushi Murai break; 142af57ed9fSAtsushi Murai } 143af57ed9fSAtsushi Murai /* Fall into ... */ 144af57ed9fSAtsushi Murai default: 1456140ba11SBrian Somers if (async->length >= HDLCSIZE) { 146af57ed9fSAtsushi Murai /* packet is too large, discard it */ 147a33b2ef7SBrian Somers log_Printf(LogWARN, "Packet too large (%d), discarding.\n", 148a33b2ef7SBrian Somers async->length); 1496140ba11SBrian Somers async->length = 0; 1506140ba11SBrian Somers async->mode = MODE_HUNT; 151af57ed9fSAtsushi Murai break; 152af57ed9fSAtsushi Murai } 1536140ba11SBrian Somers if (async->mode & MODE_ESC) { 154af57ed9fSAtsushi Murai c ^= HDLC_XOR; 1556140ba11SBrian Somers async->mode &= ~MODE_ESC; 156af57ed9fSAtsushi Murai } 1576140ba11SBrian Somers async->hbuff[async->length++] = c; 158af57ed9fSAtsushi Murai break; 159af57ed9fSAtsushi Murai } 160aa8e0519SBrian Somers return NULL; 161af57ed9fSAtsushi Murai } 162af57ed9fSAtsushi Murai 163af57ed9fSAtsushi Murai void 1646140ba11SBrian Somers async_Input(struct bundle *bundle, u_char *buff, int cnt, 1657a6f8720SBrian Somers struct physical *physical) 166af57ed9fSAtsushi Murai { 167af57ed9fSAtsushi Murai struct mbuf *bp; 168af57ed9fSAtsushi Murai 169dd7e2610SBrian Somers link_AddInOctets(&physical->link, cnt); 1708c07a7b2SBrian Somers 171dd7e2610SBrian Somers if (physical_IsSync(physical)) { 172dd7e2610SBrian Somers bp = mbuf_Alloc(cnt, MB_ASYNC); 17375240ed1SBrian Somers memcpy(MBUF_CTOP(bp), buff, cnt); 17453c9f6c0SAtsushi Murai bp->cnt = cnt; 175dd7e2610SBrian Somers hdlc_Input(bundle, bp, physical); 17653c9f6c0SAtsushi Murai } else { 177af57ed9fSAtsushi Murai while (cnt > 0) { 1786140ba11SBrian Somers bp = async_Decode(&physical->async, *buff++); 179af57ed9fSAtsushi Murai if (bp) 180dd7e2610SBrian Somers hdlc_Input(bundle, bp, physical); 181af57ed9fSAtsushi Murai cnt--; 182af57ed9fSAtsushi Murai } 183af57ed9fSAtsushi Murai } 18453c9f6c0SAtsushi Murai } 185