Пример #1
0
static const uint8_t* Encode_Packet(
    EncState* enc, const Packet* p, uint32_t* len)
{
    Buffer ibuf, obuf;
    ENC_STATUS status = ENC_BAD_PROTO;
    PROTO_ID next;

    ibuf.base = (uint8_t*)p->pkt;
    ibuf.off = ibuf.end = 0;
    ibuf.size = p->pkth->caplen;

    obuf.base = s_pkt;
    obuf.off = obuf.end = 0;
    obuf.size = sizeof(s_pkt);

    enc->layer = 0;
    enc->p = p;

    next = NextEncoder(enc);

    if ( next < PROTO_MAX )
    {
        Encoder e = encoders[next].fencode;
        status = (*e)(enc, &ibuf, &obuf);
    }
    if ( status != ENC_OK || enc->layer != p->next_layer )
    {
        *len = 0;
        return NULL;
    }
    *len = (uint32_t)obuf.end;
    return obuf.base + obuf.off;
}
Пример #2
0
static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out)
{
    int len;
    uint32_t start = out->end;

    IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start;
    IPHdr* ho = (IPHdr*)(out->base + out->end);
    PROTO_ID next = NextEncoder(enc);
    UPDATE_BOUND(out, sizeof(*ho));

    /* IPv4 encoded header is hardcoded 20 bytes */
    ho->ip_verhl = 0x45;
    ho->ip_off = 0;

    ho->ip_id = IpId_Next();
    ho->ip_tos = hi->ip_tos;
    ho->ip_proto = hi->ip_proto;

    if ( FORWARD(enc) )
    {
        ho->ip_src.s_addr = hi->ip_src.s_addr;
        ho->ip_dst.s_addr = hi->ip_dst.s_addr;

        ho->ip_ttl = FwdTTL(enc, hi->ip_ttl);
    }
    else
    {
        ho->ip_src.s_addr = hi->ip_dst.s_addr;
        ho->ip_dst.s_addr = hi->ip_src.s_addr;

        ho->ip_ttl = RevTTL(enc, hi->ip_ttl);
    }

    enc->ip_hdr = (uint8_t*)hi;
    enc->ip_len = IP_HLEN(hi) << 2;

    if ( next < PROTO_MAX )
    {
        ENC_STATUS err = encoders[next].fencode(enc, in, out);
        if ( ENC_OK != err ) return err;
    }
    if ( enc->proto )
    {
        ho->ip_proto = enc->proto;
        enc->proto = 0;
    }

    len = out->end - start;
    ho->ip_len = htons((uint16_t)len);

    ho->ip_csum = 0;

    /* IPv4 encoded header is hardcoded 20 bytes, we save some
     * cycles and use the literal header size for checksum */
    ho->ip_csum = in_chksum_ip((const uint16_t *)ho, sizeof *ho);

    return ENC_OK;
}
Пример #3
0
static ENC_STATUS Eth_Encode (EncState* enc, Buffer* in, Buffer* out)
{
    // not raw ip -> encode layer 2
    int raw = ( enc->flags & ENC_FLAG_RAW );

    EtherHdr* hi = (EtherHdr*)enc->p->layers[enc->layer-1].start;
    PROTO_ID next = NextEncoder(enc);

    // if not raw ip AND out buf is empty
    if ( !raw && (out->off == out->end) )
    {
        // for alignment
        out->off = out->end = SPARC_TWIDDLE;
    }
    // if not raw ip OR out buf is not empty
    if ( !raw || (out->off != out->end) )
    {
        // we get here for outer-most layer when not raw ip
        // we also get here for any encapsulated ethernet layer.
        EtherHdr* ho = (EtherHdr*)(out->base + out->end);
        UPDATE_BOUND(out, sizeof(*ho));

        ho->ether_type = hi->ether_type;
        if ( FORWARD(enc) )
        {
            memcpy(ho->ether_src, hi->ether_src, sizeof(ho->ether_src));
            /*If user configured remote MAC address, use it*/
            if (NULL != dst_mac)
                memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst));
            else
                memcpy(ho->ether_dst, hi->ether_dst, sizeof(ho->ether_dst));
        }
        else
        {
            memcpy(ho->ether_src, hi->ether_dst, sizeof(ho->ether_src));
            /*If user configured remote MAC address, use it*/
            if (NULL != dst_mac)
                memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst));
            else
                memcpy(ho->ether_dst, hi->ether_src, sizeof(ho->ether_dst));
        }
    }
    if ( next < PROTO_MAX )
        return encoders[next].fencode(enc, in, out);

    return ENC_OK;
}
Пример #4
0
static ENC_STATUS FPath_Encode (EncState* enc, Buffer* in, Buffer* out)
{
    // not raw ip -> encode layer 2
    int raw = ( enc->flags & ENC_FLAG_RAW );

    FPathHdr* hi = (FPathHdr*)enc->p->layers[enc->layer-1].start;
    PROTO_ID next = NextEncoder(enc);

    // if not raw ip AND out buf is empty
    if ( !raw && (out->off == out->end) )
    {
        // for alignment
        out->off = out->end = 0;
    }
    // if not raw ip OR out buf is not empty
    if ( !raw || (out->off != out->end) )
    {
        // we get here for outer-most layer when not raw ip
        // we also get here for any encapsulated ethernet layer.
        FPathHdr* ho = (FPathHdr*)(out->base + out->end);
        UPDATE_BOUND(out, sizeof(*ho));

        ho->fpath_type = hi->fpath_type;
        if ( FORWARD(enc) )
        {
            memcpy(ho->fpath_src, hi->fpath_src, sizeof(ho->fpath_src));
            memcpy(ho->fpath_dst, hi->fpath_dst, sizeof(ho->fpath_dst));
        }
        else
        {
            memcpy(ho->fpath_src, hi->fpath_dst, sizeof(ho->fpath_src));
            memcpy(ho->fpath_dst, hi->fpath_src, sizeof(ho->fpath_dst));
        }
    }
    if ( next < PROTO_MAX )
        return encoders[next].fencode(enc, in, out);

    return ENC_OK;
}
Пример #5
0
static ENC_STATUS Eth_Encode (EncState* enc, Buffer* in, Buffer* out)
{
    int outer = 0;
    int raw = enc->flags & ENC_FLAG_RAW;

    EtherHdr* hi = (EtherHdr*)enc->p->layers[enc->layer-1].start;
    PROTO_ID next = NextEncoder(enc);

    if ( raw && (out->off == out->end) )
    {
        // for alignment
        out->off = out->end = SPARC_TWIDDLE;
        outer = 1;  // encoding outermost eth
    }
    if ( raw || !outer )
    {
        // we get here for outer-most layer when raw is true;
        // we also get here for any encapsulated ethernet layer.
        EtherHdr* ho = (EtherHdr*)(out->base + out->end);
        UPDATE_BOUND(out, sizeof(*ho));

        if ( FORWARD(enc) )
        {
            memcpy(ho, hi, sizeof(*ho));
        }
        else
        {
            ho->ether_type = hi->ether_type;
            memcpy(ho->ether_src, hi->ether_dst, sizeof(ho->ether_src));
            memcpy(ho->ether_dst, hi->ether_src, sizeof(ho->ether_dst));
        }
    }
    if ( next < PROTO_MAX )
        return encoders[next].fencode(enc, in, out);

    return ENC_OK;
}
Пример #6
0
static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out)
{
    int len;
    uint32_t start = out->end;

    IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start;
    IPHdr* ho = (IPHdr*)(out->base + out->end);
    PROTO_ID next = NextEncoder(enc);
    UPDATE_BOUND(out, sizeof(*ho));

    len = GET_IP_HDR_LEN(hi) - sizeof(*hi);

    ho->ip_verhl = 0x45;
    ho->ip_off = 0;

    ho->ip_id = IpId_Next();
    ho->ip_tos = hi->ip_tos;
    ho->ip_proto = hi->ip_proto;

    if ( FORWARD(enc) )
    {
        uint8_t ttl = AdjTTL(hi->ip_ttl);

        ho->ip_src.s_addr = hi->ip_src.s_addr;
        ho->ip_dst.s_addr = hi->ip_dst.s_addr;

        if ( enc->p->ssnptr )
            ttl = GetTTL(enc);

#ifdef NORMALIZER
        if ( ttl < ScMinTTL() && ScNewTTL() )
            ttl = ScNewTTL();
#endif
        ho->ip_ttl = ttl;
    }
    else
    {
        uint8_t ttl = MAX_TTL;

        ho->ip_src.s_addr = hi->ip_dst.s_addr;
        ho->ip_dst.s_addr = hi->ip_src.s_addr;

        if ( enc->p->ssnptr )
            ttl = GetTTL(enc);

#ifdef NORMALIZER
        if ( ttl < ScMinTTL() && ScNewTTL() )
            ttl = ScNewTTL();
#endif
        ho->ip_ttl = ttl;
    }

    enc->ip_hdr = (uint8_t*)hi;
    enc->ip_len = IP_HLEN(hi) << 2;

    if ( next < PROTO_MAX )
    {
        int err = encoders[next].fencode(enc, in, out);
        if ( err ) return err;
    }  
    if ( enc->proto )
    {
        ho->ip_proto = enc->proto;
        enc->proto = 0;
    }
    len = out->end - start;
    ho->ip_len = htons((u_int16_t)len);
    ip_checksum(ho, len);

    return ENC_OK;
}