Exemplo n.º 1
0
/**
 * same as tcpedit_set_encoder_plugin_byid() except we take the DLT_<name>
 * as a string to select it
 */
int
tcpedit_set_encoder_dltplugin_byname(tcpedit_t *tcpedit, const char *name)
{
    tcpeditdlt_plugin_t *plugin;
    tcpeditdlt_t *ctx;

    assert(tcpedit);

    ctx = tcpedit->dlt_ctx;
    assert(ctx);

    if (ctx->encoder) {
        tcpedit_seterr(tcpedit, "You have already selected a DLT encoder: %s", ctx->encoder->name);
        return TCPEDIT_ERROR;
    }

    plugin = tcpedit_dlt_getplugin_byname(ctx, name);
    if (plugin == NULL) {
        tcpedit_seterr(tcpedit, "No output DLT plugin available for: %s", name);
        return TCPEDIT_ERROR;
    }

    ctx->encoder = plugin;

    /* init the encoder plugin if it's not the decoder plugin too */
    if (ctx->encoder->dlt != ctx->decoder->dlt) {
        if (ctx->encoder->plugin_init(ctx) != TCPEDIT_OK) {
            /* plugin should generate the error */
            return TCPEDIT_ERROR;
        }
    }

    return TCPEDIT_OK;
}
Exemplo n.º 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_ieee80211_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    assert(ctx);
    assert(packet);
    assert(pktlen >= dlt_ieee80211_l2len(ctx, packet, pktlen));

    dbgx(3, "Decoding 802.11 packet " COUNTER_SPEC, ctx->tcpedit->runtime.packetnum);
    if (! ieee80211_is_data(ctx, packet, pktlen)) {
        tcpedit_seterr(ctx->tcpedit, "Packet " COUNTER_SPEC " is not a normal 802.11 data frame",
            ctx->tcpedit->runtime.packetnum);
        return TCPEDIT_SOFT_ERROR;
    }
    
    if (ieee80211_is_encrypted(ctx, packet, pktlen)) {
        tcpedit_seterr(ctx->tcpedit, "Packet " COUNTER_SPEC " is encrypted.  Unable to decode frame.",
            ctx->tcpedit->runtime.packetnum);
        return TCPEDIT_SOFT_ERROR;
    }

    ctx->l2len = dlt_ieee80211_l2len(ctx, packet, pktlen);
    memcpy(&(ctx->srcaddr), ieee80211_get_src((ieee80211_hdr_t *)packet), ETHER_ADDR_LEN);
    memcpy(&(ctx->dstaddr), ieee80211_get_dst((ieee80211_hdr_t *)packet), ETHER_ADDR_LEN);
    ctx->proto = dlt_ieee80211_proto(ctx, packet, pktlen);

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/*
 * Function to encode the layer 2 header back into the packet.
 * Returns: total packet len or TCPEDIT_ERROR
 */
int 
dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t dir)
{
    cisco_hdlc_t *hdlc;
    hdlc_config_t *config = NULL;
    hdlc_extra_t *extra = NULL;
    tcpeditdlt_plugin_t *plugin = NULL;
    u_char tmpbuff[MAXPACKET];
    int newpktlen;

    assert(ctx);
    assert(pktlen >= 4);
    assert(packet);

    /* Make room for our new l2 header if old l2len != 4 */
    if (ctx->l2len > 4) {
        memmove(packet + 4, packet + ctx->l2len, pktlen - ctx->l2len);
    } else if (ctx->l2len < 4) {
        memcpy(tmpbuff, packet, pktlen);
        memcpy(packet + 4, (tmpbuff + ctx->l2len), pktlen - ctx->l2len);
    }
    
    /* update the total packet length */
    newpktlen = pktlen + 4 - ctx->l2len;
    
    /* 
     * HDLC doesn't support direction, since we have no real src/dst addresses
     * to deal with, so we just use the original packet data or option data
     */
    hdlc = (cisco_hdlc_t *)packet;
    plugin = tcpedit_dlt_getplugin(ctx, dlt_value);
    config = plugin->config;
    extra = (hdlc_extra_t *)ctx->decoded_extra;

    /* set the address field */
    if (config->address < 65535) {
        hdlc->address = (uint8_t)config->address;
    } else if (extra->hdlc) {
        hdlc->address = extra->hdlc;
    } else {
        tcpedit_seterr(ctx->tcpedit, "%s", "Non-HDLC packet requires --hdlc-address");
        return TCPEDIT_ERROR;
    }
    
    /* set the control field */
    if (config->control < 65535) {
        hdlc->control = (uint8_t)config->control;
    } else if (extra->hdlc) {
        hdlc->control = extra->hdlc;
    } else {
        tcpedit_seterr(ctx->tcpedit, "%s", "Non-HDLC packet requires --hdlc-control");
        return TCPEDIT_ERROR;      
    }
    
    /* copy over our protocol */
    hdlc->protocol = ctx->proto;
    
    return newpktlen; /* success */
}
Exemplo n.º 5
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_linuxsll_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    int type;
    linux_sll_header_t *linux_sll;
    assert(ctx);
    assert(packet);

    if (pktlen < (int)sizeof(linux_sll_header_t))
        return TCPEDIT_ERROR;

    linux_sll = (linux_sll_header_t *)packet;
    ctx->proto = linux_sll->proto;
    ctx->l2len = sizeof(linux_sll_header_t);


    type = ntohs(linux_sll->type);
    if (type == ARPHRD_ETHER || type == ARPHRD_LOOPBACK) { /* ethernet or loopback */
        memcpy(&(ctx->srcaddr), linux_sll->address, ETHER_ADDR_LEN);
    } else {
        tcpedit_seterr(ctx->tcpedit, "%s", "DLT_LINUX_SLL pcap's must contain only ethernet or loopback packets");
        return TCPEDIT_ERROR;
    }

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 6
0
/**
 * each DLT type may require one or more user specified Layer 2 field
 * to be able to rewrite it as plain ethernet DLT_EN10MB
 * returns -1 on error or >= 0 on success
 */
int
dltrequires(tcpedit_t *tcpedit, int dlt)
{
    assert(tcpedit);
    int req = TCPEDIT_DLT_OK; // no change required by default

    switch(dlt) {
        case DLT_JUNIPER_ETHER:
        case DLT_EN10MB:
/*        case DLT_USER:
        case DLT_VLAN: */
            /* we have everthing we need in the original packet */
            break;

        case DLT_NULL:
        case DLT_RAW:
        case DLT_C_HDLC:
        case DLT_PPP_SERIAL:
            req = TCPEDIT_DLT_SRC + TCPEDIT_DLT_DST;
            /* we just have the proto */
            break;

        case DLT_LINUX_SLL:
            /* we have proto & SRC address */
            req = TCPEDIT_DLT_DST;
            break;

        default:
            tcpedit_seterr(tcpedit, "Invalid DLT Type: %d", dlt);
            req = -1;
    }

    return req;
}
Exemplo n.º 7
0
/*
 * Initializer function.  This function is called only once, if and only iif
 * this plugin will be utilized.  Remember, if you need to keep track of any state, 
 * store it in your plugin->config, not a global!
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int 
dlt_radiotap_init(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    radiotap_config_t *config; 
    assert(ctx);
    
    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to initalize unregistered plugin %s", dlt_name);
        return TCPEDIT_ERROR;
    }
    
    /* allocate memory for our deocde extra data */
    if (sizeof(radiotap_extra_t) > 0)
        ctx->decoded_extra = safe_malloc(sizeof(radiotap_extra_t));

    /* allocate memory for our config data */
    if (sizeof(radiotap_config_t) > 0)
        plugin->config = safe_malloc(sizeof(radiotap_config_t));
    
    config = (radiotap_config_t *)plugin->config;

    
    return TCPEDIT_OK; /* success */
}
Exemplo n.º 8
0
/*
 * Since this is used in a library, we should manually clean up after ourselves
 * Unless you allocated some memory in dlt_jnpr_ether_init(), this is just an stub.
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int
dlt_jnpr_ether_cleanup(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    jnpr_ether_config_t *config;

    assert(ctx);

    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name);
        return TCPEDIT_ERROR;
    }

    if (ctx->decoded_extra != NULL) {
        safe_free(ctx->decoded_extra);
        ctx->decoded_extra = NULL;
    }

    if (plugin->config != NULL) {
        /* clean up the en10mb plugin */
        config = (jnpr_ether_config_t *)ctx->encoder->config;
        tcpedit_dlt_cleanup(config->subctx);
        plugin->config = NULL;
    }

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 9
0
/*
 * Initializer function.  This function is called only once, if and only iif
 * this plugin will be utilized.  Remember, if you need to keep track of any state, 
 * store it in your plugin->config, not a global!
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int 
dlt_hdlc_init(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    hdlc_config_t *config;
    assert(ctx);
    
    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to initalize unregistered plugin %s", dlt_name);
        return TCPEDIT_ERROR;
    }
    
    /* allocate memory for our deocde extra data */
    if (sizeof(hdlc_extra_t) > 0)
        ctx->decoded_extra = safe_malloc(sizeof(hdlc_extra_t));

    /* allocate memory for our config data */
    if (sizeof(hdlc_config_t) > 0)
        plugin->config = safe_malloc(sizeof(hdlc_config_t));

    config = (hdlc_config_t *)plugin->config;

    /* default to unset */
    config->address = 65535;
    config->control = 65535;
    return TCPEDIT_OK; /* success */
}
Exemplo n.º 10
0
/*
 * Function returns the Layer 3 protocol type of the given packet, or TCPEDIT_ERROR on error
 * Make sure you return this value in NETWORK byte order!
 */
int
dlt_jnpr_ether_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    int jnpr_hdr_len;
    const u_char *ethernet;
    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;


    /* 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_hdr_len, &packet[JUNIPER_ETHER_EXTLEN_OFFSET], 2);

    jnpr_hdr_len = ntohs(jnpr_hdr_len) + JUNIPER_ETHER_HEADER_LEN;
    ethernet = packet + jnpr_hdr_len;

    /* let the en10mb plugin do the rest of the work */
    return tcpedit_dlt_proto(config->subctx, DLT_EN10MB, ethernet, (pktlen - jnpr_hdr_len));
}
Exemplo n.º 11
0
/**
 * returns the default MTU size for the given DLT type.  Returns -1
 * for invalid DLT
 */
int 
dlt2mtu(tcpedit_t *tcpedit, int dlt)
{
    int mtu;
    assert(tcpedit);
    switch (dlt) {
/*        case DLT_VLAN:
        case DLT_USER: */
        case DLT_PPP_SERIAL:
        case DLT_EN10MB:
        case DLT_RAW:
        case DLT_C_HDLC:
        case DLT_JUNIPER_ETHER:
            mtu = 1500;
            break;

        case DLT_LINUX_SLL:
            mtu = 16436;
            break;

        case DLT_LOOP:
            mtu = 16384;
            break;

        default:
            tcpedit_seterr(tcpedit, "Invalid DLT Type: %d", dlt);
            mtu = -1;
            break;
    }

    return mtu;
}
Exemplo n.º 12
0
/*
 * Since this is used in a library, we should manually clean up after ourselves
 * Unless you allocated some memory in dlt_null_init(), this is just an stub.
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int 
dlt_null_cleanup(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    assert(ctx);

    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name);
        return TCPEDIT_ERROR;
    }

    if (ctx->decoded_extra != NULL) {
        safe_free(ctx->decoded_extra);
        ctx->decoded_extra = NULL;
        ctx->decoded_extra_size = 0;
    }
        
    if (plugin->config != NULL) {
        safe_free(plugin->config);
        plugin->config = NULL;
        plugin->config_size = 0;
    }

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 13
0
/**
 * \brief Define the actual L2 header content.
 *
 * You need to set the data, it's lenght and which direction(s) to apply to.
 * BOTH - both directions (or in the case of no tcpprep cache file)
 * S2C - server to client (primary interface)
 * C2S - client to server (secondary interface)
 * 
 * NOTE: the datalen value must be the same between each call.
 */
int 
tcpedit_user_set_dlink(tcpedit_t *tcpedit, u_char *data, int datalen, tcpedit_user_dlt_direction direction)
{
    tcpeditdlt_t *ctx;
    tcpeditdlt_plugin_t *plugin;
    user_config_t *config;

    assert(tcpedit);

    ctx = tcpedit->dlt_ctx;
    assert(ctx);
    plugin = ctx->decoder;
    assert(plugin);
    config = (user_config_t *)plugin->config;

    /* sanity checks */
    if (datalen <= 0) {
        tcpedit_seterr(tcpedit, "%s", "user datalink length must be > 0");
        return TCPEDIT_ERROR;
    } else if (datalen > USER_L2MAXLEN) {
        tcpedit_seterr(tcpedit, "user datalink length is > %d.  Please increase USER_L2MAXLEN", USER_L2MAXLEN);
        return TCPEDIT_ERROR;
    }
        
    if ((config->length > 0) && (config->length != datalen)) {
        tcpedit_seterr(tcpedit, "%s", "Subsequent calls to tcpedit_user_set_dlink() must use the same datalen");
        return TCPEDIT_ERROR;        
    } else {
        config->length = datalen;
        switch (direction) {
            case TCPEDIT_USER_DLT_BOTH:
                memcpy(config->l2server, data, datalen);
                memcpy(config->l2client, data, datalen);
                break;
                
            case TCPEDIT_USER_DLT_S2C:
                memcpy(config->l2server, data, datalen);
                break;
                
            case TCPEDIT_USER_DLT_C2S:
                memcpy(config->l2client, data, datalen);
                break;
        }
    }
    return TCPEDIT_OK;
}
Exemplo n.º 14
0
/*
 * Function to encode the layer 2 header back into the packet.
 * Returns: total packet len or TCPEDIT_ERROR
 */
int
dlt_jnpr_ether_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t dir)
{
    assert(ctx);
    assert(pktlen > JUNIPER_ETHER_HEADER_LEN); /* MAGIC + Static fields + Extension Length */
    assert(packet);

    tcpedit_seterr(ctx->tcpedit, "%s", "DLT_JUNIPER_ETHER plugin does not support packet encoding");
    return TCPEDIT_ERROR;
}
Exemplo n.º 15
0
/*
 * Function to encode the layer 2 header back into the packet.
 * Returns: total packet len or TCPEDIT_ERROR
 */
int 
dlt_linuxsll_encode(tcpeditdlt_t *ctx, u_char *packet, _U_ int pktlen,
        _U_ tcpr_dir_t dir)
{
    assert(ctx);
    assert(packet);

    tcpedit_seterr(ctx->tcpedit, "%s", "DLT_LINUX_SLL plugin does not support packet encoding");
    return TCPEDIT_ERROR;
}
Exemplo n.º 16
0
/*
 * Function to encode the layer 2 header back into the packet.
 * Returns: total packet len or TCPEDIT_ERROR
 */
int 
dlt_radiotap_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t dir)
{
    assert(ctx);
    assert(pktlen > 0);
    assert(packet);
    
    tcpedit_seterr(ctx->tcpedit, "%s", "DLT_IEEE802_11_RADIO plugin does not support packet encoding");
    return TCPEDIT_ERROR;
}
Exemplo n.º 17
0
/* you should never decode packets with this plugin! */
int
dlt_user_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    assert(ctx);
    assert(packet);
    assert(pktlen);

    tcpedit_seterr(ctx->tcpedit, "%s", "DLT_USER0 plugin does not support packet decoding");
    return TCPEDIT_ERROR;
}
Exemplo n.º 18
0
/*
 * Function to encode the layer 2 header back into the packet.
 * Returns: total packet len or TCPEDIT_ERROR
 */
int 
dlt_null_encode(tcpeditdlt_t *ctx, u_char *packet, _U_ int pktlen,
        _U_ tcpr_dir_t dir)
{
    assert(ctx);
    assert(packet);
    
    tcpedit_seterr(ctx->tcpedit, "%s", "DLT_NULL and DLT_LOOP plugins do not support packet encoding");
    return TCPEDIT_ERROR;
}
Exemplo n.º 19
0
/*
 * Function returns the Layer 3 protocol type of the given packet, or TCPEDIT_ERROR on error
 */
int
dlt_user_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    assert(ctx);
    assert(packet);
    assert(pktlen);

    /* calling this for DLT_USER0 is broken */
    tcpedit_seterr(ctx->tcpedit, "%s", "Nonsensical calling of dlt_user_proto()");
    return TCPEDIT_ERROR;
}
Exemplo n.º 20
0
/**
 * Rewrite TCP/UDP ports using the following format:
 * <src>:<dst>,...
 */
int
tcpedit_set_port_map(tcpedit_t *tcpedit, char *value)
{
    assert(tcpedit);

    if (! parse_portmap(&tcpedit->portmap, value)) {
        tcpedit_seterr(tcpedit, 
                "Unable to parse portmap: %s", value);
        return TCPEDIT_ERROR;
    }
    return TCPEDIT_OK;
}
Exemplo n.º 21
0
/**
 * Rewrite the Source IP of any packet 
 */
int
tcpedit_set_srcip_map(tcpedit_t *tcpedit, char *value)
{
    assert(tcpedit);

    tcpedit->rewrite_ip = true;
    if (! parse_cidr_map(&tcpedit->srcipmap, value)) {
        tcpedit_seterr(tcpedit, "Unable to parse source ip map: %s", value);
        return TCPEDIT_ERROR;
    }
    return TCPEDIT_OK;
}
Exemplo n.º 22
0
/**
 * \brief Set the client to server (secondary) CIDR map (Pseudo NAT)
 *
 * Set the client to server (secondary) CIDR map using the given string
 * which is in the format of:
 * <match cidr>:<target cidr>,...
 * 192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24
 */
int
tcpedit_set_cidrmap_c2s(tcpedit_t *tcpedit, char *value)
{
    assert(tcpedit);

    tcpedit->rewrite_ip = true;
    if (! parse_cidr_map(&tcpedit->cidrmap2, value)) {
        tcpedit_seterr(tcpedit, "Unable to parse: %s", value);
        return TCPEDIT_ERROR;
    }
    return TCPEDIT_OK;
}
Exemplo n.º 23
0
/*
 * Initializer function.  This function is called only once, if and only if
 * this plugin will be utilized.  Remember, if you need to keep track of any state,
 * store it in your plugin->config, not a global!
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int
dlt_loop_init(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    assert(ctx);

    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to initalize unregistered plugin %s", dlt_name);
        return TCPEDIT_ERROR;
    }

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 24
0
/**
 * initialize our plugin library.  Pass the DLT of the source pcap handle.
 * Actions:
 * - Create new tcpeditdlt_t context
 * - Link tcpedit to new context
 * - Register plugins
 * - Select decoder plugin using srcdlt
 * - Select encoder plugin using destination name
 * - Initialize decoder/encoder plugins
 * - Parse options for encoder plugin
 * - Validate provides/reqiures + user options
 */
tcpeditdlt_t *
tcpedit_dlt_init(tcpedit_t *tcpedit, const int srcdlt) 
{
    tcpeditdlt_t *ctx;
    int rcode;

    assert(tcpedit);
    assert(srcdlt >= 0);

    ctx = (tcpeditdlt_t *)safe_malloc(sizeof(tcpeditdlt_t));

    /* do we need a side buffer for L3 data? */
#ifdef FORCE_ALIGN
    ctx->l3buff = (u_char *)safe_malloc(MAXPACKET);
#endif

    /* copy our tcpedit context */
    ctx->tcpedit = tcpedit;

    /* register all our plugins */
    if (tcpedit_dlt_register(ctx) != TCPEDIT_OK) {
        tcpedit_dlt_cleanup(ctx);
        return NULL;
    }

    /* Choose decode plugin */
    if ((ctx->decoder = tcpedit_dlt_getplugin(ctx, srcdlt)) == NULL) {
        tcpedit_seterr(tcpedit, "No DLT plugin available for source DLT: 0x%x", srcdlt);
        tcpedit_dlt_cleanup(ctx);
        return NULL;
    }

    /* set our dlt type */
    ctx->dlt = srcdlt;

    /* set our address type */
    ctx->addr_type = ctx->decoder->plugin_l2addr_type();

    /* initalize decoder plugin */
    rcode = ctx->decoder->plugin_init(ctx);
    if (tcpedit_checkerror(ctx->tcpedit, rcode, NULL) != TCPEDIT_OK) {
        tcpedit_dlt_cleanup(ctx);
        return NULL;
    }


    /* we're OK */
    return ctx;
}
Exemplo n.º 25
0
/**
 * Get the layer 2 length of the packet using the DLT plugin currently in
 * place
 */
int
tcpedit_dlt_l2len(tcpeditdlt_t *ctx, int dlt, const u_char *packet, const int pktlen)
{
    tcpeditdlt_plugin_t *plugin;
    assert(ctx);
    assert(dlt >= 0);
    assert(packet);
    assert(pktlen);
    
    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to find plugin for DLT 0x%04x", dlt);
        return -1;        
    }
    return plugin->plugin_l2len(ctx, packet, pktlen);
}
Exemplo n.º 26
0
/**
 * takes in a libpcap DLT_ type and returns the length of the layer2 header
 * returns -1 for unsupported DLT
 */
int
dlt2layer2len(tcpedit_t *tcpedit, int dlt)
{
    assert(tcpedit);
    int len;
    switch(dlt) {
        /*
        case DLT_USER:
            len = tcpedit->l2.len;
            break;
            */
        case DLT_NULL:
            len = 2;
            break;

        case DLT_RAW:
            len = 0;
            break;

        case DLT_EN10MB:
            len = 12;
            break;
            /*
        case DLT_VLAN:
            len = 14;
            break;
            */
        case DLT_LINUX_SLL:
            len = 16;
            break;

        case DLT_PPP_SERIAL:
        case DLT_C_HDLC:
            len = 4;
            break;

        case DLT_JUNIPER_ETHER:
            len = 36;
            break;

        default:
            tcpedit_seterr(tcpedit, "Invalid DLT Type: %d", dlt);
            len = -1;
    }

    return len;
}
Exemplo n.º 27
0
/*
 * This is where you should define all your AutoGen AutoOpts option parsing.
 * Any user specified option should have it's bit turned on in the 'provides'
 * bit mask.
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int
dlt_user_parse_opts(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    user_config_t *config;
    assert(ctx);

    plugin = tcpedit_dlt_getplugin(ctx, dlt_value);
    config = plugin->config;

    /*
     * --user-dlt will override the output DLT type, otherwise we'll use
     * the DLT of the decoder
     */
    if (HAVE_OPT(USER_DLT)) {
        config->dlt = OPT_VALUE_USER_DLT;
    } else {
        config->dlt = ctx->decoder->dlt;
    }

    /* --user-dlink */
    if (HAVE_OPT(USER_DLINK)) {
        int  ct = STACKCT_OPT(USER_DLINK);
        char **list = STACKLST_OPT(USER_DLINK);
        int first = 1;

        do  {
            char *p = *list++;
            if (first) {
                config->length = read_hexstring(p, config->l2server, USER_L2MAXLEN);
                memcpy(config->l2client, config->l2server, config->length);
            } else {
                if (config->length != read_hexstring(p, config->l2client, USER_L2MAXLEN)) {
                    tcpedit_seterr(ctx->tcpedit, "%s",
                                   "both --dlink's must contain the same number of bytes");
                    return TCPEDIT_ERROR;
                }
            }

            first = 0;
        } while (--ct > 0);
    }

    return TCPEDIT_OK; /* success */
}
Exemplo n.º 28
0
/**
 * \brief Merge the Layer 3 data back onto the mainbuffer so it's immediately
 *   after the layer 2 header
 * 
 * Since some L2 headers aren't strictly aligned, we need to "merge" the packet w/ L2 data
 * and the L3 buffer.  This is basically a NO-OP for things like vlan tagged ethernet (16 byte) header
 * or Cisco HDLC (4 byte header) but is critical for std ethernet (12 byte header)
 */
u_char *
tcpedit_dlt_merge_l3data(tcpeditdlt_t *ctx, int dlt, u_char *packet, const int pktlen, u_char *l3data)
{
    tcpeditdlt_plugin_t *plugin;
    assert(ctx);
    assert(dlt >= 0);
    assert(pktlen >= 0);
    assert(packet);

    if (l3data == NULL)
        return packet;
        
    if ((plugin = tcpedit_dlt_getplugin(ctx, dlt)) == NULL) {
        tcpedit_seterr(ctx->tcpedit, "Unable to find plugin for DLT 0x%04x", dlt);
        return NULL;
    }

    return plugin->plugin_merge_layer3(ctx, packet, pktlen, l3data);
}
Exemplo n.º 29
0
/*
 * Function returns the Layer 3 protocol type of the given packet, or TCPEDIT_ERROR on error
 */
int 
dlt_null_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    assert(ctx);
    assert(packet);
    assert(pktlen > 0);
    uint32_t *af_type; 
    int protocol = 0;
    
    af_type = (uint32_t *)packet;
    if (*af_type == PF_INET || SWAPLONG(*af_type) == PF_INET) {
        protocol = ETHERTYPE_IP;
    } else if (*af_type == PF_INET6 || SWAPLONG(*af_type) == PF_INET6) {
        protocol = ETHERTYPE_IP6;
    } else {
        tcpedit_seterr(ctx->tcpedit, "Unsupported DLT_NULL/DLT_LOOP PF_ type: 0x%04x", *af_type);
        return TCPEDIT_ERROR;
    }
    
    return htons(protocol);
}
Exemplo n.º 30
0
/*
 * Function returns a pointer to the layer 3 protocol header or NULL on error
 */
u_char *
dlt_jnpr_ether_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
{
    int l2len;
    assert(ctx);
    assert(packet);

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

    l2len = dlt_jnpr_ether_l2len(ctx, packet, pktlen);

    assert(pktlen >= l2len);

    return tcpedit_dlt_l3data_copy(ctx, packet, pktlen, l2len);
}