summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/hdlc.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1999-05-08 11:07:56 +0000
committerbrian <brian@FreeBSD.org>1999-05-08 11:07:56 +0000
commitab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4 (patch)
treee79816f983bd5a5be86a78fe0aafbd00a13ac2db /usr.sbin/ppp/hdlc.c
parent713dd62834d401cc7b9b394a4b916ab9e5e3d4d5 (diff)
downloadFreeBSD-src-ab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4.zip
FreeBSD-src-ab7d88ae2d8ea955c6193cc242b9cee4d58f8fd4.tar.gz
o Redesign the layering mechanism and make the aliasing code part of
the layering. We now ``stack'' layers as soon as we open the device (when we figure out what we're dealing with). A static set of `dispatch' routines are also declared for dealing with incoming packets after they've been `pulled' up through the stacked layers. Physical devices are now assigned handlers based on the device type when they're opened. For the moment there are three device types; ttys, execs and tcps. o Increment version number to 2.2 o Make an entry in [uw]tmp for non-tty -direct invocations (after pap/chap authentication). o Make throughput counters quad_t's o Account for the absolute number of mbuf malloc()s and free()s in ``show mem''. o ``show modem'' becomes ``show physical''.
Diffstat (limited to 'usr.sbin/ppp/hdlc.c')
-rw-r--r--usr.sbin/ppp/hdlc.c325
1 files changed, 59 insertions, 266 deletions
diff --git a/usr.sbin/ppp/hdlc.c b/usr.sbin/ppp/hdlc.c
index 2176b5f..a2042ff 100644
--- a/usr.sbin/ppp/hdlc.c
+++ b/usr.sbin/ppp/hdlc.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: hdlc.c,v 1.40 1999/03/29 08:21:26 brian Exp $
+ * $Id: hdlc.c,v 1.41 1999/04/03 11:54:00 brian Exp $
*
* TODO:
*/
@@ -32,6 +32,7 @@
#include <termios.h>
#include "defs.h"
+#include "layer.h"
#include "command.h"
#include "mbuf.h"
#include "log.h"
@@ -39,7 +40,7 @@
#include "fsm.h"
#include "lqr.h"
#include "hdlc.h"
-#include "lcpproto.h"
+#include "proto.h"
#include "iplist.h"
#include "throughput.h"
#include "slcompress.h"
@@ -112,12 +113,15 @@ hdlc_Init(struct hdlc *hdlc, struct lcp *lcp)
* HDLC FCS computation. Read RFC 1171 Appendix B and CCITT X.25 section
* 2.27 for further details.
*/
-inline u_short
-hdlc_Fcs(u_short fcs, u_char * cp, int len)
+u_short
+hdlc_Fcs(u_char *cp, size_t len)
{
+ u_short fcs = INITFCS;
+
while (len--)
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
- return (fcs);
+
+ return fcs;
}
static inline u_short
@@ -140,107 +144,41 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m)
return (fcs);
}
-void
-hdlc_Output(struct link *l, int pri, u_short proto, struct mbuf *bp)
+int
+hdlc_WrapperOctets(struct lcp *lcp, u_short proto)
{
- struct physical *p = link2physical(l);
- struct mbuf *mhp, *mfcs;
+ return 2;
+}
+
+static struct mbuf *
+hdlc_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ struct mbuf *last;
u_char *cp;
u_short fcs;
- if (!p || physical_IsSync(p))
- mfcs = NULL;
- else
- mfcs = mbuf_Alloc(2, MB_HDLCOUT);
-
- mhp = mbuf_Alloc(4, MB_HDLCOUT);
- mhp->cnt = 0;
- cp = MBUF_CTOP(mhp);
- if (p && (proto == PROTO_LCP || l->lcp.his_acfcomp == 0)) {
- *cp++ = HDLC_ADDR;
- *cp++ = HDLC_UI;
- mhp->cnt += 2;
- }
-
- /*
- * If possible, compress protocol field.
- */
- if (l->lcp.his_protocomp && (proto & 0xff00) == 0) {
- *cp++ = proto;
- mhp->cnt++;
- } else {
- *cp++ = proto >> 8;
- *cp = proto & 0377;
- mhp->cnt += 2;
- }
+ fcs = HdlcFcsBuf(INITFCS, bp);
+ fcs = ~fcs;
- mhp->next = bp = mbuf_Contiguous(bp);
+ for (last = bp; last->next; last = last->next)
+ ;
- if (!p) {
- /*
- * This is where we multiplex the data over our available physical
- * links. We don't frame our logical link data. Instead we wait
- * for the logical link implementation to chop our data up and pile
- * it into the physical links by re-calling this function with the
- * encapsulated fragments.
- */
- link_Output(l, pri, mhp);
- return;
- }
-
- bp->next = mfcs; /* Tack mfcs onto the end */
-
- p->hdlc.lqm.OutOctets += mbuf_Length(mhp) + 1;
- p->hdlc.lqm.OutPackets++;
-
- if (proto == PROTO_LQR) {
- /* Overwrite the entire packet */
- struct lqrdata lqr;
-
- lqr.MagicNumber = p->link.lcp.want_magic;
- lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
- lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
- lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
- lqr.PeerInLQRs = p->hdlc.lqm.lqr.SaveInLQRs;
- lqr.PeerInPackets = p->hdlc.lqm.SaveInPackets;
- lqr.PeerInDiscards = p->hdlc.lqm.SaveInDiscards;
- lqr.PeerInErrors = p->hdlc.lqm.SaveInErrors;
- lqr.PeerInOctets = p->hdlc.lqm.SaveInOctets;
- lqr.PeerOutPackets = p->hdlc.lqm.OutPackets;
- lqr.PeerOutOctets = p->hdlc.lqm.OutOctets;
- if (p->hdlc.lqm.lqr.peer.LastOutLQRs == p->hdlc.lqm.lqr.OutLQRs) {
- /*
- * only increment if it's the first time or we've got a reply
- * from the last one
- */
- lqr.PeerOutLQRs = ++p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output", &lqr);
- } else {
- lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output (again)", &lqr);
- }
- lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
- }
-
- if (mfcs) {
- mfcs->cnt = 0;
- fcs = HdlcFcsBuf(INITFCS, mhp);
- fcs = ~fcs;
- cp = MBUF_CTOP(mfcs);
- *cp++ = fcs & 0377; /* Low byte first!! */
- *cp++ = fcs >> 8;
- mfcs->cnt = 2;
+ if (last->size - last->offset - last->cnt >= 2) {
+ cp = MBUF_CTOP(last) + last->cnt;
+ last->cnt += 2;
+ } else {
+ struct mbuf *tail = mbuf_Alloc(2, MB_HDLCOUT);
+ last->next = tail;
+ cp = MBUF_CTOP(tail);
}
- log_DumpBp(LogHDLC, "hdlc_Output", mhp);
+ *cp++ = fcs & 0377; /* Low byte first (nothing like consistency) */
+ *cp++ = fcs >> 8;
- link_ProtocolRecord(l, proto, PROTO_OUT);
- log_Printf(LogDEBUG, "hdlc_Output: proto = 0x%04x\n", proto);
+ log_DumpBp(LogHDLC, "hdlc_Output", bp);
- if (physical_IsSync(p))
- link_Output(l, pri, mhp); /* Send it raw */
- else
- async_Output(pri, mhp, proto, p);
+ return bp;
}
/* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
@@ -369,192 +307,45 @@ hdlc_Protocol2Nam(u_short proto)
return "unrecognised protocol";
}
-void
-hdlc_DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp,
- struct link *l)
+static struct mbuf *
+hdlc_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
+ u_short *proto)
{
struct physical *p = link2physical(l);
- u_char *cp;
- const char *type;
-
- log_Printf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto);
-
- /* decompress everything. CCP needs uncompressed data too */
- if ((bp = ccp_Decompress(&l->ccp, &proto, bp)) == NULL)
- return;
-
- switch (proto) {
- case PROTO_LCP:
- lcp_Input(&l->lcp, bp);
- break;
- case PROTO_PAP:
- if (p)
- pap_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: PAP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_CBCP:
- if (p)
- cbcp_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: CBCP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_LQR:
- if (p) {
- p->hdlc.lqm.lqr.SaveInLQRs++;
- lqr_Input(p, bp);
- } else {
- log_Printf(LogERROR, "DecodePacket: LQR: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_CHAP:
- if (p)
- chap_Input(p, bp);
- else {
- log_Printf(LogERROR, "DecodePacket: CHAP: Not a physical link !\n");
- mbuf_Free(bp);
- }
- break;
- case PROTO_VJUNCOMP:
- case PROTO_VJCOMP:
- bp = vj_Input(&bundle->ncp.ipcp, bp, proto);
- if (bp == NULL)
- break;
- /* fall down */
- case PROTO_IP:
- ip_Input(bundle, bp);
- break;
- case PROTO_IPCP:
- ipcp_Input(&bundle->ncp.ipcp, bundle, bp);
- break;
- case PROTO_CCP:
- ccp_Input(&l->ccp, bundle, bp);
- break;
- case PROTO_MP:
- if (bundle->ncp.mp.active) {
- if (p)
- mp_Input(&bundle->ncp.mp, bp, p);
- else {
- log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
- mbuf_Free(bp);
- }
- break;
- }
- /* Fall through */
- default:
- switch (proto) {
- case PROTO_MP:
- case PROTO_COMPD:
- case PROTO_ICOMPD:
- type = "Unexpected";
- break;
- default:
- type = "Unknown";
- break;
- }
- log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n", type, proto,
- hdlc_Protocol2Nam(proto));
- bp->offset -= 2;
- bp->cnt += 2;
- cp = MBUF_CTOP(bp);
- lcp_SendProtoRej(&l->lcp, cp, bp->cnt);
- if (p) {
- p->hdlc.lqm.SaveInDiscards++;
- p->hdlc.stats.unknownproto++;
- }
- mbuf_Free(bp);
- break;
- }
-}
+ u_short fcs;
+ int len;
-static int
-hdlc_GetProto(const u_char *cp, u_short *proto)
-{
- *proto = *cp;
- if (!(*proto & 1)) {
- *proto = (*proto << 8) | cp[1];
- return 2;
+ if (!p) {
+ log_Printf(LogERROR, "Can't Pull a hdlc packet from a logical link\n");
+ return bp;
}
- return 1;
-}
-
-void
-hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical)
-{
- u_short fcs, proto;
- u_char *cp, addr, ctrl;
- int n;
log_DumpBp(LogHDLC, "hdlc_Input:", bp);
- if (physical_IsSync(physical))
- fcs = GOODFCS;
- else
- fcs = hdlc_Fcs(INITFCS, MBUF_CTOP(bp), bp->cnt);
- physical->hdlc.lqm.SaveInOctets += bp->cnt + 1;
+
+ fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->cnt);
log_Printf(LogDEBUG, "%s: hdlc_Input: fcs = %04x (%s)\n",
- physical->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
+ p->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
+
if (fcs != GOODFCS) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badfcs++;
+ p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.stats.badfcs++;
mbuf_Free(bp);
- return;
+ return NULL;
}
- if (!physical_IsSync(physical))
- bp->cnt -= 2; /* discard FCS part */
- if (bp->cnt < 2) { /* XXX: raise this bar ? */
+ p->hdlc.lqm.SaveInOctets += bp->cnt + 1;
+ p->hdlc.lqm.SaveInPackets++;
+
+ len = mbuf_Length(bp);
+ if (len < 4) { /* rfc1662 section 4.3 */
mbuf_Free(bp);
- return;
- }
- cp = MBUF_CTOP(bp);
-
- if (!physical->link.lcp.want_acfcomp) {
- /* We expect the packet not to be compressed */
- addr = *cp++;
- if (addr != HDLC_ADDR) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badaddr++;
- log_Printf(LogDEBUG, "hdlc_Input: addr %02x\n", *cp);
- mbuf_Free(bp);
- return;
- }
- ctrl = *cp++;
- if (ctrl != HDLC_UI) {
- physical->hdlc.lqm.SaveInErrors++;
- physical->hdlc.stats.badcommand++;
- log_Printf(LogDEBUG, "hdlc_Input: %02x\n", *cp);
- mbuf_Free(bp);
- return;
- }
- bp->offset += 2;
- bp->cnt -= 2;
- } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
- /*
- * We can receive compressed packets, but the peer still sends
- * uncompressed packets !
- */
- cp += 2;
- bp->offset += 2;
- bp->cnt -= 2;
+ bp = NULL;
}
- n = hdlc_GetProto(cp, &proto);
- bp->offset += n;
- bp->cnt -= n;
- if (!physical->link.lcp.want_protocomp && n == 1)
- log_Printf(LogHDLC, "%s: Warning: received a proto-compressed packet !\n",
- physical->link.name);
-
- link_ProtocolRecord(&physical->link, proto, PROTO_IN);
- physical->hdlc.lqm.SaveInPackets++;
+ bp = mbuf_Truncate(bp, len - 2); /* discard the FCS */
- hdlc_DecodePacket(bundle, proto, bp, &physical->link);
+ return bp;
}
/*
@@ -650,3 +441,5 @@ hdlc_StopTimer(struct hdlc *hdlc)
{
timer_Stop(&hdlc->ReportTimer);
}
+
+struct layer hdlclayer = { LAYER_HDLC, "hdlc", hdlc_LayerPush, hdlc_LayerPull };
OpenPOWER on IntegriCloud