Beispiel #1
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 */
}
Beispiel #2
0
/* 
 * return the length of the L2 header w/ 802.11 header of the current packet
 */
int
dlt_radiotap_80211_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    int radiolen;
    u_char *data;
    
    radiolen = dlt_radiotap_l2len(ctx, packet, pktlen);
    data = dlt_radiotap_get_80211(ctx, packet, pktlen, radiolen);
    radiolen += dlt_ieee80211_l2len(ctx, data, pktlen - radiolen);
    return radiolen;
}
Beispiel #3
0
/*
 * Function returns a pointer to the layer 3 protocol header or NULL on error
 */
u_char *
dlt_radiotap_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
{
    int radiolen, l2len;
    u_char *data;
    
    assert(ctx);
    assert(packet);
    
    radiolen = dlt_radiotap_l2len(ctx, packet, pktlen);
    data = dlt_radiotap_get_80211(ctx, packet, pktlen, radiolen);
    l2len = dlt_ieee80211_l2len(ctx, data, pktlen - radiolen);
    return tcpedit_dlt_l3data_copy(ctx, data, pktlen - radiolen, l2len);
}
Beispiel #4
0
/*
 * Function returns a pointer to the layer 3 protocol header or NULL on error
 */
u_char *
dlt_ieee80211_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
{
    int l2len;
    assert(ctx);
    assert(packet);

    l2len = dlt_ieee80211_l2len(ctx, packet, pktlen);

    assert(pktlen >= l2len);
    dbgx(1, "Getting data for packet " COUNTER_SPEC " from offset: %d", ctx->tcpedit->runtime.packetnum, l2len);
    
    return tcpedit_dlt_l3data_copy(ctx, packet, pktlen, l2len);
}
Beispiel #5
0
/*
 * function merges the packet (containing L2 and old L3) with the l3data buffer
 * containing the new l3 data.  Note, if L2 % 4 == 0, then they're pointing to the
 * same buffer, otherwise there was a memcpy involved on strictly aligned architectures
 * like SPARC
 */
u_char *
dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
{
    int l2len;
    assert(ctx);
    assert(packet);
    assert(l3data);

    
    l2len = dlt_ieee80211_l2len(ctx, packet, pktlen);
    
    assert(pktlen >= l2len);
    
    return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
}
Beispiel #6
0
/*
 * Function returns the Layer 3 protocol type of the given packet, or TCPEDIT_ERROR on error
 */
int 
dlt_ieee80211_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
{
    int l2len;
    int hdrlen = 0;
    u_int16_t *frame_control, fc;
    struct tcpr_802_2snap_hdr *hdr;

    assert(ctx);
    assert(packet);

    l2len = dlt_ieee80211_l2len(ctx, packet, pktlen);
    assert(pktlen >= l2len);

    /* check 802.11 frame control field */
    frame_control = (u_int16_t *)packet;
    fc = ntohs(*frame_control);

    /* Not all 802.11 frames have data */
    if ((fc & ieee80211_FC_TYPE_MASK) != ieee80211_FC_TYPE_DATA)
        return TCPEDIT_SOFT_ERROR;
    
    /* Some data frames are QoS and have no data 
        if (((fc & ieee80211_FC_SUBTYPE_MASK) & ieee80211_FC_SUBTYPE_QOS) == ieee80211_FC_SUBTYPE_QOS)
        return TCPEDIT_SOFT_ERROR;
    */
    if ((fc & ieee80211_FC_SUBTYPE_QOS) == ieee80211_FC_SUBTYPE_QOS) {
        hdrlen += 2;
    }
    
    /* figure out the actual header length */
    if (ieee80211_USE_4(fc)) {
        hdrlen += sizeof(ieee80211_addr4_hdr_t);
    } else {
        hdrlen += sizeof(ieee80211_hdr_t);
    }
    
    hdr = (struct tcpr_802_2snap_hdr *)&packet[hdrlen];

    /* verify the header is 802.2SNAP (8 bytes) not 802.2 (3 bytes) */
    if (hdr->snap_dsap == 0xAA && hdr->snap_ssap == 0xAA)
        return hdr->snap_type;
    

    return TCPEDIT_SOFT_ERROR; /* 802.2 has no type field */
}