acf.c revision 330449
1295484Semaste/*-
2295484Semaste * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3295484Semaste *
4295484Semaste * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
5295484Semaste * All rights reserved.
6295484Semaste *
7295484Semaste * Redistribution and use in source and binary forms, with or without
8295484Semaste * modification, are permitted provided that the following conditions
9295484Semaste * are met:
10295484Semaste * 1. Redistributions of source code must retain the above copyright
11295484Semaste *    notice, this list of conditions and the following disclaimer.
12295484Semaste * 2. Redistributions in binary form must reproduce the above copyright
13295484Semaste *    notice, this list of conditions and the following disclaimer in the
14295484Semaste *    documentation and/or other materials provided with the distribution.
15295484Semaste *
16295484Semaste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17295484Semaste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18295484Semaste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19295484Semaste * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20295484Semaste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21295484Semaste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22295484Semaste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23295484Semaste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24295484Semaste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25295484Semaste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26295484Semaste * SUCH DAMAGE.
27295484Semaste *
28295484Semaste * $FreeBSD: stable/11/usr.sbin/ppp/acf.c 330449 2018-03-05 07:26:05Z eadler $
29295484Semaste */
30295484Semaste
31295484Semaste#include <sys/types.h>
32295484Semaste
33295484Semaste#include <stdio.h>
34295484Semaste#include <termios.h>
35295484Semaste
36295484Semaste#include "defs.h"
37295484Semaste#include "layer.h"
38295484Semaste#include "timer.h"
39295484Semaste#include "fsm.h"
40295484Semaste#include "log.h"
41295484Semaste#include "mbuf.h"
42295484Semaste#include "acf.h"
43295484Semaste#include "proto.h"
44295484Semaste#include "throughput.h"
45295484Semaste#include "lqr.h"
46295484Semaste#include "hdlc.h"
47295484Semaste#include "lcp.h"
48295484Semaste#include "ccp.h"
49295484Semaste#include "link.h"
50295484Semaste#include "descriptor.h"
51295484Semaste#include "async.h"
52295484Semaste#include "physical.h"
53295484Semaste
54295484Semasteint
55295484Semasteacf_WrapperOctets(struct lcp *lcp, u_short proto)
56295484Semaste{
57295484Semaste  return (proto == PROTO_LCP || lcp->his_acfcomp == 0) ? 2 : 0;
58295484Semaste}
59295484Semaste
60295484Semastestatic struct mbuf *
61295484Semasteacf_LayerPush(struct bundle *b __unused, struct link *l, struct mbuf *bp,
62295484Semaste              int pri __unused, u_short *proto)
63295484Semaste{
64295484Semaste  const u_char cp[2] = { HDLC_ADDR, HDLC_UI };
65295484Semaste
66295484Semaste  if (*proto == PROTO_LCP || l->lcp.his_acfcomp == 0) {
67295484Semaste    bp = m_prepend(bp, cp, 2, 0);
68295484Semaste    m_settype(bp, MB_ACFOUT);
69295484Semaste  }
70295484Semaste
71295484Semaste  return bp;
72295484Semaste}
73295484Semaste
74295484Semastestatic struct mbuf *
75295484Semasteacf_LayerPull(struct bundle *b __unused, struct link *l, struct mbuf *bp,
76295484Semaste	      u_short *proto __unused)
77295484Semaste{
78295484Semaste  struct physical *p = link2physical(l);
79295484Semaste  u_char cp[2];
80295484Semaste
81295484Semaste  if (!p) {
82295484Semaste    log_Printf(LogERROR, "Can't Pull an acf packet from a logical link\n");
83295484Semaste    return bp;
84295484Semaste  }
85295484Semaste
86295484Semaste  if (mbuf_View(bp, cp, 2) == 2) {
87295484Semaste    if (!p->link.lcp.want_acfcomp) {
88295484Semaste      /* We expect the packet not to be compressed */
89295484Semaste      bp = mbuf_Read(bp, cp, 2);
90295484Semaste      if (cp[0] != HDLC_ADDR) {
91295484Semaste        p->hdlc.lqm.ifInErrors++;
92295484Semaste        p->hdlc.stats.badaddr++;
93295484Semaste        log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]);
94295484Semaste        m_freem(bp);
95295484Semaste        return NULL;
96295484Semaste      }
97295484Semaste      if (cp[1] != HDLC_UI) {
98295484Semaste        p->hdlc.lqm.ifInErrors++;
99295484Semaste        p->hdlc.stats.badcommand++;
100295484Semaste        log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]);
101295484Semaste        m_freem(bp);
102295484Semaste        return NULL;
103295484Semaste      }
104295484Semaste      m_settype(bp, MB_ACFIN);
105295484Semaste    } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
106295484Semaste      /*
107295484Semaste       * We can receive compressed packets, but the peer still sends
108295484Semaste       * uncompressed packets (or maybe this is a PROTO_LCP packet) !
109295484Semaste       */
110295484Semaste      bp = mbuf_Read(bp, cp, 2);
111295484Semaste      m_settype(bp, MB_ACFIN);
112295484Semaste    }
113295484Semaste  }
114295484Semaste
115295484Semaste  return bp;
116295484Semaste}
117295484Semaste
118295484Semastestruct layer acflayer = { LAYER_ACF, "acf", acf_LayerPush, acf_LayerPull };
119295484Semaste