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); }
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); }
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; }
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; }
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; }
/* * 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); } }
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); } }
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; }
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; }
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; } } }
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); }
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; } }
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; }
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; }
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; }
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; }
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; }
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; }
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)
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; }
#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;
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;