/*-
 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: src/usr.sbin/ppp/cbcp.c,v 1.26.26.1 2010/12/21 17:10:29 kensmith Exp $
 */

#include <sys/param.h>

#ifdef __FreeBSD__
#include <netinet/in.h>
#endif
#include <sys/un.h>

#include <string.h>
#include <termios.h>

#include "layer.h"
#include "defs.h"
#include "log.h"
#include "timer.h"
#include "descriptor.h"
#include "lqr.h"
#include "mbuf.h"
#include "fsm.h"
#include "throughput.h"
#include "hdlc.h"
#include "lcp.h"
#include "ccp.h"
#include "link.h"
#include "async.h"
#include "physical.h"
#include "proto.h"
#include "cbcp.h"
#include "mp.h"
#include "chat.h"
#include "auth.h"
#include "chap.h"
#include "datalink.h"

void
cbcp_Init(struct cbcp *cbcp, struct physical *p)
{
  cbcp->required = 0;
  cbcp->fsm.state = CBCP_CLOSED;
  cbcp->fsm.id = 0;
  cbcp->fsm.delay = 0;
  *cbcp->fsm.phone = '\0';
  memset(&cbcp->fsm.timer, '\0', sizeof cbcp->fsm.timer);
  cbcp->p = p;
}

static void cbcp_SendReq(struct cbcp *);
static void cbcp_SendResponse(struct cbcp *);
static void cbcp_SendAck(struct cbcp *);

static void
cbcp_Timeout(void *v)
{
  struct cbcp *cbcp = (struct cbcp *)v;

  timer_Stop(&cbcp->fsm.timer);
  if (cbcp->fsm.restart) {
    switch (cbcp->fsm.state) {
      case CBCP_CLOSED:
      case CBCP_STOPPED:
        log_Printf(LogCBCP, "%s: Urk - unexpected CBCP timeout !\n",
                   cbcp->p->dl->name);
        break;

      case CBCP_REQSENT:
        cbcp_SendReq(cbcp);
        break;
      case CBCP_RESPSENT:
        cbcp_SendResponse(cbcp);
        break;
      case CBCP_ACKSENT:
        cbcp_SendAck(cbcp);
        break;
    }
  } else {
    const char *missed;

    switch (cbcp->fsm.state) {
      case CBCP_STOPPED:
        missed = "REQ";
        break;
      case CBCP_REQSENT:
        missed = "RESPONSE";
        break;
      case CBCP_RESPSENT:
        missed = "ACK";
        break;
      case CBCP_ACKSENT:
        missed = "Terminate REQ";
        break;
      default:
        log_Printf(LogCBCP, "%s: Urk - unexpected CBCP timeout !\n",
                   cbcp->p->dl->name);
        missed = NULL;
        break;
    }
    if (missed)
      log_Printf(LogCBCP, "%s: Timeout waiting for peer %s\n",
                 cbcp->p->dl->name, missed);
    datalink_CBCPFailed(cbcp->p->dl);
  }
}

static void
cbcp_StartTimer(struct cbcp *cbcp, int timeout)
{
  timer_Stop(&cbcp->fsm.timer);
  cbcp->fsm.timer.func = cbcp_Timeout;
  cbcp->fsm.timer.name = "cbcp";
  cbcp->fsm.timer.load = timeout * SECTICKS;
  cbcp->fsm.timer.arg = cbcp;
  timer_Start(&cbcp->fsm.timer);
}

#define CBCP_CLOSED	(0)	/* Not in use */
#define CBCP_STOPPED	(1)	/* Waiting for a REQ */
#define CBCP_REQSENT	(2)	/* Waiting for a RESP */
#define CBCP_RESPSENT	(3)	/* Waiting for an ACK */
#define CBCP_ACKSENT	(4)	/* Waiting for an LCP Term REQ */

static const char * const cbcpname[] = {
  "closed", "stopped", "req-sent", "resp-sent", "ack-sent"
};

static const char *
cbcpstate(unsigned s)
{
  if (s < sizeof cbcpname / sizeof cbcpname[0])
    return cbcpname[s];
  return HexStr(s, NULL, 0);
}

static void
cbcp_NewPhase(struct cbcp *cbcp, int new)
{
  if (cbcp->fsm.state != new) {
    log_Printf(LogCBCP, "%s: State change %s --> %s\n", cbcp->p->dl->name,
               cbcpstate(cbcp->fsm.state), cbcpstate(new));
    cbcp->fsm.state = new;
  }
}

struct cbcp_header {
  u_char code;
  u_char id;
  u_int16_t length;	/* Network byte order */
};


/* cbcp_header::code values */
#define CBCP_REQ	(1)
#define CBCP_RESPONSE	(2)
#define CBCP_ACK	(3)

struct cbcp_data {
  u_char type;
  u_char length;
  u_char delay;
  char addr_start[253];	/* max cbcp_data length 255 + 1 for NULL */
};

/* cbcp_data::type values */
#define CBCP_NONUM	(1)
#define CBCP_CLIENTNUM	(2)
#define CBCP_SERVERNUM	(3)
#define CBCP_LISTNUM	(4)

static void
cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data)
{
  struct cbcp_header *head;
  struct mbuf *bp;

  bp = m_get(sizeof *head + data->length, MB_CBCPOUT);
  head = (struct cbcp_header *)MBUF_CTOP(bp);
  head->code = code;
  head->id = cbcp->fsm.id;
  head->length = htons(sizeof *head + data->length);
  memcpy(MBUF_CTOP(bp) + sizeof *head, data, data->length);
  log_DumpBp(LogDEBUG, "cbcp_Output", bp);
  link_PushPacket(&cbcp->p->link, bp, cbcp->p->dl->bundle,
                  LINK_QUEUES(&cbcp->p->link) - 1, PROTO_CBCP);
}

static const char *
cbcp_data_Type(unsigned type)
{
  static const char * const types[] = {
    "No callback", "User-spec", "Server-spec", "list"
  };

  if (type < 1 || type > sizeof types / sizeof types[0])
    return HexStr(type, NULL, 0);
  return types[type-1];
}

struct cbcp_addr {
  u_char type;
  char addr[sizeof ((struct cbcp_data *)0)->addr_start - 1];	/* ASCIIZ */
};

/* cbcp_data::type values */
#define CBCP_ADDR_PSTN	(1)

static void
cbcp_data_Show(struct cbcp_data *data)
{
  struct cbcp_addr *addr;
  char *end;

  addr = (struct cbcp_addr *)data->addr_start;
  end = (char *)data + data->length;
  *end = '\0';

  log_Printf(LogCBCP, " TYPE %s\n", cbcp_data_Type(data->type));
  if ((char *)&data->delay < end) {
    log_Printf(LogCBCP, " DELAY %d\n", data->delay);
    while (addr->addr < end) {
      if (addr->type == CBCP_ADDR_PSTN)
        log_Printf(LogCBCP, " ADDR %s\n", addr->addr);
      else
        log_Printf(LogCBCP, " ADDR type %d ??\n", (int)addr->type);
      addr = (struct cbcp_addr *)(addr->addr + strlen(addr->addr) + 1);
    }
  }
}

static void
cbcp_SendReq(struct cbcp *cbcp)
{
  struct cbcp_data data;
  struct cbcp_addr *addr;
  char list[sizeof cbcp->fsm.phone], *next;
  int len, max;

  /* Only callees send REQs */

  log_Printf(LogCBCP, "%s: SendReq(%d) state = %s\n", cbcp->p->dl->name,
             cbcp->fsm.id, cbcpstate(cbcp->fsm.state));
  data.type = cbcp->fsm.type;
  data.delay = 0;
  strncpy(list, cbcp->fsm.phone, sizeof list - 1);
  list[sizeof list - 1] = '\0';

  switch (data.type) {
    case CBCP_CLIENTNUM:
      addr = (struct cbcp_addr *)data.addr_start;
      addr->type = CBCP_ADDR_PSTN;
      *addr->addr = '\0';
      data.length = addr->addr - (char *)&data;
      break;

    case CBCP_LISTNUM:
      addr = (struct cbcp_addr *)data.addr_start;
      for (next = strtok(list, ","); next; next = strtok(NULL, ",")) {
        len = strlen(next);
        max = data.addr_start + sizeof data.addr_start - addr->addr - 1;
        if (len <= max) {
          addr->type = CBCP_ADDR_PSTN;
          strncpy(addr->addr, next, sizeof addr->addr - 1);
          addr->addr[sizeof addr->addr - 1] = '\0';
          addr = (struct cbcp_addr *)((char *)addr + len + 2);
        } else
          log_Printf(LogWARN, "CBCP ADDR \"%s\" skipped - packet too large\n",
                     next);
      }
      data.length = (char *)addr - (char *)&data;
      break;

    case CBCP_SERVERNUM:
      data.length = data.addr_start - (char *)&data;
      break;

    default:
      data.length = (char *)&data.delay - (char *)&data;
      break;
  }

  cbcp_data_Show(&data);
  cbcp_Output(cbcp, CBCP_REQ, &data);
  cbcp->fsm.restart--;
  cbcp_StartTimer(cbcp, cbcp->fsm.delay);
  cbcp_NewPhase(cbcp, CBCP_REQSENT);		/* Wait for a RESPONSE */
}

void
cbcp_Up(struct cbcp *cbcp)
{
  struct lcp *lcp = &cbcp->p->link.lcp;

  cbcp->fsm.delay = cbcp->p->dl->cfg.cbcp.delay;
  if (*cbcp->p->dl->peer.authname == '\0' ||
      !auth_SetPhoneList(cbcp->p->dl->peer.authname, cbcp->fsm.phone,
                         sizeof cbcp->fsm.phone)) {
    strncpy(cbcp->fsm.phone, cbcp->p->dl->cfg.cbcp.phone,
            sizeof cbcp->fsm.phone - 1);
    cbcp->fsm.phone[sizeof cbcp->fsm.phone - 1] = '\0';
  }

  if (lcp->want_callback.opmask) {
    if (*cbcp->fsm.phone == '\0')
      cbcp->fsm.type = CBCP_NONUM;
    else if (!strcmp(cbcp->fsm.phone, "*")) {
      cbcp->fsm.type = CBCP_SERVERNUM;
      *cbcp->fsm.phone = '\0';
    } else
      cbcp->fsm.type = CBCP_CLIENTNUM;
    cbcp_NewPhase(cbcp, CBCP_STOPPED);		/* Wait for a REQ */
    cbcp_StartTimer(cbcp, cbcp->fsm.delay * DEF_FSMTRIES);
  } else {
    if (*cbcp->fsm.phone == '\0')
      cbcp->fsm.type = CBCP_NONUM;
    else if (!strcmp(cbcp->fsm.phone, "*")) {
      cbcp->fsm.type = CBCP_CLIENTNUM;
      *cbcp->fsm.phone = '\0';
    } else if (strchr(cbcp->fsm.phone, ','))
      cbcp->fsm.type = CBCP_LISTNUM;
    else
      cbcp->fsm.type = CBCP_SERVERNUM;
    cbcp->fsm.restart = DEF_FSMTRIES;
    cbcp_SendReq(cbcp);
  }
}

static int
cbcp_AdjustResponse(struct cbcp *cbcp, struct cbcp_data *data)
{
  /*
   * We've received a REQ (data).  Adjust our reponse (cbcp->fsm.*)
   * so that we (hopefully) agree with the peer
   */
  struct cbcp_addr *addr;

  switch (data->type) {
    case CBCP_NONUM:
      if (cbcp->p->dl->cfg.callback.opmask & CALLBACK_BIT(CALLBACK_NONE))
        /*
         * if ``none'' is a configured callback possibility
         * (ie, ``set callback cbcp none''), go along with the callees
         * request
         */
        cbcp->fsm.type = CBCP_NONUM;

      /*
       * Otherwise, we send our desired response anyway.  This seems to be
       * what Win95 does - although I can't find this behaviour documented
       * in the CBCP spec....
       */

      return 1;

    case CBCP_CLIENTNUM:
      if (cbcp->fsm.type == CBCP_CLIENTNUM) {
        char *ptr;

        if (data->length > data->addr_start - (char *)data) {
          /*
           * The peer has given us an address type spec - make sure we
           * understand !
           */
          addr = (struct cbcp_addr *)data->addr_start;
          if (addr->type != CBCP_ADDR_PSTN) {
            log_Printf(LogPHASE, "CBCP: Unrecognised address type %d !\n",
                       (int)addr->type);
            return 0;
          }
        }
        /* we accept the REQ even if the peer didn't specify an addr->type */
        ptr = strchr(cbcp->fsm.phone, ',');
        if (ptr)
          *ptr = '\0';		/* Just use the first number in our list */
        return 1;
      }
      log_Printf(LogPHASE, "CBCP: no number to pass to the peer !\n");
      return 0;

    case CBCP_SERVERNUM:
      if (cbcp->fsm.type == CBCP_SERVERNUM) {
        *cbcp->fsm.phone = '\0';
        return 1;
      }
      if (data->length > data->addr_start - (char *)data) {
        /*
         * This violates the spec, but if the peer has told us the
         * number it wants to call back, take advantage of this fact
         * and allow things to proceed if we've specified the same
         * number
         */
        addr = (struct cbcp_addr *)data->addr_start;
        if (addr->type != CBCP_ADDR_PSTN) {
          log_Printf(LogPHASE, "CBCP: Unrecognised address type %d !\n",
                     (int)addr->type);
          return 0;
        } else if (cbcp->fsm.type == CBCP_CLIENTNUM) {
          /*
           * If the peer's insisting on deciding the number, make sure
           * it's one of the ones in our list.  If it is, let the peer
           * think it's in control :-)
           */
          char list[sizeof cbcp->fsm.phone], *next;

          strncpy(list, cbcp->fsm.phone, sizeof list - 1);
          list[sizeof list - 1] = '\0';
          for (next = strtok(list, ","); next; next = strtok(NULL, ","))
            if (!strcmp(next, addr->addr)) {
              cbcp->fsm.type = CBCP_SERVERNUM;
              strcpy(cbcp->fsm.phone, next);
              return 1;
            }
        }
      }
      log_Printf(LogPHASE, "CBCP: Peer won't allow local decision !\n");
      return 0;

    case CBCP_LISTNUM:
      if (cbcp->fsm.type == CBCP_CLIENTNUM || cbcp->fsm.type == CBCP_LISTNUM) {
        /*
         * Search through ``data''s addresses and see if cbcp->fsm.phone
         * contains any of them
         */
        char list[sizeof cbcp->fsm.phone], *next, *end;

        addr = (struct cbcp_addr *)data->addr_start;
        end = (char *)data + data->length;

        while (addr->addr < end) {
          if (addr->type == CBCP_ADDR_PSTN) {
            strncpy(list, cbcp->fsm.phone, sizeof list - 1);
            list[sizeof list - 1] = '\0';
            for (next = strtok(list, ","); next; next = strtok(NULL, ","))
              if (!strcmp(next, addr->addr)) {
                cbcp->fsm.type = CBCP_LISTNUM;
                strcpy(cbcp->fsm.phone, next);
                return 1;
              }
          } else
            log_Printf(LogCBCP, "Warning: Unrecognised address type %d !\n",
                       (int)addr->type);
          addr = (struct cbcp_addr *)(addr->addr + strlen(addr->addr) + 1);
        }
      }
      log_Printf(LogPHASE, "CBCP: no good number to pass to the peer !\n");
      return 0;
  }

  log_Printf(LogCBCP, "Unrecognised REQ type %d !\n", (int)data->type);
  return 0;
}

static void
cbcp_SendResponse(struct cbcp *cbcp)
{
  struct cbcp_data data;
  struct cbcp_addr *addr;

  /* Only callers send RESPONSEs */

  log_Printf(LogCBCP, "%s: SendResponse(%d) state = %s\n", cbcp->p->dl->name,
             cbcp->fsm.id, cbcpstate(cbcp->fsm.state));

  data.type = cbcp->fsm.type;
  data.delay = cbcp->fsm.delay;
  addr = (struct cbcp_addr *)data.addr_start;
  if (data.type == CBCP_NONUM)
    data.length = (char *)&data.delay - (char *)&data;
  else if (*cbcp->fsm.phone) {
    addr->type = CBCP_ADDR_PSTN;
    strncpy(addr->addr, cbcp->fsm.phone, sizeof addr->addr - 1);
    addr->addr[sizeof addr->addr - 1] = '\0';
    data.length = (addr->addr + strlen(addr->addr) + 1) - (char *)&data;
  } else
    data.length = data.addr_start - (char *)&data;

  cbcp_data_Show(&data);
  cbcp_Output(cbcp, CBCP_RESPONSE, &data);
  cbcp->fsm.restart--;
  cbcp_StartTimer(cbcp, cbcp->fsm.delay);
  cbcp_NewPhase(cbcp, CBCP_RESPSENT);	/* Wait for an ACK */
}

/* What to do after checking an incoming response */
#define CBCP_ACTION_DOWN (0)
#define CBCP_ACTION_REQ (1)
#define CBCP_ACTION_ACK (2)

static int
cbcp_CheckResponse(struct cbcp *cbcp, struct cbcp_data *data)
{
  /*
   * We've received a RESPONSE (data).  Check if it agrees with
   * our REQ (cbcp->fsm)
   */
  struct cbcp_addr *addr;

  addr = (struct cbcp_addr *)data->addr_start;

  if (data->type == cbcp->fsm.type) {
    switch (cbcp->fsm.type) {
      case CBCP_NONUM:
        return CBCP_ACTION_ACK;

      case CBCP_CLIENTNUM:
        if ((char *)data + data->length <= addr->addr)
          log_Printf(LogPHASE, "CBCP: peer didn't respond with a number !\n");
        else if (addr->type != CBCP_ADDR_PSTN)
          log_Printf(LogPHASE, "CBCP: Unrecognised address type %d !\n",
                     addr->type);
        else {
          strncpy(cbcp->fsm.phone, addr->addr, sizeof cbcp->fsm.phone - 1);
          cbcp->fsm.phone[sizeof cbcp->fsm.phone - 1] = '\0';
          cbcp->fsm.delay = data->delay;
          return CBCP_ACTION_ACK;
        }
        return CBCP_ACTION_DOWN;

      case CBCP_SERVERNUM:
        cbcp->fsm.delay = data->delay;
        return CBCP_ACTION_ACK;

      case CBCP_LISTNUM:
        if ((char *)data + data->length <= addr->addr)
          log_Printf(LogPHASE, "CBCP: peer didn't respond with a number !\n");
        else if (addr->type != CBCP_ADDR_PSTN)
          log_Printf(LogPHASE, "CBCP: Unrecognised address type %d !\n",
                     addr->type);
        else {
          char list[sizeof cbcp->fsm.phone], *next;

          strncpy(list, cbcp->fsm.phone, sizeof list - 1);
          list[sizeof list - 1] = '\0';
          for (next = strtok(list, ","); next; next = strtok(NULL, ","))
            if (!strcmp(addr->addr, next)) {
              strcpy(cbcp->fsm.phone, next);
              cbcp->fsm.delay = data->delay;
              return CBCP_ACTION_ACK;
            }
          log_Printf(LogPHASE, "CBCP: peer didn't respond with a "
                     "valid number !\n");
        }
        return CBCP_ACTION_DOWN;
    }
    log_Printf(LogPHASE, "Internal CBCP error - agreed on %d !\n",
               (int)cbcp->fsm.type);
    return CBCP_ACTION_DOWN;
  } else if (data->type == CBCP_NONUM && cbcp->fsm.type == CBCP_CLIENTNUM) {
    /*
     * Client doesn't want CBCP after all....
     * We only allow this when ``set cbcp *'' has been specified.
     */
    cbcp->fsm.type = CBCP_NONUM;
    return CBCP_ACTION_ACK;
  }
  log_Printf(LogCBCP, "Invalid peer RESPONSE\n");
  return CBCP_ACTION_REQ;
}

static void
cbcp_SendAck(struct cbcp *cbcp)
{
  struct cbcp_data data;
  struct cbcp_addr *addr;

  /* Only callees send ACKs */

  log_Printf(LogCBCP, "%s: SendAck(%d) state = %s\n", cbcp->p->dl->name,
             cbcp->fsm.id, cbcpstate(cbcp->fsm.state));

  data.type = cbcp->fsm.type;
  switch (data.type) {
    case CBCP_NONUM:
      data.length = (char *)&data.delay - (char *)&data;
      break;
    case CBCP_CLIENTNUM:
      addr = (struct cbcp_addr *)data.addr_start;
      addr->type = CBCP_ADDR_PSTN;
      strncpy(addr->addr, cbcp->fsm.phone, sizeof addr->addr - 1);
      addr->addr[sizeof addr->addr - 1] = '\0';
      data.delay = cbcp->fsm.delay;
      data.length = addr->addr + strlen(addr->addr) + 1 - (char *)&data;
      break;
    default:
      data.delay = cbcp->fsm.delay;
      data.length = data.addr_start - (char *)&data;
      break;
  }

  cbcp_data_Show(&data);
  cbcp_Output(cbcp, CBCP_ACK, &data);
  cbcp->fsm.restart--;
  cbcp_StartTimer(cbcp, cbcp->fsm.delay);
  cbcp_NewPhase(cbcp, CBCP_ACKSENT);	/* Wait for an ACK */
}

extern struct mbuf *
cbcp_Input(struct bundle *bundle __unused, struct link *l, struct mbuf *bp)
{
  struct physical *p = link2physical(l);
  struct cbcp_header *head;
  struct cbcp_data *data;
  struct cbcp *cbcp = &p->dl->cbcp;
  size_t len;

  if (p == NULL) {
    log_Printf(LogERROR, "cbcp_Input: Not a physical link - dropped\n");
    m_freem(bp);
    return NULL;
  }

  bp = m_pullup(bp);
  len = m_length(bp);
  if (len < sizeof(struct cbcp_header)) {
    m_freem(bp);
    return NULL;
  }
  head = (struct cbcp_header *)MBUF_CTOP(bp);
  if (ntohs(head->length) != len) {
    log_Printf(LogWARN, "Corrupt CBCP packet (code %d, length %u not %zu)"
               " - ignored\n", head->code, ntohs(head->length), len);
    m_freem(bp);
    return NULL;
  }
  m_settype(bp, MB_CBCPIN);

  /* XXX check the id */

  bp->m_offset += sizeof(struct cbcp_header);
  bp->m_len -= sizeof(struct cbcp_header);
  data = (struct cbcp_data *)MBUF_CTOP(bp);

  switch (head->code) {
    case CBCP_REQ:
      log_Printf(LogCBCP, "%s: RecvReq(%d) state = %s\n",
                 p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
      cbcp_data_Show(data);
      if (cbcp->fsm.state == CBCP_STOPPED || cbcp->fsm.state == CBCP_RESPSENT) {
        timer_Stop(&cbcp->fsm.timer);
        if (cbcp_AdjustResponse(cbcp, data)) {
          cbcp->fsm.restart = DEF_FSMTRIES;
          cbcp->fsm.id = head->id;
          cbcp_SendResponse(cbcp);
        } else
          datalink_CBCPFailed(cbcp->p->dl);
      } else
        log_Printf(LogCBCP, "%s: unexpected REQ dropped\n", p->dl->name);
      break;

    case CBCP_RESPONSE:
      log_Printf(LogCBCP, "%s: RecvResponse(%d) state = %s\n",
	         p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
      cbcp_data_Show(data);
      if (cbcp->fsm.id != head->id) {
        log_Printf(LogCBCP, "Warning: Expected id was %d, not %d\n",
                   cbcp->fsm.id, head->id);
        cbcp->fsm.id = head->id;
      }
      if (cbcp->fsm.state == CBCP_REQSENT || cbcp->fsm.state == CBCP_ACKSENT) {
        timer_Stop(&cbcp->fsm.timer);
        switch (cbcp_CheckResponse(cbcp, data)) {
          case CBCP_ACTION_REQ:
            cbcp_SendReq(cbcp);
            break;

          case CBCP_ACTION_ACK:
            cbcp->fsm.restart = DEF_FSMTRIES;
            cbcp_SendAck(cbcp);
            if (cbcp->fsm.type == CBCP_NONUM) {
              /*
               * Don't change state in case the peer doesn't get our ACK,
               * just bring the layer up.
               */
              timer_Stop(&cbcp->fsm.timer);
              datalink_NCPUp(cbcp->p->dl);
            }
            break;

          default:
            datalink_CBCPFailed(cbcp->p->dl);
            break;
        }
      } else
        log_Printf(LogCBCP, "%s: unexpected RESPONSE dropped\n", p->dl->name);
      break;

    case CBCP_ACK:
      log_Printf(LogCBCP, "%s: RecvAck(%d) state = %s\n",
	         p->dl->name, head->id, cbcpstate(cbcp->fsm.state));
      cbcp_data_Show(data);
      if (cbcp->fsm.id != head->id) {
        log_Printf(LogCBCP, "Warning: Expected id was %d, not %d\n",
                   cbcp->fsm.id, head->id);
        cbcp->fsm.id = head->id;
      }
      if (cbcp->fsm.type == CBCP_NONUM) {
        /*
         * Don't change state in case the peer doesn't get our ACK,
         * just bring the layer up.
         */
        timer_Stop(&cbcp->fsm.timer);
        datalink_NCPUp(cbcp->p->dl);
      } else if (cbcp->fsm.state == CBCP_RESPSENT) {
        timer_Stop(&cbcp->fsm.timer);
        datalink_CBCPComplete(cbcp->p->dl);
        log_Printf(LogPHASE, "%s: CBCP: Peer will dial back\n", p->dl->name);
      } else
        log_Printf(LogCBCP, "%s: unexpected ACK dropped\n", p->dl->name);
      break;

    default:
      log_Printf(LogWARN, "Unrecognised CBCP packet (code %d, length %zd)\n",
               head->code, len);
      break;
  }

  m_freem(bp);
  return NULL;
}

void
cbcp_Down(struct cbcp *cbcp)
{
  timer_Stop(&cbcp->fsm.timer);
  cbcp_NewPhase(cbcp, CBCP_CLOSED);
  cbcp->required = 0;
}

void
cbcp_ReceiveTerminateReq(struct physical *p)
{
  if (p->dl->cbcp.fsm.state == CBCP_ACKSENT) {
    /* Don't change our state in case the peer doesn't get the ACK */
    p->dl->cbcp.required = 1;
    log_Printf(LogPHASE, "%s: CBCP: Will dial back on %s\n", p->dl->name,
               p->dl->cbcp.fsm.phone);
  } else
    cbcp_NewPhase(&p->dl->cbcp, CBCP_CLOSED);
}
