aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ieee80211.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-06-18 20:17:17 +0000
committerGuy Harris <guy@alum.mit.edu>2002-06-18 20:17:17 +0000
commitaca19eb102cc1cf8853f5a937050f567added04e (patch)
tree93d2cafb4006e7ce7d27fd24c0c74f619a4bf25e /packet-ieee80211.c
parent2cdcbf6d3c0417ce250e292cc4313e6cce2714da (diff)
downloadwireshark-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.c211
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;