xref: /freebsd/usr.sbin/ppp/async.c (revision af57ed9fdcc4e2a81940fc2243c0d3949fc0e00f)
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  *
20af57ed9fSAtsushi Murai  * $Id:$
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  */
23af57ed9fSAtsushi Murai #include "fsm.h"
24af57ed9fSAtsushi Murai #include "hdlc.h"
25af57ed9fSAtsushi Murai #include "lcp.h"
26af57ed9fSAtsushi Murai #include "lcpproto.h"
27af57ed9fSAtsushi Murai #include "modem.h"
28af57ed9fSAtsushi Murai 
29af57ed9fSAtsushi Murai #define HDLCSIZE	(MAX_MRU*2+6)
30af57ed9fSAtsushi Murai 
31af57ed9fSAtsushi Murai struct async_state {
32af57ed9fSAtsushi Murai   int mode;
33af57ed9fSAtsushi Murai   int length;
34af57ed9fSAtsushi Murai   struct mbuf *hpacket;
35af57ed9fSAtsushi Murai   u_char hbuff[HDLCSIZE];	/* recv buffer */
36af57ed9fSAtsushi Murai   u_char xbuff[HDLCSIZE];	/* xmit buffer */
37af57ed9fSAtsushi Murai   u_long my_accmap;
38af57ed9fSAtsushi Murai   u_long his_accmap;
39af57ed9fSAtsushi Murai } AsyncState;
40af57ed9fSAtsushi Murai 
41af57ed9fSAtsushi Murai #define MODE_HUNT 0x01
42af57ed9fSAtsushi Murai #define MODE_ESC  0x02
43af57ed9fSAtsushi Murai 
44af57ed9fSAtsushi Murai void
45af57ed9fSAtsushi Murai AsyncInit()
46af57ed9fSAtsushi Murai {
47af57ed9fSAtsushi Murai   struct async_state *stp = &AsyncState;
48af57ed9fSAtsushi Murai 
49af57ed9fSAtsushi Murai   stp->mode = MODE_HUNT;
50af57ed9fSAtsushi Murai   stp->my_accmap = stp->his_accmap = 0xffffffff;
51af57ed9fSAtsushi Murai }
52af57ed9fSAtsushi Murai 
53af57ed9fSAtsushi Murai void
54af57ed9fSAtsushi Murai SetLinkParams(lcp)
55af57ed9fSAtsushi Murai struct lcpstate *lcp;
56af57ed9fSAtsushi Murai {
57af57ed9fSAtsushi Murai   struct async_state *stp = &AsyncState;
58af57ed9fSAtsushi Murai 
59af57ed9fSAtsushi Murai   stp->my_accmap = lcp->want_accmap;
60af57ed9fSAtsushi Murai   stp->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
67af57ed9fSAtsushi Murai HdlcPutByte(cp, c, proto)
68af57ed9fSAtsushi Murai u_char **cp;
69af57ed9fSAtsushi Murai u_char c;
70af57ed9fSAtsushi Murai int proto;
71af57ed9fSAtsushi Murai {
72af57ed9fSAtsushi Murai   u_char *wp;
73af57ed9fSAtsushi Murai 
74af57ed9fSAtsushi Murai   wp = *cp;
75af57ed9fSAtsushi Murai   if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c))))
76af57ed9fSAtsushi Murai 	|| (c == HDLC_ESC) || (c == HDLC_SYN)) {
77af57ed9fSAtsushi Murai     *wp++ = HDLC_ESC;
78af57ed9fSAtsushi Murai     c ^= HDLC_XOR;
79af57ed9fSAtsushi Murai   }
80af57ed9fSAtsushi Murai   if (EscMap[32] && EscMap[c >> 3] & (c&7)) {
81af57ed9fSAtsushi Murai     *wp++ = HDLC_ESC;
82af57ed9fSAtsushi Murai     c ^= HDLC_XOR;
83af57ed9fSAtsushi Murai   }
84af57ed9fSAtsushi Murai   *wp++ = c;
85af57ed9fSAtsushi Murai   *cp = wp;
86af57ed9fSAtsushi Murai }
87af57ed9fSAtsushi Murai 
88af57ed9fSAtsushi Murai void
89af57ed9fSAtsushi Murai AsyncOutput(pri, bp, proto)
90af57ed9fSAtsushi Murai int pri;
91af57ed9fSAtsushi Murai struct mbuf *bp;
92af57ed9fSAtsushi Murai int proto;
93af57ed9fSAtsushi Murai {
94af57ed9fSAtsushi Murai   struct async_state *hs = &AsyncState;
95af57ed9fSAtsushi Murai   u_char *cp, *sp, *ep;
96af57ed9fSAtsushi Murai   struct mbuf *wp;
97af57ed9fSAtsushi Murai   int cnt;
98af57ed9fSAtsushi Murai 
99af57ed9fSAtsushi Murai   if (plength(bp) > HDLCSIZE) {
100af57ed9fSAtsushi Murai     pfree(bp);
101af57ed9fSAtsushi Murai     return;
102af57ed9fSAtsushi Murai   }
103af57ed9fSAtsushi Murai   cp = hs->xbuff;
104af57ed9fSAtsushi Murai   ep = cp + HDLCSIZE - 10;
105af57ed9fSAtsushi Murai   wp = bp;
106af57ed9fSAtsushi Murai   *cp ++ = HDLC_SYN;
107af57ed9fSAtsushi Murai   while (wp) {
108af57ed9fSAtsushi Murai     sp = MBUF_CTOP(wp);
109af57ed9fSAtsushi Murai     for (cnt = wp->cnt; cnt > 0; cnt--) {
110af57ed9fSAtsushi Murai       HdlcPutByte(&cp, *sp++, proto);
111af57ed9fSAtsushi Murai       if (cp >= ep) {
112af57ed9fSAtsushi Murai 	pfree(bp);
113af57ed9fSAtsushi Murai 	return;
114af57ed9fSAtsushi Murai       }
115af57ed9fSAtsushi Murai     }
116af57ed9fSAtsushi Murai     wp = wp->next;
117af57ed9fSAtsushi Murai   }
118af57ed9fSAtsushi Murai   *cp ++ = HDLC_SYN;
119af57ed9fSAtsushi Murai 
120af57ed9fSAtsushi Murai   cnt = cp - hs->xbuff;
121af57ed9fSAtsushi Murai   LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt);
122af57ed9fSAtsushi Murai   WriteModem(pri, (char *)hs->xbuff, cnt);
123af57ed9fSAtsushi Murai   OsAddOutOctets(cnt);
124af57ed9fSAtsushi Murai   pfree(bp);
125af57ed9fSAtsushi Murai }
126af57ed9fSAtsushi Murai 
127af57ed9fSAtsushi Murai struct mbuf *
128af57ed9fSAtsushi Murai AsyncDecode(c)
129af57ed9fSAtsushi Murai u_char c;
130af57ed9fSAtsushi Murai {
131af57ed9fSAtsushi Murai   struct async_state *hs = &AsyncState;
132af57ed9fSAtsushi Murai   struct mbuf *bp;
133af57ed9fSAtsushi Murai 
134af57ed9fSAtsushi Murai   if ((hs->mode & MODE_HUNT) && c != HDLC_SYN)
135af57ed9fSAtsushi Murai     return(NULLBUFF);
136af57ed9fSAtsushi Murai 
137af57ed9fSAtsushi Murai   switch (c) {
138af57ed9fSAtsushi Murai   case HDLC_SYN:
139af57ed9fSAtsushi Murai     hs->mode &= ~MODE_HUNT;
140af57ed9fSAtsushi Murai     if (hs->length) {	/* packet is ready. */
141af57ed9fSAtsushi Murai       bp = mballoc(hs->length, MB_ASYNC);
142af57ed9fSAtsushi Murai       mbwrite(bp, hs->hbuff, hs->length);
143af57ed9fSAtsushi Murai       hs->length = 0;
144af57ed9fSAtsushi Murai       return(bp);
145af57ed9fSAtsushi Murai     }
146af57ed9fSAtsushi Murai     break;
147af57ed9fSAtsushi Murai   case HDLC_ESC:
148af57ed9fSAtsushi Murai     if (!(hs->mode & MODE_ESC)) {
149af57ed9fSAtsushi Murai       hs->mode |= MODE_ESC;
150af57ed9fSAtsushi Murai       break;
151af57ed9fSAtsushi Murai     }
152af57ed9fSAtsushi Murai     /* Fall into ... */
153af57ed9fSAtsushi Murai   default:
154af57ed9fSAtsushi Murai     if (hs->length >= HDLCSIZE) {
155af57ed9fSAtsushi Murai       /* packet is too large, discard it */
156af57ed9fSAtsushi Murai       logprintf("too large, diacarding.\n");
157af57ed9fSAtsushi Murai       hs->length = 0;
158af57ed9fSAtsushi Murai       hs->mode = MODE_HUNT;
159af57ed9fSAtsushi Murai       break;
160af57ed9fSAtsushi Murai     }
161af57ed9fSAtsushi Murai     if (hs->mode & MODE_ESC) {
162af57ed9fSAtsushi Murai       c ^= HDLC_XOR;
163af57ed9fSAtsushi Murai       hs->mode &= ~MODE_ESC;
164af57ed9fSAtsushi Murai     }
165af57ed9fSAtsushi Murai     hs->hbuff[hs->length++] = c;
166af57ed9fSAtsushi Murai     break;
167af57ed9fSAtsushi Murai   }
168af57ed9fSAtsushi Murai   return NULLBUFF;
169af57ed9fSAtsushi Murai }
170af57ed9fSAtsushi Murai 
171af57ed9fSAtsushi Murai void
172af57ed9fSAtsushi Murai AsyncInput(buff, cnt)
173af57ed9fSAtsushi Murai u_char *buff;
174af57ed9fSAtsushi Murai int cnt;
175af57ed9fSAtsushi Murai {
176af57ed9fSAtsushi Murai   struct mbuf *bp;
177af57ed9fSAtsushi Murai 
178af57ed9fSAtsushi Murai   OsAddInOctets(cnt);
179af57ed9fSAtsushi Murai   while (cnt > 0) {
180af57ed9fSAtsushi Murai     bp = AsyncDecode(*buff++);
181af57ed9fSAtsushi Murai     if (bp)
182af57ed9fSAtsushi Murai       HdlcInput(bp);
183af57ed9fSAtsushi Murai     cnt--;
184af57ed9fSAtsushi Murai   }
185af57ed9fSAtsushi Murai }
186