2 * PPP Async HDLC Module
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 #include <sys/types.h>
39 #include "throughput.h"
42 #include "descriptor.h"
45 #define MODE_HUNT 0x01
49 async_Init(struct async *async)
51 async->mode = MODE_HUNT;
53 async->my_accmap = async->his_accmap = 0xffffffff;
54 memset(async->cfg.EscMap, '\0', sizeof async->cfg.EscMap);
58 async_SetLinkParams(struct async *async, struct lcp *lcp)
60 async->my_accmap = lcp->want_accmap;
61 async->his_accmap = lcp->his_accmap | lcp->want_accmap;
65 * Encode into async HDLC byte code
68 async_Encode(struct async *async, u_char **cp, u_char c, int proto)
73 if ((c < 0x20 && (proto == PROTO_LCP || (async->his_accmap & (1 << c))))
74 || (c == HDLC_ESC) || (c == HDLC_SYN)) {
78 if (async->cfg.EscMap[32] && async->cfg.EscMap[c >> 3] & (1 << (c & 7))) {
87 async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
88 int pri, u_short *proto)
90 struct physical *p = link2physical(l);
95 if (!p || m_length(bp) > HDLCSIZE) {
101 ep = cp + HDLCSIZE - 10;
106 for (cnt = wp->m_len; cnt > 0; cnt--) {
107 async_Encode(&p->async, &cp, *sp++, *proto);
117 cnt = cp - p->async.xbuff;
119 bp = m_get(cnt, MB_ASYNCOUT);
120 memcpy(MBUF_CTOP(bp), p->async.xbuff, cnt);
121 log_DumpBp(LogASYNC, "Write", bp);
127 async_Decode(struct async *async, u_char c)
131 if ((async->mode & MODE_HUNT) && c != HDLC_SYN)
136 async->mode &= ~MODE_HUNT;
137 if (async->length) { /* packet is ready. */
138 bp = m_get(async->length, MB_ASYNCIN);
139 mbuf_Write(bp, async->hbuff, async->length);
145 if (!(async->mode & MODE_ESC)) {
146 async->mode |= MODE_ESC;
151 if (async->length >= HDLCSIZE) {
152 /* packet is too large, discard it */
153 log_Printf(LogWARN, "Packet too large (%d), discarding.\n",
156 async->mode = MODE_HUNT;
159 if (async->mode & MODE_ESC) {
161 async->mode &= ~MODE_ESC;
163 async->hbuff[async->length++] = c;
170 async_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
173 struct mbuf *nbp, **last;
174 struct physical *p = link2physical(l);
179 log_Printf(LogERROR, "Can't Pull an async packet from a logical link\n");
185 log_DumpBp(LogASYNC, "Read", bp);
188 for (cnt = bp->m_len; cnt; cnt--) {
189 *last = async_Decode(&p->async, *ch++);
191 last = &(*last)->m_nextpkt;
199 struct layer asynclayer =
200 { LAYER_ASYNC, "async", async_LayerPush, async_LayerPull };