diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-06-18 20:17:17 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-06-18 20:17:17 +0000 |
commit | aca19eb102cc1cf8853f5a937050f567added04e (patch) | |
tree | 93d2cafb4006e7ce7d27fd24c0c74f619a4bf25e /packet-ieee80211.c | |
parent | 2cdcbf6d3c0417ce250e292cc4313e6cce2714da (diff) | |
download | wireshark-aca19eb102cc1cf8853f5a937050f567added04e.tar.gz wireshark-aca19eb102cc1cf8853f5a937050f567added04e.tar.bz2 wireshark-aca19eb102cc1cf8853f5a937050f567added04e.zip |
From Solomon Peachy: do WEP decryption before reassembly.
Use "memset()" rather than "bzero()", as "memset()" is the official ANSI
C routine (and you get an error when compiling with MSVC++ if you use
"bzero()").
svn path=/trunk/; revision=5699
Diffstat (limited to 'packet-ieee80211.c')
-rw-r--r-- | packet-ieee80211.c | 211 |
1 files changed, 107 insertions, 104 deletions
diff --git a/packet-ieee80211.c b/packet-ieee80211.c index 03fddb6f48..86069370ac 100644 --- a/packet-ieee80211.c +++ b/packet-ieee80211.c @@ -3,7 +3,7 @@ * Copyright 2000, Axis Communications AB * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com * - * $Id: packet-ieee80211.c,v 1.65 2002/06/18 08:38:17 guy Exp $ + * $Id: packet-ieee80211.c,v 1.66 2002/06/18 20:17:17 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -90,7 +90,7 @@ static guint8 **wep_keys = NULL; static int *wep_keylens = NULL; static void init_wepkeys(void); static int wep_decrypt(guint8 *buf, guint32 len, int key_override); -static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb); +static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len); #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;} /* #define USE_ENV */ @@ -1125,7 +1125,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, guint16 hdr_len; gint len, reported_len; gboolean save_fragmented; - tvbuff_t *volatile next_tvb; + tvbuff_t *volatile next_tvb = NULL; guint32 addr_type; volatile gboolean is_802_2; @@ -1559,6 +1559,102 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, } /* + * For WEP-encrypted frames, dissect the WEP parameters and decrypt + * the data, if we have a matching key. Otherwise display it as data. + */ + if (IS_WEP(COOK_FLAGS(fcf))) { + gboolean can_decrypt = FALSE; + proto_tree *wep_tree = NULL; + + if (tree) { + proto_item *wep_fields; + + wep_fields = proto_tree_add_text(tree, tvb, hdr_len, 4, + "WEP parameters"); + + wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters); + proto_tree_add_item (wep_tree, hf_wep_iv, tvb, hdr_len, 3, TRUE); + + proto_tree_add_uint (wep_tree, hf_wep_key, tvb, hdr_len, 1, + COOK_WEP_KEY (tvb_get_guint8 (tvb, 3))); + } + + len = tvb_length_remaining(tvb, 4); + reported_len = tvb_reported_length_remaining(tvb, 4); + if (len == -1 || reported_len == -1) { + /* We don't have anything beyond the IV. */ + return; + } + + /* + * Well, this packet should, in theory, have an ICV. + * Do we have the entire packet, and does it have enough data for + * the ICV? + */ + if (reported_len < 4) { + /* + * The packet is claimed not to even have enough data for a + * 4-byte ICV. + * Pretend it doesn't have an ICV. + */ + ; + } else if (len < reported_len) { + /* + * The packet is claimed to have enough data for a 4-byte ICV, + * but we didn't capture all of the packet. + * Slice off the 4-byte ICV from the reported length, and trim + * the captured length so it's no more than the reported length; + * that will slice off what of the ICV, if any, is in the + * captured length. + * + */ + reported_len -= 4; + if (len > reported_len) + len = reported_len; + } else { + /* + * We have the entire packet, and it includes a 4-byte ICV. + * Slice it off, and put it into the tree. + * + * We only support decrypting if we have the the ICV. + * + * XXX - the ICV is encrypted; we're putting the encrypted + * value, not the decrypted value, into the tree. + */ + len -= 4; + reported_len -= 4; + if (tree) + proto_tree_add_item (wep_tree, hf_wep_icv, tvb, len, 4, + FALSE); + can_decrypt = TRUE; + } + + if (!can_decrypt || (next_tvb = try_decrypt_wep(tvb, hdr_len, reported_len - hdr_len + 4)) == NULL) { + /* WEP decode impossible or failed, treat payload as raw data. */ + next_tvb = tvb_new_subset(tvb, 4, len, reported_len); + + call_dissector(data_handle, next_tvb, pinfo, tree); + return; + } else { + add_new_data_source(pinfo, next_tvb, "Decrypted WEP data"); + /* + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Decrypted WEP data"); + */ + } + hdr_len += 4; /* so we don't include the IV in the fragment payload */ + } + + if (next_tvb == NULL) { + next_tvb = tvb; /* and WEP decode failed, if attempted. offsets ok. */ + } else { + /* WEP decode successful! Lie about offsets as we're using a child skb */ + reported_len -= hdr_len; + len -= hdr_len; + hdr_len = 0; + } + + /* * Do defragmentation if "wlan_defragment" is true, and we have more * fragments or this isn't the first fragment. * @@ -1589,7 +1685,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, * whatever reassembly is in progress, if any, and see * if it's done. */ - fd_head = fragment_add_seq_check(tvb, hdr_len, pinfo, seq_number, + fd_head = fragment_add_seq_check(next_tvb, hdr_len, pinfo, seq_number, wlan_fragment_table, wlan_reassembled_table, frag_number, @@ -1619,7 +1715,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, * Not fragmented, really. * Show it as a regular frame. */ - next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len); + next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len); } /* It's not fragmented. */ @@ -1640,7 +1736,7 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, /* First fragment, or not fragmented. Dissect what we have here. */ /* Get a tvbuff for the payload. */ - next_tvb = tvb_new_subset (tvb, hdr_len, len, reported_len); + next_tvb = tvb_new_subset (next_tvb, hdr_len, len, reported_len); /* * If this is the first fragment, but not the only fragment, @@ -1661,100 +1757,8 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, call_dissector(data_handle, next_tvb, pinfo, tree); pinfo->fragmented = save_fragmented; return; - } - - /* - * For WEP-encrypted frames, dissect the WEP parameters and decrypt - * the data, if we have a matching key. Otherwise display it as data. - * - * XXX - is WEP encrypting done *before* fragmentation or *after* - * fragmentation? We're doing the WEP stuff here, after defragmenting, - * which is correct only if WEP encrypting is done *after* fragmentation. - */ - if (IS_WEP(COOK_FLAGS(fcf))) { - gboolean can_decrypt = FALSE; - tvbuff_t *tmp_tvb; - proto_tree *wep_tree = NULL; - - if (tree) { - proto_item *wep_fields; - - wep_fields = proto_tree_add_text(tree, next_tvb, 0, 4, - "WEP parameters"); - - wep_tree = proto_item_add_subtree (wep_fields, ett_wep_parameters); - proto_tree_add_item (wep_tree, hf_wep_iv, next_tvb, 0, 3, TRUE); - - proto_tree_add_uint (wep_tree, hf_wep_key, next_tvb, 3, 1, - COOK_WEP_KEY (tvb_get_guint8 (next_tvb, 3))); - } - - len = tvb_length_remaining(next_tvb, 4); - reported_len = tvb_reported_length_remaining(next_tvb, 4); - if (len == -1 || reported_len == -1) { - /* We don't have anything beyond the IV. */ - return; - } - - /* - * Well, this packet should, in theory, have an ICV. - * Do we have the entire packet, and does it have enough data for - * the ICV? - */ - if (reported_len < 4) { - /* - * The packet is claimed not to even have enough data for a - * 4-byte ICV. - * Pretend it doesn't have an ICV. - */ - ; - } else if (len < reported_len) { - /* - * The packet is claimed to have enough data for a 4-byte ICV, - * but we didn't capture all of the packet. - * Slice off the 4-byte ICV from the reported length, and trim - * the captured length so it's no more than the reported length; - * that will slice off what of the ICV, if any, is in the - * captured length. - * - */ - reported_len -= 4; - if (len > reported_len) - len = reported_len; - } else { - /* - * We have the entire packet, and it includes a 4-byte ICV. - * Slice it off, and put it into the tree. - * - * We only support decrypting if we have the the ICV. - * - * XXX - the ICV is encrypted; we're putting the encrypted - * value, not the decrypted value, into the tree. - */ - len -= 4; - reported_len -= 4; - if (tree) - proto_tree_add_item (wep_tree, hf_wep_icv, next_tvb, 4 + len, 4, - FALSE); - can_decrypt = TRUE; - } - - if (!can_decrypt || (tmp_tvb = try_decrypt_wep(next_tvb)) == NULL) { - /* WEP decode impossible or failed, treat payload as raw data. */ - tmp_tvb = tvb_new_subset(next_tvb, 4, len, reported_len); - - call_dissector(data_handle, tmp_tvb, pinfo, tree); - return; - } else { - add_new_data_source(pinfo, tmp_tvb, "Decrypted WEP data"); - /* - if (check_col(pinfo->cinfo, COL_INFO)) - col_set_str(pinfo->cinfo, COL_INFO, "Decrypted WEP data"); - */ - } - next_tvb = tmp_tvb; - } - + } + switch (COOK_FRAME_TYPE (fcf)) { @@ -2405,11 +2409,10 @@ static const guint32 wep_crc32_table[256] = { 0x2d02ef8dL }; -static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb) { +static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) { guint8 *tmp = NULL; int i; tvbuff_t *decr_tvb = NULL; - guint len = tvb_length(tvb); if (num_wepkeys < 1) return NULL; @@ -2425,7 +2428,7 @@ static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb) { #if 0 printf("trying %d\n", i); #endif - tvb_memcpy(tvb, tmp, 0, len); + tvb_memcpy(tvb, tmp, offset, len); if (wep_decrypt(tmp, len, i) == 0) { /* decrypt successful, let's set up a new data tvb. */ @@ -2587,7 +2590,7 @@ static void init_wepkeys(void) { #endif wep_keys[i] = malloc(32 * sizeof(guint8)); - bzero(wep_keys[i], 32 * sizeof(guint8)); + memset(wep_keys[i], 0, 32 * sizeof(guint8)); tmp3 = wep_keys[i]; while ((tmp != NULL) && (*tmp != 0)) { tmp3[j] = strtoul(tmp, &tmp2, 16) & 0xff; |