Beispiel #1
0
/**
 * This is the recommended method to edit a packet.  Returns (new) total packet length
 */
int
tcpedit_dlt_process(tcpeditdlt_t *ctx, u_char **packet, int pktlen, tcpr_dir_t direction)
{
    int rcode;
    
    assert(ctx);
    assert(packet);
    assert(pktlen);
    assert(direction == TCPR_DIR_C2S || direction == TCPR_DIR_S2C || direction == TCPR_DIR_NOSEND);
    
    /* nothing to do here */
    if (direction == TCPR_DIR_NOSEND)
        return pktlen;
    
    /* decode packet */    
    if ((rcode = tcpedit_dlt_decode(ctx, *packet, pktlen)) == TCPEDIT_ERROR) {
        return TCPEDIT_ERROR;
    } else if (rcode == TCPEDIT_WARN) {
        warnx("Warning decoding packet: %s", tcpedit_getwarn(ctx->tcpedit));
    } else if (rcode == TCPEDIT_SOFT_ERROR) {
        return rcode; /* can't edit the packet */
    }
    
    /* encode packet */
    if ((rcode = tcpedit_dlt_encode(ctx, *packet, pktlen, direction)) == TCPEDIT_ERROR) {
        return TCPEDIT_ERROR;
    } else if (rcode == TCPEDIT_WARN) {
        warnx("Warning encoding packet: %s", tcpedit_getwarn(ctx->tcpedit));
    }
       
    return rcode;
}
Beispiel #2
0
/*
 * Function to decode the layer 2 header in the packet.
 * You need to fill out:
 * - ctx->l2len
 * - ctx->srcaddr
 * - ctx->dstaddr
 * - ctx->proto
 * - ctx->decoded_extra
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int
dlt_jnpr_ether_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    int jnpr_header_len = 0;
    const u_char *ethernet = NULL;
    jnpr_ether_config_t *config;


    assert(ctx);
    assert(packet);
    assert(pktlen > JUNIPER_ETHER_HEADER_LEN); /* MAGIC + Static fields + Extension Length */

    config = (jnpr_ether_config_t *)ctx->encoder->config;


    /* first, verify magic */
    if (memcmp(packet, JUNIPER_ETHER_MAGIC, JUNIPER_ETHER_MAGIC_LEN) != 0) {
        tcpedit_seterr(ctx->tcpedit, "Invalid magic 0x%02X%02X%02X",
                       packet[0], packet[1], packet[2]);
        return TCPEDIT_ERROR;
    }

    /* next make sure the L2 header is present */
    if ((packet[JUNIPER_ETHER_OPTIONS_OFFSET] & JUNIPER_ETHER_L2PRESENT)
            != JUNIPER_ETHER_L2PRESENT) {
        tcpedit_seterr(ctx->tcpedit, "Frame is missing L2 Header: %x",
                       packet[JUNIPER_ETHER_OPTIONS_OFFSET]);
        return TCPEDIT_ERROR;
    }

    /* then get the Juniper header length */
    memcpy(&jnpr_header_len, &packet[JUNIPER_ETHER_EXTLEN_OFFSET], 2);

    jnpr_header_len = ntohs(jnpr_header_len) + JUNIPER_ETHER_HEADER_LEN;

    dbgx(1, "jnpr header len: %d", jnpr_header_len);
    /* make sure the packet is big enough to find the Ethernet Header */

    if (pktlen < jnpr_header_len + TCPR_ETH_H) {
        tcpedit_seterr(ctx->tcpedit, "Frame is too short! %d < %d",
                       pktlen, (jnpr_header_len + TCPR_ETH_H));
        return TCPEDIT_ERROR;
    }

    ctx->l2len = jnpr_header_len;

    /* jump to the appropriate offset */
    ethernet = packet + jnpr_header_len;

    /* let the en10mb plugin decode the rest */
    if (tcpedit_dlt_decode(config->subctx, ethernet, (pktlen - jnpr_header_len)) == TCPEDIT_ERROR)
        return TCPEDIT_ERROR;

    /* copy the subdecoder state to our encoder state */
    if (tcpedit_dlt_copy_decoder_state(ctx, config->subctx) == TCPEDIT_ERROR)
        return TCPEDIT_ERROR;

    return TCPEDIT_OK;
}