Beispiel #1
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;
}
Beispiel #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));

    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;
}