async.c revision 32663
1139825Simp/* 21541Srgrimes * PPP Async HDLC Module 31541Srgrimes * 41541Srgrimes * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 51541Srgrimes * 61541Srgrimes * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 71541Srgrimes * 81541Srgrimes * Redistribution and use in source and binary forms are permitted 91541Srgrimes * provided that the above copyright notice and this paragraph are 101541Srgrimes * duplicated in all such forms and that any documentation, 111541Srgrimes * advertising materials, and other materials related to such 121541Srgrimes * distribution and use acknowledge that the software was developed 131541Srgrimes * by the Internet Initiative Japan, Inc. The name of the 141541Srgrimes * IIJ may not be used to endorse or promote products derived 151541Srgrimes * from this software without specific prior written permission. 161541Srgrimes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 171541Srgrimes * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 181541Srgrimes * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 191541Srgrimes * 201541Srgrimes * $Id: async.c,v 1.14 1997/11/22 03:37:23 brian Exp $ 211541Srgrimes * 221541Srgrimes */ 231541Srgrimes#include <sys/param.h> 241541Srgrimes#include <netinet/in.h> 251541Srgrimes 261541Srgrimes#include <stdio.h> 271541Srgrimes#include <string.h> 281541Srgrimes#include <termios.h> 291541Srgrimes 3050477Speter#include "command.h" 311541Srgrimes#include "mbuf.h" 321541Srgrimes#include "log.h" 331541Srgrimes#include "defs.h" 341541Srgrimes#include "timer.h" 351541Srgrimes#include "fsm.h" 36103731Swollman#include "hdlc.h" 3734319Sdufault#include "lcp.h" 38103731Swollman#include "lcpproto.h" 39103731Swollman#include "modem.h" 40103731Swollman#include "loadalias.h" 41103731Swollman#include "vars.h" 42103731Swollman#include "async.h" 43103731Swollman 44103731Swollman#define HDLCSIZE (MAX_MRU*2+6) 45103731Swollman 46103731Swollmanstatic struct async_state { 47103731Swollman int mode; 48103731Swollman int length; 49103731Swollman u_char hbuff[HDLCSIZE]; /* recv buffer */ 50103731Swollman u_char xbuff[HDLCSIZE]; /* xmit buffer */ 51103731Swollman u_long my_accmap; 52103731Swollman u_long his_accmap; 53103731Swollman} AsyncState; 54103731Swollman 55103731Swollman#define MODE_HUNT 0x01 56103731Swollman#define MODE_ESC 0x02 57103731Swollman 58106055Swollmanvoid 59103731SwollmanAsyncInit() 60103731Swollman{ 61103731Swollman struct async_state *stp = &AsyncState; 62103731Swollman 63103731Swollman stp->mode = MODE_HUNT; 64153006Sdavidxu stp->length = 0; 65151659Swollman stp->my_accmap = stp->his_accmap = 0xffffffff; 66103731Swollman} 67103731Swollman 68103731Swollmanvoid 69103731SwollmanSetLinkParams(struct lcpstate *lcp) 70151578Sdavidxu{ 71103731Swollman struct async_state *stp = &AsyncState; 72103731Swollman 73103731Swollman stp->my_accmap = lcp->want_accmap; 74103731Swollman stp->his_accmap = lcp->his_accmap; 75153004Sdavidxu} 76151872Sdavidxu 77103731Swollman/* 78103731Swollman * Encode into async HDLC byte code if necessary 791541Srgrimes */ 80103731Swollmanstatic void 81103731SwollmanHdlcPutByte(u_char **cp, u_char c, int proto) 82103731Swollman{ 83103731Swollman u_char *wp; 84103731Swollman 851541Srgrimes wp = *cp; 8620640Sbde if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1 << c)))) 8720640Sbde || (c == HDLC_ESC) || (c == HDLC_SYN)) { 8820640Sbde *wp++ = HDLC_ESC; 89103731Swollman c ^= HDLC_XOR; 90103731Swollman } 911541Srgrimes if (EscMap[32] && EscMap[c >> 3] & (1 << (c & 7))) { 9220640Sbde *wp++ = HDLC_ESC; 93103731Swollman c ^= HDLC_XOR; 9420640Sbde } 951541Srgrimes *wp++ = c; 96105045Smike *cp = wp; 97105045Smike} 98105045Smike 991541Srgrimesvoid 1001541SrgrimesAsyncOutput(int pri, struct mbuf *bp, int proto) 1011541Srgrimes{ 1021541Srgrimes struct async_state *hs = &AsyncState; 1031541Srgrimes u_char *cp, *sp, *ep; 1041541Srgrimes struct mbuf *wp; 1051541Srgrimes int cnt; 106105789Sphk 1071541Srgrimes if (plength(bp) > HDLCSIZE) { 1081541Srgrimes pfree(bp); 1091541Srgrimes return; 110168397Spjd } 111168397Spjd cp = hs->xbuff; 112105789Sphk ep = cp + HDLCSIZE - 10; 1131541Srgrimes wp = bp; 1141541Srgrimes *cp++ = HDLC_SYN; 1151541Srgrimes while (wp) { 1161541Srgrimes sp = MBUF_CTOP(wp); 1171541Srgrimes for (cnt = wp->cnt; cnt > 0; cnt--) { 1181541Srgrimes HdlcPutByte(&cp, *sp++, proto); 1191541Srgrimes if (cp >= ep) { 1201541Srgrimes pfree(bp); 1211541Srgrimes return; 1221541Srgrimes } 1231541Srgrimes } 1241541Srgrimes wp = wp->next; 1251541Srgrimes } 1261541Srgrimes *cp++ = HDLC_SYN; 1271541Srgrimes 1281541Srgrimes cnt = cp - hs->xbuff; 1291541Srgrimes LogDumpBuff(LogASYNC, "WriteModem", hs->xbuff, cnt); 1301541Srgrimes WriteModem(pri, (char *) hs->xbuff, cnt); 1311541Srgrimes ModemAddOutOctets(cnt); 132103731Swollman pfree(bp); 133103768Sbde} 134103768Sbde 135103768Sbdestatic struct mbuf * 136103731SwollmanAsyncDecode(u_char c) 13734030Sdufault{ 138103731Swollman struct async_state *hs = &AsyncState; 139103731Swollman struct mbuf *bp; 140103731Swollman 141103731Swollman if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 142103731Swollman return NULL; 143103731Swollman 144103731Swollman switch (c) { 145106055Swollman case HDLC_SYN: 146103731Swollman hs->mode &= ~MODE_HUNT; 14734030Sdufault if (hs->length) { /* packet is ready. */ 148103731Swollman bp = mballoc(hs->length, MB_ASYNC); 149105572Srwatson mbwrite(bp, hs->hbuff, hs->length); 150105572Srwatson hs->length = 0; 151105572Srwatson return bp; 152105572Srwatson } 153105572Srwatson break; 154103731Swollman case HDLC_ESC: 155101071Srwatson if (!(hs->mode & MODE_ESC)) { 156168397Spjd hs->mode |= MODE_ESC; 157168397Spjd break; 158168397Spjd } 159103731Swollman /* Fall into ... */ 16014222Speter default: 16114222Speter if (hs->length >= HDLCSIZE) { 16214222Speter /* packet is too large, discard it */ 16365557Sjasone LogPrintf(LogERROR, "Packet too large (%d), discarding.\n", hs->length); 16414222Speter hs->length = 0; 165103768Sbde hs->mode = MODE_HUNT; 166103768Sbde break; 167103768Sbde } 168103768Sbde if (hs->mode & MODE_ESC) { 169103768Sbde c ^= HDLC_XOR; 170103768Sbde hs->mode &= ~MODE_ESC; 171103768Sbde } 172103768Sbde hs->hbuff[hs->length++] = c; 173103768Sbde break; 174103768Sbde } 175103731Swollman return NULL; 176103731Swollman} 177103768Sbde 178103731Swollmanvoid 179103768SbdeAsyncInput(u_char *buff, int cnt) 180103768Sbde{ 181103768Sbde struct mbuf *bp; 18226671Sdyson 183103731Swollman ModemAddInOctets(cnt); 18414222Speter if (DEV_IS_SYNC) { 1851541Srgrimes bp = mballoc(cnt, MB_ASYNC); 186 memcpy(MBUF_CTOP(bp), buff, cnt); 187 bp->cnt = cnt; 188 HdlcInput(bp); 189 } else { 190 while (cnt > 0) { 191 bp = AsyncDecode(*buff++); 192 if (bp) 193 HdlcInput(bp); 194 cnt--; 195 } 196 } 197} 198