xref: /freebsd/usr.sbin/ppp/acf.c (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
15d9e6103SBrian Somers /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
45d9e6103SBrian Somers  * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
55d9e6103SBrian Somers  * All rights reserved.
65d9e6103SBrian Somers  *
75d9e6103SBrian Somers  * Redistribution and use in source and binary forms, with or without
85d9e6103SBrian Somers  * modification, are permitted provided that the following conditions
95d9e6103SBrian Somers  * are met:
105d9e6103SBrian Somers  * 1. Redistributions of source code must retain the above copyright
115d9e6103SBrian Somers  *    notice, this list of conditions and the following disclaimer.
125d9e6103SBrian Somers  * 2. Redistributions in binary form must reproduce the above copyright
135d9e6103SBrian Somers  *    notice, this list of conditions and the following disclaimer in the
145d9e6103SBrian Somers  *    documentation and/or other materials provided with the distribution.
155d9e6103SBrian Somers  *
165d9e6103SBrian Somers  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
175d9e6103SBrian Somers  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185d9e6103SBrian Somers  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195d9e6103SBrian Somers  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
205d9e6103SBrian Somers  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215d9e6103SBrian Somers  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
225d9e6103SBrian Somers  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235d9e6103SBrian Somers  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245d9e6103SBrian Somers  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255d9e6103SBrian Somers  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265d9e6103SBrian Somers  * SUCH DAMAGE.
275d9e6103SBrian Somers  *
2897d92980SPeter Wemm  * $FreeBSD$
295d9e6103SBrian Somers  */
305d9e6103SBrian Somers 
315d9e6103SBrian Somers #include <sys/types.h>
325d9e6103SBrian Somers 
335d9e6103SBrian Somers #include <stdio.h>
345d9e6103SBrian Somers #include <termios.h>
355d9e6103SBrian Somers 
365d9e6103SBrian Somers #include "defs.h"
375d9e6103SBrian Somers #include "layer.h"
385d9e6103SBrian Somers #include "timer.h"
395d9e6103SBrian Somers #include "fsm.h"
405d9e6103SBrian Somers #include "log.h"
415d9e6103SBrian Somers #include "mbuf.h"
425d9e6103SBrian Somers #include "acf.h"
435d9e6103SBrian Somers #include "proto.h"
445d9e6103SBrian Somers #include "throughput.h"
455d9e6103SBrian Somers #include "lqr.h"
465d9e6103SBrian Somers #include "hdlc.h"
471038894eSBrian Somers #include "lcp.h"
485d9e6103SBrian Somers #include "ccp.h"
495d9e6103SBrian Somers #include "link.h"
505d9e6103SBrian Somers #include "descriptor.h"
515d9e6103SBrian Somers #include "async.h"
525d9e6103SBrian Somers #include "physical.h"
535d9e6103SBrian Somers 
545d9e6103SBrian Somers int
555d9e6103SBrian Somers acf_WrapperOctets(struct lcp *lcp, u_short proto)
565d9e6103SBrian Somers {
575d9e6103SBrian Somers   return (proto == PROTO_LCP || lcp->his_acfcomp == 0) ? 2 : 0;
585d9e6103SBrian Somers }
595d9e6103SBrian Somers 
605d9e6103SBrian Somers static struct mbuf *
61057f1760SBrian Somers acf_LayerPush(struct bundle *b __unused, struct link *l, struct mbuf *bp,
62057f1760SBrian Somers               int pri __unused, u_short *proto)
635d9e6103SBrian Somers {
645d9e6103SBrian Somers   const u_char cp[2] = { HDLC_ADDR, HDLC_UI };
655d9e6103SBrian Somers 
66411675baSBrian Somers   if (*proto == PROTO_LCP || l->lcp.his_acfcomp == 0) {
6726af0ae9SBrian Somers     bp = m_prepend(bp, cp, 2, 0);
6826af0ae9SBrian Somers     m_settype(bp, MB_ACFOUT);
69411675baSBrian Somers   }
705d9e6103SBrian Somers 
715d9e6103SBrian Somers   return bp;
725d9e6103SBrian Somers }
735d9e6103SBrian Somers 
745d9e6103SBrian Somers static struct mbuf *
75057f1760SBrian Somers acf_LayerPull(struct bundle *b __unused, struct link *l, struct mbuf *bp,
76057f1760SBrian Somers 	      u_short *proto __unused)
775d9e6103SBrian Somers {
785d9e6103SBrian Somers   struct physical *p = link2physical(l);
795d9e6103SBrian Somers   u_char cp[2];
805d9e6103SBrian Somers 
815d9e6103SBrian Somers   if (!p) {
825d9e6103SBrian Somers     log_Printf(LogERROR, "Can't Pull an acf packet from a logical link\n");
835d9e6103SBrian Somers     return bp;
845d9e6103SBrian Somers   }
855d9e6103SBrian Somers 
865d9e6103SBrian Somers   if (mbuf_View(bp, cp, 2) == 2) {
875d9e6103SBrian Somers     if (!p->link.lcp.want_acfcomp) {
885d9e6103SBrian Somers       /* We expect the packet not to be compressed */
895d9e6103SBrian Somers       bp = mbuf_Read(bp, cp, 2);
905d9e6103SBrian Somers       if (cp[0] != HDLC_ADDR) {
91a57095e7SBrian Somers         p->hdlc.lqm.ifInErrors++;
925d9e6103SBrian Somers         p->hdlc.stats.badaddr++;
935d9e6103SBrian Somers         log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]);
9426af0ae9SBrian Somers         m_freem(bp);
955d9e6103SBrian Somers         return NULL;
965d9e6103SBrian Somers       }
975d9e6103SBrian Somers       if (cp[1] != HDLC_UI) {
98a57095e7SBrian Somers         p->hdlc.lqm.ifInErrors++;
995d9e6103SBrian Somers         p->hdlc.stats.badcommand++;
1005d9e6103SBrian Somers         log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]);
10126af0ae9SBrian Somers         m_freem(bp);
1025d9e6103SBrian Somers         return NULL;
1035d9e6103SBrian Somers       }
10426af0ae9SBrian Somers       m_settype(bp, MB_ACFIN);
1055d9e6103SBrian Somers     } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
1065d9e6103SBrian Somers       /*
1075d9e6103SBrian Somers        * We can receive compressed packets, but the peer still sends
1085d9e6103SBrian Somers        * uncompressed packets (or maybe this is a PROTO_LCP packet) !
1095d9e6103SBrian Somers        */
1105d9e6103SBrian Somers       bp = mbuf_Read(bp, cp, 2);
11126af0ae9SBrian Somers       m_settype(bp, MB_ACFIN);
1125d9e6103SBrian Somers     }
1135d9e6103SBrian Somers   }
1145d9e6103SBrian Somers 
1155d9e6103SBrian Somers   return bp;
1165d9e6103SBrian Somers }
1175d9e6103SBrian Somers 
1185d9e6103SBrian Somers struct layer acflayer = { LAYER_ACF, "acf", acf_LayerPush, acf_LayerPull };
119