Esempio n. 1
0
static void
SendPapCode(struct authinfo *authp, int code, const char *message)
{
  struct fsmheader lh;
  struct mbuf *bp;
  u_char *cp;
  int plen, mlen;

  lh.code = code;
  lh.id = authp->id;
  mlen = strlen(message);
  plen = mlen + 1;
  lh.length = htons(plen + sizeof(struct fsmheader));
  bp = m_get(plen + sizeof(struct fsmheader), MB_PAPOUT);
  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
  /*
   * If our message is longer than 255 bytes, truncate the length to
   * 255 and send the entire message anyway.  Maybe the other end will
   * display it... (see pap_Input() !)
   */
  *cp++ = mlen > 255 ? 255 : mlen;
  memcpy(cp, message, mlen);
  log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]);

  link_PushPacket(&authp->physical->link, bp, authp->physical->dl->bundle,
                  LINK_QUEUES(&authp->physical->link) - 1, PROTO_PAP);
}
Esempio n. 2
0
static void
pap_Req(struct authinfo *authp)
{
  struct bundle *bundle = authp->physical->dl->bundle;
  struct fsmheader lh;
  struct mbuf *bp;
  u_char *cp;
  int namelen, keylen, plen;

  namelen = strlen(bundle->cfg.auth.name);
  keylen = strlen(bundle->cfg.auth.key);
  plen = namelen + keylen + 2;
  log_Printf(LogDEBUG, "pap_Req: namelen = %d, keylen = %d\n", namelen, keylen);
  log_Printf(LogPHASE, "Pap Output: %s ********\n", bundle->cfg.auth.name);
  if (*bundle->cfg.auth.name == '\0')
    log_Printf(LogWARN, "Sending empty PAP authname!\n");
  lh.code = PAP_REQUEST;
  lh.id = authp->id;
  lh.length = htons(plen + sizeof(struct fsmheader));
  bp = m_get(plen + sizeof(struct fsmheader), MB_PAPOUT);
  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
  cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
  *cp++ = namelen;
  memcpy(cp, bundle->cfg.auth.name, namelen);
  cp += namelen;
  *cp++ = keylen;
  memcpy(cp, bundle->cfg.auth.key, keylen);
  link_PushPacket(&authp->physical->link, bp, bundle,
                  LINK_QUEUES(&authp->physical->link) - 1, PROTO_PAP);
}
Esempio n. 3
0
struct mbuf *
m_pullup(struct mbuf *bp)
{
  /* Put it all in one contigous (aligned) mbuf */

  if (bp != NULL) {
    if (bp->m_next != NULL) {
      struct mbuf *nbp;
      u_char *cp;

      nbp = m_get(m_length(bp), bp->m_type);

      for (cp = MBUF_CTOP(nbp); bp; bp = m_free(bp)) {
        memcpy(cp, MBUF_CTOP(bp), bp->m_len);
        cp += bp->m_len;
      }
      bp = nbp;
    }
#ifndef __i386__	/* Do any other archs not care about alignment ? */
    else if ((bp->m_offset & (sizeof(long) - 1)) != 0) {
      bcopy(MBUF_CTOP(bp), bp + 1, bp->m_len);
      bp->m_offset = 0;
    }
#endif
  }

  return bp;
}
Esempio n. 4
0
struct mbuf *
m_prepend(struct mbuf *bp, const void *ptr, size_t len, u_short extra)
{
  struct mbuf *head;

  if (bp && bp->m_offset) {
    if (bp->m_offset >= len) {
      bp->m_offset -= len;
      bp->m_len += len;
      if (ptr)
        memcpy(MBUF_CTOP(bp), ptr, len);
      return bp;
    }
    len -= bp->m_offset;
    if (ptr)
      memcpy(bp + 1, (const char *)ptr + len, bp->m_offset);
    bp->m_len += bp->m_offset;
    bp->m_offset = 0;
  }

  head = m_get(len + extra, bp ? bp->m_type : MB_UNKNOWN);
  head->m_offset = extra;
  head->m_len -= extra;
  if (ptr)
    memcpy(MBUF_CTOP(head), ptr, len);
  head->m_next = bp;

  return head;
}
Esempio n. 5
0
static struct mbuf *
tcpmss_Check(struct bundle *bundle, struct mbuf *bp)
{
  struct ip *pip;
  size_t hlen, plen;

  if (!Enabled(bundle, OPT_TCPMSSFIXUP))
    return bp;

  bp = m_pullup(bp);
  plen = m_length(bp);
  pip = (struct ip *)MBUF_CTOP(bp);
  hlen = pip->ip_hl << 2;

  /*
   * Check for MSS option only for TCP packets with zero fragment offsets
   * and correct total and header lengths.
   */
  if (pip->ip_p == IPPROTO_TCP && (ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
      ntohs(pip->ip_len) == plen && hlen <= plen &&
      plen >= sizeof(struct tcphdr) + hlen)
    MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen,
             MAXMSS(bundle->iface->mtu));

  return bp;
}
Esempio n. 6
0
/*
 * Enqueue a packet of the given address family.  Nothing will make it
 * down to the physical link level 'till ncp_FillPhysicalQueues() is used.
 */
void
ncp_Enqueue(struct ncp *ncp, int af, unsigned pri, char *ptr, int count)
{
#ifndef NOINET6
  struct ipv6cp *ipv6cp = &ncp->ipv6cp;
#endif
  struct ipcp *ipcp = &ncp->ipcp;
  struct mbuf *bp;

  /*
   * We allocate an extra 6 bytes, four at the front and two at the end.
   * This is an optimisation so that we need to do less work in
   * m_prepend() in acf_LayerPush() and proto_LayerPush() and
   * appending in hdlc_LayerPush().
   */

  switch (af) {
  case AF_INET:
    if (pri >= IPCP_QUEUES(ipcp)) {
      log_Printf(LogERROR, "Can't store in ip queue %u\n", pri);
      break;
    }

    bp = m_get(count + 6, MB_IPOUT);
    bp->m_offset += 4;
    bp->m_len -= 6;
    memcpy(MBUF_CTOP(bp), ptr, count);
    m_enqueue(ipcp->Queue + pri, bp);
    break;

#ifndef NOINET6
  case AF_INET6:
    if (pri >= IPV6CP_QUEUES(ipcp)) {
      log_Printf(LogERROR, "Can't store in ipv6 queue %u\n", pri);
      break;
    }

    bp = m_get(count + 6, MB_IPOUT);
    bp->m_offset += 4;
    bp->m_len -= 6;
    memcpy(MBUF_CTOP(bp), ptr, count);
    m_enqueue(ipv6cp->Queue + pri, bp);
    break;
#endif

  default:
      log_Printf(LogERROR, "Can't enqueue protocol family %d\n", af);
  }
}
Esempio n. 7
0
static void
Despatch(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short proto)
{
  unsigned f;

  for (f = 0; f < DSIZE; f++)
    if (despatcher[f].proto == proto) {
      bp = (*despatcher[f].fn)(bundle, l, bp);
      break;
    }

  if (bp) {
    struct physical *p = link2physical(l);

    log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n",
               f == DSIZE ? "Unknown" : "Unexpected", proto,
               hdlc_Protocol2Nam(proto));
    bp = m_pullup(proto_Prepend(bp, proto, 0, 0));
    lcp_SendProtoRej(&l->lcp, MBUF_CTOP(bp), bp->m_len);
    if (p) {
      p->hdlc.lqm.SaveInDiscards++;
      p->hdlc.stats.unknownproto++;
    }
    m_freem(bp);
  }
}
Esempio n. 8
0
static int
physical_DescriptorWrite(struct fdescriptor *d, struct bundle *bundle,
                         const fd_set *fdset)
{
  struct physical *p = descriptor2physical(d);
  int nw, result = 0;

  if (p->out == NULL)
    p->out = link_Dequeue(&p->link);

  if (p->out) {
    nw = physical_Write(p, MBUF_CTOP(p->out), p->out->m_len);
    log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%lu) to %d\n",
               p->link.name, nw, (unsigned long)p->out->m_len, p->fd);
    if (nw > 0) {
      p->out->m_len -= nw;
      p->out->m_offset += nw;
      if (p->out->m_len == 0)
	p->out = m_free(p->out);
      result = 1;
    } else if (nw < 0) {
      if (errno == EAGAIN)
        result = 1;
      else if (errno != ENOBUFS) {
	log_Printf(LogPHASE, "%s: write (%d): %s\n", p->link.name,
                   p->fd, strerror(errno));
        datalink_Down(p->dl, CLOSE_NORMAL);
      }
    }
    /* else we shouldn't really have been called !  select() is broken ! */
  }

  return result;
}
Esempio n. 9
0
struct mbuf *
mbuf_Read(struct mbuf *bp, void *v, size_t len)
{
  int nb;
  u_char *ptr = v;

  while (bp && len > 0) {
    if (len > bp->m_len)
      nb = bp->m_len;
    else
      nb = len;
    if (nb) {
      memcpy(ptr, MBUF_CTOP(bp), nb);
      ptr += nb;
      bp->m_len -= nb;
      len -= nb;
      bp->m_offset += nb;
    }
    if (bp->m_len == 0)
      bp = m_free(bp);
  }

  while (bp && bp->m_len == 0)
    bp = m_free(bp);

  return bp;
}
Esempio n. 10
0
void
link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b)
{
  struct mbuf *bp, *lbp[LAYER_MAX], *next;
  u_short lproto[LAYER_MAX], proto;
  int layer;

  /*
   * When we ``pull'' a packet from the link, it gets processed by the
   * ``pull'' function in each layer starting at the bottom.
   * Each ``pull'' may produce multiple packets, chained together using
   * bp->m_nextpkt.
   * Each packet that results from each pull has to be pulled through
   * all of the higher layers before the next resulting packet is pulled
   * through anything; this ensures that packets that depend on the
   * fsm state resulting from the receipt of the previous packet aren't
   * surprised.
   */

  link_AddInOctets(l, len);

  memset(lbp, '\0', sizeof lbp);
  lbp[0] = m_get(len, MB_UNKNOWN);
  memcpy(MBUF_CTOP(lbp[0]), buf, len);
  lproto[0] = 0;
  layer = 0;

  while (layer || lbp[layer]) {
    if (lbp[layer] == NULL) {
      layer--;
      continue;
    }
    bp = lbp[layer];
    lbp[layer] = bp->m_nextpkt;
    bp->m_nextpkt = NULL;
    proto = lproto[layer];

    if (l->layer[layer]->pull != NULL)
      bp = (*l->layer[layer]->pull)(b, l, bp, &proto);

    if (layer == l->nlayers - 1) {
      /* We've just done the top layer, despatch the packet(s) */
      while (bp) {
        next = bp->m_nextpkt;
        bp->m_nextpkt = NULL;
        log_Printf(LogDEBUG, "link_PullPacket: Despatch proto 0x%04x\n", proto);
        Despatch(b, l, bp, proto);
        bp = next;
      }
    } else {
      lbp[++layer] = bp;
      lproto[layer] = proto;
    }
  }
}
Esempio n. 11
0
static void
ChapOutput(struct physical *physical, u_int code, u_int id,
	   const u_char *ptr, int count, const char *text)
{
  int plen;
  struct fsmheader lh;
  struct mbuf *bp;

  plen = sizeof(struct fsmheader) + count;
  lh.code = code;
  lh.id = id;
  lh.length = htons(plen);
  bp = m_get(plen, MB_CHAPOUT);
  memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
  if (count)
    memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count);
  log_DumpBp(LogDEBUG, "ChapOutput", bp);
  if (text == NULL)
    log_Printf(LogPHASE, "Chap Output: %s\n", chapcodes[code]);
  else
    log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text);
  link_PushPacket(&physical->link, bp, physical->dl->bundle,
                  LINK_QUEUES(&physical->link) - 1, PROTO_CHAP);
}
Esempio n. 12
0
void
mbuf_Write(struct mbuf *bp, const void *ptr, size_t m_len)
{
  size_t plen;
  int nb;

  plen = m_length(bp);
  if (plen < m_len)
    m_len = plen;

  while (m_len > 0) {
    nb = (m_len < bp->m_len) ? m_len : bp->m_len;
    memcpy(MBUF_CTOP(bp), ptr, nb);
    m_len -= bp->m_len;
    bp = bp->m_next;
  }
}
Esempio n. 13
0
size_t
mbuf_View(struct mbuf *bp, void *v, size_t len)
{
  size_t nb, l = len;
  u_char *ptr = v;

  while (bp && l > 0) {
    if (l > bp->m_len)
      nb = bp->m_len;
    else
      nb = l;
    memcpy(ptr, MBUF_CTOP(bp), nb);
    ptr += nb;
    l -= nb;
    bp = bp->m_next;
  }

  return len - l;
}
Esempio n. 14
0
int
ipv6cp_PushPacket(struct ipv6cp *ipv6cp, struct link *l)
{
  struct bundle *bundle = ipv6cp->fsm.bundle;
  struct mqueue *queue;
  struct mbuf *bp;
  int m_len;
  u_int32_t secs = 0;
  unsigned alivesecs = 0;

  if (ipv6cp->fsm.state != ST_OPENED)
    return 0;

  /*
   * If ccp is not open but is required, do nothing.
   */
  if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) {
    log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name);
    return 0;
  }

  queue = ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp) - 1;
  do {
    if (queue->top) {
      bp = m_dequeue(queue);
      bp = mbuf_Read(bp, &secs, sizeof secs);
      bp = m_pullup(bp);
      m_len = m_length(bp);
      if (!FilterCheck(MBUF_CTOP(bp), AF_INET6, &bundle->filter.alive,
                       &alivesecs)) {
        if (secs == 0)
          secs = alivesecs;
        bundle_StartIdleTimer(bundle, secs);
      }
      link_PushPacket(l, bp, bundle, 0, PROTO_IPV6);
      ipv6cp_AddOutOctets(ipv6cp, m_len);
      return 1;
    }
  } while (queue-- != ipv6cp->Queue);

  return 0;
}
Esempio n. 15
0
static struct mbuf *
vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri,
             u_short *proto)
{
  int type;
  struct ip *pip;
  u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16;

  bp = m_pullup(bp);
  pip = (struct ip *)MBUF_CTOP(bp);
  if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP &&
      cproto == PROTO_VJCOMP) {
    type = sl_compress_tcp(bp, pip, &bundle->ncp.ipcp.vj.cslc,
                           &bundle->ncp.ipcp.vj.slstat,
                           bundle->ncp.ipcp.peer_compproto & 0xff);
    log_Printf(LogDEBUG, "vj_LayerWrite: type = %x\n", type);
    switch (type) {
    case TYPE_IP:
      break;

    case TYPE_UNCOMPRESSED_TCP:
      *proto = PROTO_VJUNCOMP;
      log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n");
      m_settype(bp, MB_VJOUT);
      break;

    case TYPE_COMPRESSED_TCP:
      *proto = PROTO_VJCOMP;
      log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n");
      m_settype(bp, MB_VJOUT);
      break;

    default:
      log_Printf(LogERROR, "vj_LayerPush: Unknown frame type %x\n", type);
      m_freem(bp);
      return NULL;
    }
  }

  return bp;
}
Esempio n. 16
0
static struct mbuf *
VjUncompressTcp(struct ipcp *ipcp, struct mbuf *bp, u_char type)
{
  u_char *bufp;
  int len, olen, rlen;
  u_char work[MAX_HDR + MAX_VJHEADER];	/* enough to hold TCP/IP header */

  bp = m_pullup(bp);
  olen = len = m_length(bp);
  if (type == TYPE_UNCOMPRESSED_TCP) {
    /*
     * Uncompressed packet does NOT change its size, so that we can use mbuf
     * space for uncompression job.
     */
    bufp = MBUF_CTOP(bp);
    len = sl_uncompress_tcp(&bufp, len, type, &ipcp->vj.cslc, &ipcp->vj.slstat,
                            (ipcp->my_compproto >> 8) & 255);
    if (len <= 0) {
      m_freem(bp);
      bp = NULL;
    } else
      m_settype(bp, MB_VJIN);
    return bp;
  }
Esempio n. 17
0
struct mbuf *
pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  struct physical *p = link2physical(l);
  struct authinfo *authp = &p->dl->pap;
  u_char nlen, klen, *key;
  const char *txt;
  int txtlen;

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

  if (bundle_Phase(bundle) != PHASE_NETWORK &&
      bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
    log_Printf(LogPHASE, "Unexpected pap input - dropped !\n");
    m_freem(bp);
    return NULL;
  }

  if ((bp = auth_ReadHeader(authp, bp)) == NULL &&
      ntohs(authp->in.hdr.length) == 0) {
    log_Printf(LogWARN, "Pap Input: Truncated header !\n");
    return NULL;
  }

  if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) {
    log_Printf(LogPHASE, "Pap Input: %d: Bad PAP code !\n", authp->in.hdr.code);
    m_freem(bp);
    return NULL;
  }

  if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id &&
      Enabled(bundle, OPT_IDCHECK)) {
    /* Wrong conversation dude ! */
    log_Printf(LogPHASE, "Pap Input: %s dropped (got id %d, not %d)\n",
               papcodes[authp->in.hdr.code], authp->in.hdr.id, authp->id);
    m_freem(bp);
    return NULL;
  }
  m_settype(bp, MB_PAPIN);
  authp->id = authp->in.hdr.id;		/* We respond with this id */

  if (bp) {
    bp = mbuf_Read(bp, &nlen, 1);
    if (authp->in.hdr.code == PAP_ACK) {
      /*
       * Don't restrict the length of our acknowledgement freetext to
       * nlen (a one-byte length).  Show the rest of the ack packet
       * instead.  This isn't really part of the protocol.....
       */
      bp = m_pullup(bp);
      txt = MBUF_CTOP(bp);
      txtlen = m_length(bp);
    } else {
      bp = auth_ReadName(authp, bp, nlen);
      txt = authp->in.name;
      txtlen = strlen(authp->in.name);
    }
  } else {
    txt = "";
    txtlen = 0;
  }

  log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n",
             papcodes[authp->in.hdr.code], txtlen, txt);

  switch (authp->in.hdr.code) {
    case PAP_REQUEST:
      if (bp == NULL) {
        log_Printf(LogPHASE, "Pap Input: No key given !\n");
        break;
      }
      bp = mbuf_Read(bp, &klen, 1);
      if (m_length(bp) < klen) {
        log_Printf(LogERROR, "Pap Input: Truncated key !\n");
        break;
      }
      if ((key = malloc(klen+1)) == NULL) {
        log_Printf(LogERROR, "Pap Input: Out of memory !\n");
        break;
      }
      bp = mbuf_Read(bp, key, klen);
      key[klen] = '\0';

#ifndef NORADIUS
      if (*bundle->radius.cfg.file) {
        if (!radius_Authenticate(&bundle->radius, authp, authp->in.name,
                                 key, strlen(key), NULL, 0))
          pap_Failure(authp);
      } else
#endif
      if (auth_Validate(bundle, authp->in.name, key))
        pap_Success(authp);
      else
        pap_Failure(authp);

      free(key);
      break;

    case PAP_ACK:
      auth_StopTimer(authp);
      if (p->link.lcp.auth_iwait == PROTO_PAP) {
        p->link.lcp.auth_iwait = 0;
        if (p->link.lcp.auth_ineed == 0)
          /*
           * We've succeeded in our ``login''
           * If we're not expecting  the peer to authenticate (or he already
           * has), proceed to network phase.
           */
          datalink_AuthOk(p->dl);
      }
      break;

    case PAP_NAK:
      auth_StopTimer(authp);
      datalink_AuthNotOk(p->dl);
      break;
  }

  m_freem(bp);
  return NULL;
}
Esempio n. 18
0
struct mbuf *
lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
{
  struct physical *p = link2physical(l);
  struct lcp *lcp = p->hdlc.lqm.owner;
  int len;

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

  len = m_length(bp);
  if (len != sizeof(struct lqrdata))
    log_Printf(LogWARN, "lqr_Input: Got packet size %d, expecting %ld !\n",
              len, (long)sizeof(struct lqrdata));
  else if (!IsAccepted(l->lcp.cfg.lqr) && !(p->hdlc.lqm.method & LQM_LQR)) {
    bp = m_pullup(proto_Prepend(bp, PROTO_LQR, 0, 0));
    lcp_SendProtoRej(lcp, MBUF_CTOP(bp), bp->m_len);
  } else {
    struct lqrdata *lqr;

    bp = m_pullup(bp);
    lqr = (struct lqrdata *)MBUF_CTOP(bp);
    if (ntohl(lqr->MagicNumber) != lcp->his_magic)
      log_Printf(LogWARN, "lqr_Input: magic 0x%08lx is wrong,"
                 " expecting 0x%08lx\n",
		 (u_long)ntohl(lqr->MagicNumber), (u_long)lcp->his_magic);
    else {
      struct lqrdata lastlqr;
 
      memcpy(&lastlqr, &p->hdlc.lqm.lqr.peer, sizeof lastlqr);
      lqr_ChangeOrder(lqr, &p->hdlc.lqm.lqr.peer);
      lqr_Dump(l->name, "Input", &p->hdlc.lqm.lqr.peer);
      /* we have received an LQR from our peer */
      p->hdlc.lqm.lqr.resent = 0;

      /* Snapshot our state when the LQR packet was received */
      memcpy(&p->hdlc.lqm.lqr.prevSave, &p->hdlc.lqm.lqr.Save,
             sizeof p->hdlc.lqm.lqr.prevSave);
      p->hdlc.lqm.lqr.Save.InLQRs = ++p->hdlc.lqm.lqr.InLQRs;
      p->hdlc.lqm.lqr.Save.InPackets = p->hdlc.lqm.ifInUniPackets;
      p->hdlc.lqm.lqr.Save.InDiscards = p->hdlc.lqm.ifInDiscards;
      p->hdlc.lqm.lqr.Save.InErrors = p->hdlc.lqm.ifInErrors;
      p->hdlc.lqm.lqr.Save.InOctets = p->hdlc.lqm.lqr.InGoodOctets;

      lqr_Analyse(&p->hdlc, &lastlqr, &p->hdlc.lqm.lqr.peer);

      /*
       * Generate an LQR response if we're not running an LQR timer OR
       * two successive LQR's PeerInLQRs are the same.
       */
      if (p->hdlc.lqm.timer.load == 0 || !(p->hdlc.lqm.method & LQM_LQR) ||
          (lastlqr.PeerInLQRs &&
           lastlqr.PeerInLQRs == p->hdlc.lqm.lqr.peer.PeerInLQRs))
        SendLqrData(lcp);
    }
  }
  m_freem(bp);
  return NULL;
}
Esempio n. 19
0
  return 0;
}

static struct mbuf *
nat_LayerPush(struct bundle *bundle, struct link *l __unused, struct mbuf *bp,
                int pri __unused, u_short *proto)
{
  if (!bundle->NatEnabled || *proto != PROTO_IP)
    return bp;

  log_Printf(LogDEBUG, "nat_LayerPush: PROTO_IP -> PROTO_IP\n");
  m_settype(bp, MB_NATOUT);
  /* Ensure there's a bit of extra buffer for the NAT code... */
  bp = m_pullup(m_append(bp, NULL, NAT_EXTRABUF));
  LibAliasOut(la, MBUF_CTOP(bp), bp->m_len);
  bp->m_len = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len);

  return bp;
}

static struct mbuf *
nat_LayerPull(struct bundle *bundle, struct link *l __unused, struct mbuf *bp,
                u_short *proto)
{
  static int gfrags;
  int ret, len, nfrags;
  struct mbuf **last;
  char *fptr;

  if (!bundle->NatEnabled || *proto != PROTO_IP)
Esempio n. 20
0
static struct mbuf *
lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
              int pri, u_short *proto)
{
  struct physical *p = link2physical(l);
  int len, layer;

  if (!p) {
    /* Oops - can't happen :-] */
    m_freem(bp);
    return NULL;
  }

  bp = m_pullup(bp);
  len = m_length(bp);

  /*-
   * From rfc1989:
   *
   *  All octets which are included in the FCS calculation MUST be counted,
   *  including the packet header, the information field, and any padding.
   *  The FCS octets MUST also be counted, and one flag octet per frame
   *  MUST be counted.  All other octets (such as additional flag
   *  sequences, and escape bits or octets) MUST NOT be counted.
   *
   * As we're stacked higher than the HDLC layer (otherwise HDLC wouldn't be
   * able to calculate the FCS), we must not forget about these additional
   * bytes when we're asynchronous.
   *
   * We're also expecting to be stacked *before* the likes of the proto and
   * acf layers (to avoid alignment issues), so deal with this too.
   */

  p->hdlc.lqm.ifOutUniPackets++;
  p->hdlc.lqm.ifOutOctets += len + 1;		/* plus 1 flag octet! */
  for (layer = 0; layer < l->nlayers; layer++)
    switch (l->layer[layer]->type) {
      case LAYER_ACF:
        p->hdlc.lqm.ifOutOctets += acf_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_ASYNC:
        /* Not included - see rfc1989 */
        break;
      case LAYER_HDLC:
        p->hdlc.lqm.ifOutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_LQR:
        layer = l->nlayers;
        break;
      case LAYER_PROTO:
        p->hdlc.lqm.ifOutOctets += proto_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_SYNC:
        /* Nothing to add on */
        break;
      default:
        log_Printf(LogWARN, "Oops, don't know how to do octets for %s layer\n",
                   l->layer[layer]->name);
        break;
    }

  if (*proto == PROTO_LQR) {
    /* Overwrite the entire packet (created in SendLqrData()) */
    struct lqrdata lqr;
    size_t pending_pkts, pending_octets;
 
    p->hdlc.lqm.lqr.OutLQRs++;

    /*
     * We need to compensate for the fact that we're pushing our data
     * onto the highest priority queue by factoring out packet & octet
     * values from other queues!
     */
    link_PendingLowPriorityData(l, &pending_pkts, &pending_octets);

    memset(&lqr, '\0', sizeof 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.Save.InLQRs;
    lqr.PeerInPackets = p->hdlc.lqm.lqr.Save.InPackets;
    lqr.PeerInDiscards = p->hdlc.lqm.lqr.Save.InDiscards;
    lqr.PeerInErrors = p->hdlc.lqm.lqr.Save.InErrors;
    lqr.PeerInOctets = p->hdlc.lqm.lqr.Save.InOctets;
    lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
    lqr.PeerOutPackets = p->hdlc.lqm.ifOutUniPackets - pending_pkts;
    /* Don't forget our ``flag'' octets.... */
    lqr.PeerOutOctets = p->hdlc.lqm.ifOutOctets - pending_octets - pending_pkts;
    lqr_Dump(l->name, "Output", &lqr);
    lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
  }

  return bp;
}
Esempio n. 21
0
#include "ncp.h"
#include "bundle.h"
#include "vjcomp.h"

#define MAX_VJHEADER 16		/* Maximum size of compressed header */

static struct mbuf *
vj_LayerPush(struct bundle *bundle, struct link *l __unused, struct mbuf *bp,
	     int pri __unused, u_short *proto)
{
  int type;
  struct ip *pip;
  u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16;

  bp = m_pullup(bp);
  pip = (struct ip *)MBUF_CTOP(bp);
  if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP &&
      cproto == PROTO_VJCOMP) {
    type = sl_compress_tcp(bp, pip, &bundle->ncp.ipcp.vj.cslc,
                           &bundle->ncp.ipcp.vj.slstat,
                           bundle->ncp.ipcp.peer_compproto & 0xff);
    log_Printf(LogDEBUG, "vj_LayerWrite: type = %x\n", type);
    switch (type) {
    case TYPE_IP:
      break;

    case TYPE_UNCOMPRESSED_TCP:
      *proto = PROTO_VJUNCOMP;
      log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n");
      m_settype(bp, MB_VJOUT);
      break;
Esempio n. 22
0
DeflateOutput(void *v, struct ccp *ccp, struct link *l __unused,
	      int pri __unused, u_short *proto, struct mbuf *mp)
{
  struct deflate_state *state = (struct deflate_state *)v;
  u_char *wp, *rp;
  int olen, ilen, len, res, flush;
  struct mbuf *mo_head, *mo, *mi_head, *mi;

  ilen = m_length(mp);
  log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", *proto, ilen);
  log_DumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp);

  /* Stuff the protocol in front of the input */
  mi_head = mi = m_get(2, MB_CCPOUT);
  mi->m_next = mp;
  rp = MBUF_CTOP(mi);
  if (*proto < 0x100) {			/* Compress the protocol */
    rp[0] = *proto & 0377;
    mi->m_len = 1;
  } else {				/* Don't compress the protocol */
    rp[0] = *proto >> 8;
    rp[1] = *proto & 0377;
    mi->m_len = 2;
  }

  /* Allocate the initial output mbuf */
  mo_head = mo = m_get(DEFLATE_CHUNK_LEN, MB_CCPOUT);
  mo->m_len = 2;
  wp = MBUF_CTOP(mo);
  *wp++ = state->seqno >> 8;
  *wp++ = state->seqno & 0377;