xref: /freebsd/usr.sbin/ppp/async.c (revision 53c9f6c0c48df668bb8fa282cd0b12cb8690bcce)
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"
2853c9f6c0SAtsushi Murai #include "vars.h"
29af57ed9fSAtsushi Murai 
30af57ed9fSAtsushi Murai #define HDLCSIZE	(MAX_MRU*2+6)
31af57ed9fSAtsushi Murai 
32af57ed9fSAtsushi Murai struct async_state {
33af57ed9fSAtsushi Murai   int mode;
34af57ed9fSAtsushi Murai   int length;
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;
5053c9f6c0SAtsushi Murai   stp->length = 0;
51af57ed9fSAtsushi Murai   stp->my_accmap = stp->his_accmap = 0xffffffff;
52af57ed9fSAtsushi Murai }
53af57ed9fSAtsushi Murai 
54af57ed9fSAtsushi Murai void
55af57ed9fSAtsushi Murai SetLinkParams(lcp)
56af57ed9fSAtsushi Murai struct lcpstate *lcp;
57af57ed9fSAtsushi Murai {
58af57ed9fSAtsushi Murai   struct async_state *stp = &AsyncState;
59af57ed9fSAtsushi Murai 
60af57ed9fSAtsushi Murai   stp->my_accmap = lcp->want_accmap;
61af57ed9fSAtsushi Murai   stp->his_accmap = lcp->his_accmap;
62af57ed9fSAtsushi Murai }
63af57ed9fSAtsushi Murai 
64af57ed9fSAtsushi Murai /*
65af57ed9fSAtsushi Murai  * Encode into async HDLC byte code if necessary
66af57ed9fSAtsushi Murai  */
67af57ed9fSAtsushi Murai static void
68af57ed9fSAtsushi Murai HdlcPutByte(cp, c, proto)
69af57ed9fSAtsushi Murai u_char **cp;
70af57ed9fSAtsushi Murai u_char c;
71af57ed9fSAtsushi Murai int proto;
72af57ed9fSAtsushi Murai {
73af57ed9fSAtsushi Murai   u_char *wp;
74af57ed9fSAtsushi Murai 
75af57ed9fSAtsushi Murai   wp = *cp;
76af57ed9fSAtsushi Murai   if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c))))
77af57ed9fSAtsushi Murai 	|| (c == HDLC_ESC) || (c == HDLC_SYN)) {
78af57ed9fSAtsushi Murai     *wp++ = HDLC_ESC;
79af57ed9fSAtsushi Murai     c ^= HDLC_XOR;
80af57ed9fSAtsushi Murai   }
81af57ed9fSAtsushi Murai   if (EscMap[32] && EscMap[c >> 3] & (c&7)) {
82af57ed9fSAtsushi Murai     *wp++ = HDLC_ESC;
83af57ed9fSAtsushi Murai     c ^= HDLC_XOR;
84af57ed9fSAtsushi Murai   }
85af57ed9fSAtsushi Murai   *wp++ = c;
86af57ed9fSAtsushi Murai   *cp = wp;
87af57ed9fSAtsushi Murai }
88af57ed9fSAtsushi Murai 
89af57ed9fSAtsushi Murai void
90af57ed9fSAtsushi Murai AsyncOutput(pri, bp, proto)
91af57ed9fSAtsushi Murai int pri;
92af57ed9fSAtsushi Murai struct mbuf *bp;
93af57ed9fSAtsushi Murai int proto;
94af57ed9fSAtsushi Murai {
95af57ed9fSAtsushi Murai   struct async_state *hs = &AsyncState;
96af57ed9fSAtsushi Murai   u_char *cp, *sp, *ep;
97af57ed9fSAtsushi Murai   struct mbuf *wp;
98af57ed9fSAtsushi Murai   int cnt;
99af57ed9fSAtsushi Murai 
100af57ed9fSAtsushi Murai   if (plength(bp) > HDLCSIZE) {
101af57ed9fSAtsushi Murai     pfree(bp);
102af57ed9fSAtsushi Murai     return;
103af57ed9fSAtsushi Murai   }
104af57ed9fSAtsushi Murai   cp = hs->xbuff;
105af57ed9fSAtsushi Murai   ep = cp + HDLCSIZE - 10;
106af57ed9fSAtsushi Murai   wp = bp;
107af57ed9fSAtsushi Murai   *cp ++ = HDLC_SYN;
108af57ed9fSAtsushi Murai   while (wp) {
109af57ed9fSAtsushi Murai     sp = MBUF_CTOP(wp);
110af57ed9fSAtsushi Murai     for (cnt = wp->cnt; cnt > 0; cnt--) {
111af57ed9fSAtsushi Murai       HdlcPutByte(&cp, *sp++, proto);
112af57ed9fSAtsushi Murai       if (cp >= ep) {
113af57ed9fSAtsushi Murai 	pfree(bp);
114af57ed9fSAtsushi Murai 	return;
115af57ed9fSAtsushi Murai       }
116af57ed9fSAtsushi Murai     }
117af57ed9fSAtsushi Murai     wp = wp->next;
118af57ed9fSAtsushi Murai   }
119af57ed9fSAtsushi Murai   *cp ++ = HDLC_SYN;
120af57ed9fSAtsushi Murai 
121af57ed9fSAtsushi Murai   cnt = cp - hs->xbuff;
122af57ed9fSAtsushi Murai   LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt);
123af57ed9fSAtsushi Murai   WriteModem(pri, (char *)hs->xbuff, cnt);
124af57ed9fSAtsushi Murai   OsAddOutOctets(cnt);
125af57ed9fSAtsushi Murai   pfree(bp);
126af57ed9fSAtsushi Murai }
127af57ed9fSAtsushi Murai 
128af57ed9fSAtsushi Murai struct mbuf *
129af57ed9fSAtsushi Murai AsyncDecode(c)
130af57ed9fSAtsushi Murai u_char c;
131af57ed9fSAtsushi Murai {
132af57ed9fSAtsushi Murai   struct async_state *hs = &AsyncState;
133af57ed9fSAtsushi Murai   struct mbuf *bp;
134af57ed9fSAtsushi Murai 
135af57ed9fSAtsushi Murai   if ((hs->mode & MODE_HUNT) && c != HDLC_SYN)
136af57ed9fSAtsushi Murai     return(NULLBUFF);
137af57ed9fSAtsushi Murai 
138af57ed9fSAtsushi Murai   switch (c) {
139af57ed9fSAtsushi Murai   case HDLC_SYN:
140af57ed9fSAtsushi Murai     hs->mode &= ~MODE_HUNT;
141af57ed9fSAtsushi Murai     if (hs->length) {	/* packet is ready. */
142af57ed9fSAtsushi Murai       bp = mballoc(hs->length, MB_ASYNC);
143af57ed9fSAtsushi Murai       mbwrite(bp, hs->hbuff, hs->length);
144af57ed9fSAtsushi Murai       hs->length = 0;
145af57ed9fSAtsushi Murai       return(bp);
146af57ed9fSAtsushi Murai     }
147af57ed9fSAtsushi Murai     break;
148af57ed9fSAtsushi Murai   case HDLC_ESC:
149af57ed9fSAtsushi Murai     if (!(hs->mode & MODE_ESC)) {
150af57ed9fSAtsushi Murai       hs->mode |= MODE_ESC;
151af57ed9fSAtsushi Murai       break;
152af57ed9fSAtsushi Murai     }
153af57ed9fSAtsushi Murai     /* Fall into ... */
154af57ed9fSAtsushi Murai   default:
155af57ed9fSAtsushi Murai     if (hs->length >= HDLCSIZE) {
156af57ed9fSAtsushi Murai       /* packet is too large, discard it */
157af57ed9fSAtsushi Murai       logprintf("too large, diacarding.\n");
158af57ed9fSAtsushi Murai       hs->length = 0;
159af57ed9fSAtsushi Murai       hs->mode = MODE_HUNT;
160af57ed9fSAtsushi Murai       break;
161af57ed9fSAtsushi Murai     }
162af57ed9fSAtsushi Murai     if (hs->mode & MODE_ESC) {
163af57ed9fSAtsushi Murai       c ^= HDLC_XOR;
164af57ed9fSAtsushi Murai       hs->mode &= ~MODE_ESC;
165af57ed9fSAtsushi Murai     }
166af57ed9fSAtsushi Murai     hs->hbuff[hs->length++] = c;
167af57ed9fSAtsushi Murai     break;
168af57ed9fSAtsushi Murai   }
169af57ed9fSAtsushi Murai   return NULLBUFF;
170af57ed9fSAtsushi Murai }
171af57ed9fSAtsushi Murai 
172af57ed9fSAtsushi Murai void
173af57ed9fSAtsushi Murai AsyncInput(buff, cnt)
174af57ed9fSAtsushi Murai u_char *buff;
175af57ed9fSAtsushi Murai int cnt;
176af57ed9fSAtsushi Murai {
177af57ed9fSAtsushi Murai   struct mbuf *bp;
178af57ed9fSAtsushi Murai 
179af57ed9fSAtsushi Murai   OsAddInOctets(cnt);
18053c9f6c0SAtsushi Murai   if (DEV_IS_SYNC) {
18153c9f6c0SAtsushi Murai     bp = mballoc(cnt, MB_ASYNC);
18253c9f6c0SAtsushi Murai     bcopy(buff, MBUF_CTOP(bp), cnt);
18353c9f6c0SAtsushi Murai     bp->cnt = cnt;
18453c9f6c0SAtsushi Murai     HdlcInput(bp);
18553c9f6c0SAtsushi Murai   } else {
186af57ed9fSAtsushi Murai     while (cnt > 0) {
187af57ed9fSAtsushi Murai       bp = AsyncDecode(*buff++);
188af57ed9fSAtsushi Murai       if (bp)
189af57ed9fSAtsushi Murai         HdlcInput(bp);
190af57ed9fSAtsushi Murai       cnt--;
191af57ed9fSAtsushi Murai     }
192af57ed9fSAtsushi Murai   }
19353c9f6c0SAtsushi Murai }
194