示例#1
0
文件: ng_vjc.c 项目: MarginC/kame
/*
 * Receive data
 */
static int
ng_vjc_rcvdata(hook_p hook, item_p item)
{
	const node_p node = NG_HOOK_NODE(hook);
	const priv_p priv = NG_NODE_PRIVATE(node);
	int error = 0;
	struct mbuf *m;

	NGI_GET_M(item, m);
	if (hook == priv->ip) {			/* outgoing packet */
		u_int type = TYPE_IP;

		/* Compress packet if enabled and proto is TCP */
		if (priv->conf.enableComp) {
			struct ip *ip;

			if ((m = ng_vjc_pulluphdrs(m, 0)) == NULL) {
				NG_FREE_ITEM(item);
				return (ENOBUFS);
			}
			ip = mtod(m, struct ip *);
			if (ip->ip_p == IPPROTO_TCP) {
				const int origLen = m->m_len;

				type = sl_compress_tcp(m, ip,
				    &priv->slc, priv->conf.compressCID);
				m->m_pkthdr.len += m->m_len - origLen;
			}
		}

		/* Dispatch to the appropriate outgoing hook */
		switch (type) {
		case TYPE_IP:
			hook = priv->vjip;
			break;
		case TYPE_UNCOMPRESSED_TCP:
			hook = priv->vjuncomp;
			break;
		case TYPE_COMPRESSED_TCP:
			hook = priv->vjcomp;
			break;
		default:
			panic("%s: type=%d", __func__, type);
		}
	} else if (hook == priv->vjcomp) {	/* incoming compressed packet */
示例#2
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;
}
示例#3
0
/*
 * Get a packet to send.  This procedure is intended to be called at
 * splsoftnet, since it may involve time-consuming operations such as
 * applying VJ compression, packet compression, address/control and/or
 * protocol field compression to the packet.
 */
struct mbuf *
ppp_dequeue(struct ppp_softc *sc)
{
    struct mbuf *m, *mp;
    u_char *cp;
    int address, control, protocol;

    /*
     * Grab a packet to send: first try the fast queue, then the
     * normal queue.
     */
    IF_DEQUEUE(&sc->sc_fastq, m);
    if (m == NULL)
	m = ifsq_dequeue(ifq_get_subq_default(&sc->sc_if.if_snd));
    if (m == NULL)
	return NULL;

    ++sc->sc_stats.ppp_opackets;

    /*
     * Extract the ppp header of the new packet.
     * The ppp header will be in one mbuf.
     */
    cp = mtod(m, u_char *);
    address = PPP_ADDRESS(cp);
    control = PPP_CONTROL(cp);
    protocol = PPP_PROTOCOL(cp);

    switch (protocol) {
    case PPP_IP:
#ifdef VJC
	/*
	 * If the packet is a TCP/IP packet, see if we can compress it.
	 */
	if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
	    struct ip *ip;
	    int type;

	    mp = m;
	    ip = (struct ip *) (cp + PPP_HDRLEN);
	    if (mp->m_len <= PPP_HDRLEN) {
		mp = mp->m_next;
		if (mp == NULL)
		    break;
		ip = mtod(mp, struct ip *);
	    }
	    /* this code assumes the IP/TCP header is in one non-shared mbuf */
	    if (ip->ip_p == IPPROTO_TCP) {
		type = sl_compress_tcp(mp, ip, sc->sc_comp,
				       !(sc->sc_flags & SC_NO_TCP_CCID));
		switch (type) {
		case TYPE_UNCOMPRESSED_TCP:
		    protocol = PPP_VJC_UNCOMP;
		    break;
		case TYPE_COMPRESSED_TCP:
		    protocol = PPP_VJC_COMP;
		    cp = mtod(m, u_char *);
		    cp[0] = address;	/* header has moved */
		    cp[1] = control;
		    cp[2] = 0;
		    break;
		}
		cp[3] = protocol;	/* update protocol in PPP header */
	    }
	}