diff options
author | marcus <marcus@FreeBSD.org> | 2005-12-09 12:03:57 +0800 |
---|---|---|
committer | marcus <marcus@FreeBSD.org> | 2005-12-09 12:03:57 +0800 |
commit | 9ddc6c98b0dfaacdd6eba6418a1a1a4ff5c4a1d4 (patch) | |
tree | 505b6b1f89bdc883ebbaadde40108b2e3606aec1 /net/wireshark | |
parent | 05a2702edeea8b08559a8c6168e00e028d449039 (diff) | |
download | freebsd-ports-gnome-9ddc6c98b0dfaacdd6eba6418a1a1a4ff5c4a1d4.tar.gz freebsd-ports-gnome-9ddc6c98b0dfaacdd6eba6418a1a1a4ff5c4a1d4.tar.zst freebsd-ports-gnome-9ddc6c98b0dfaacdd6eba6418a1a1a4ff5c4a1d4.zip |
* Fix a bug in caclulating the 802.11 header length for QoS data frames
(way bad regression from previous code)
* Add support for packets w/ data padding between the 802.11 header and
the payload (as indicated in the radiotap flags)
* Add support for handling FCS indication in the radiotap flags
* Fix display of TSF (previous code was not byte swapping)
* Update ieee80211_mhz2ieee in radiotap.c to handle more channels
* Nuke some #if 0 code leftover in radiotap.c
Submitted by: sam
Diffstat (limited to 'net/wireshark')
-rw-r--r-- | net/wireshark/Makefile | 2 | ||||
-rw-r--r-- | net/wireshark/files/patch-epan_dissectors_packet-ieee80211.c | 240 | ||||
-rw-r--r-- | net/wireshark/files/patch-epan_dissectors_packet-radiotap.c | 206 |
3 files changed, 447 insertions, 1 deletions
diff --git a/net/wireshark/Makefile b/net/wireshark/Makefile index 0505bf786d11..82ac483e7908 100644 --- a/net/wireshark/Makefile +++ b/net/wireshark/Makefile @@ -7,7 +7,7 @@ PORTNAME= ethereal PORTVERSION= 0.10.13 -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= net ipv6 MASTER_SITES= ${MASTER_SITE_SOURCEFORGE} \ ftp://ftp.ethereal.com/pub/ethereal/all-versions/ diff --git a/net/wireshark/files/patch-epan_dissectors_packet-ieee80211.c b/net/wireshark/files/patch-epan_dissectors_packet-ieee80211.c new file mode 100644 index 000000000000..e2e1179952f5 --- /dev/null +++ b/net/wireshark/files/patch-epan_dissectors_packet-ieee80211.c @@ -0,0 +1,240 @@ +--- epan/dissectors/packet-ieee80211.c.orig Mon Oct 10 06:23:01 2005 ++++ epan/dissectors/packet-ieee80211.c Tue Dec 6 18:53:33 2005 +@@ -74,6 +74,10 @@ + #include <ctype.h> + #include "isprint.h" + ++#ifndef roundup2 ++#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ ++#endif ++ + /* Defragment fragmented 802.11 datagrams */ + static gboolean wlan_defragment = TRUE; + +@@ -635,11 +639,11 @@ + case DATA_FRAME: + len = (COOK_ADDR_SELECTOR(fcf) == DATA_ADDR_T4) ? DATA_LONG_HDR_LEN : + DATA_SHORT_HDR_LEN; +- if( IS_DATA_QOS(fcf)) ++ if (fcf & 0x80) + return len + 2; + else + return len; +- ++ + default: + return 4; /* XXX */ + } +@@ -1922,6 +1926,23 @@ + ether_to_str(addr)); + } + ++static guint32 ++crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len) ++{ ++ guint32 c_crc; ++ ++ c_crc = crc32_ccitt_tvb(tvb, hdr_len); ++ c_crc = crc32_ccitt_seed(tvb_get_ptr(tvb, hdr_size, len), len, ~c_crc); ++ ++ /* Byte reverse. */ ++ c_crc = ((unsigned char)(c_crc>>0)<<24) | ++ ((unsigned char)(c_crc>>8)<<16) | ++ ((unsigned char)(c_crc>>16)<<8) | ++ ((unsigned char)(c_crc>>24)<<0); ++ ++ return ( c_crc ); ++} ++ + typedef enum { + ENCAP_802_2, + ENCAP_IPX, +@@ -1935,7 +1956,7 @@ + dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, + proto_tree * tree, gboolean fixed_length_header, + gboolean has_radio_information, gint fcs_len, +- gboolean wlan_broken_fc) ++ gboolean wlan_broken_fc, gboolean datapad) + { + guint16 fcf, flags, frame_type_subtype; + guint16 seq_control; +@@ -1950,7 +1971,7 @@ + proto_tree *hdr_tree = NULL; + proto_tree *flag_tree; + proto_tree *fc_tree; +- guint16 hdr_len; ++ guint16 hdr_len, ohdr_len; + gboolean has_fcs; + gint len, reported_len, ivlen; + gboolean save_fragmented; +@@ -1994,6 +2015,9 @@ + hdr_len = DATA_LONG_HDR_LEN; + else + hdr_len = find_header_length (fcf); ++ ohdr_len = hdr_len; ++ if (datapad) ++ hdr_len = roundup2(hdr_len, 4); + frame_type_subtype = COMPOSE_FRAME_TYPE(fcf); + + /*if (check_col (pinfo->cinfo, COL_INFO)) +@@ -2495,9 +2519,13 @@ + reported_len -= 4; + if (tree) + { +- guint32 fcs = crc32_802_tvb(tvb, hdr_len + len); + guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len); ++ guint32 fcs; + ++ if (datapad) ++ fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len); ++ else ++ fcs = crc32_802_tvb(tvb, hdr_len + len); + if (fcs == sent_fcs) + proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb, + hdr_len + len, 4, sent_fcs, +@@ -2530,35 +2558,46 @@ + proto_item *qos_fields; + proto_tree *qos_tree; + ++ guint16 qosoff; + guint16 qos_control; + guint16 qos_priority; + guint16 qos_ack_policy; + guint16 qos_eosp; + guint16 qos_field_content; + +- qos_fields = proto_tree_add_text(hdr_tree, tvb, hdr_len - 2, 2, ++ /* ++ * We calculate the offset to the QoS header data as ++ * an offset relative to the end of the header. But ++ * when the header has been padded to align the data ++ * this must be done relative to true header size, not ++ * the padded/aligned value. To simplify this work we ++ * stash the original header size in ohdr_len instead ++ * of recalculating it. ++ */ ++ qosoff = ohdr_len - 2; ++ qos_fields = proto_tree_add_text(hdr_tree, tvb, qosoff, 2, + "QoS parameters"); + qos_tree = proto_item_add_subtree (qos_fields, ett_qos_parameters); + +- qos_control = tvb_get_letohs(tvb, hdr_len - 2); ++ qos_control = tvb_get_letohs(tvb, qosoff + 0); + qos_priority = COOK_QOS_PRIORITY(qos_control); + qos_ack_policy = COOK_QOS_ACK_POLICY(qos_control); + qos_eosp = COOK_QOS_EOSP(qos_control); + qos_field_content = COOK_QOS_FIELD_CONTENT( qos_control); + + proto_tree_add_uint_format (qos_tree, hf_qos_priority, tvb, +- hdr_len - 2, 2, qos_priority, ++ qosoff, 2, qos_priority, + "Priority: %d (%s) (%s)", + qos_priority, qos_tags[qos_priority], qos_acs[qos_priority]); + + if(flags & FLAG_FROM_DS) { + proto_tree_add_boolean (qos_tree, hf_qos_eosp, tvb, +- hdr_len - 2, 1, qos_eosp); ++ qosoff, 1, qos_eosp); + + if(IS_DATA_CF_POLL(frame_type_subtype)) { + /* txop limit */ + proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb, +- hdr_len - 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content); ++ qosoff + 1, 1, qos_field_content, "TXOP Limit: %d ", qos_field_content); + + }else { + /* qap ps buffer state */ +@@ -2572,7 +2611,7 @@ + buf_ac = COOK_PS_BUF_AC(qos_field_content); /*access category */ + buf_load = COOK_PS_BUF_LOAD(qos_field_content); + +- qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, hdr_len - 1, 1, ++ qos_ps_buf_state_fields = proto_tree_add_text(qos_tree, tvb, qosoff + 1, 1, + "QAP PS Buffer State: 0x%x", qos_field_content); + qos_ps_buf_state_tree = proto_item_add_subtree (qos_ps_buf_state_fields, ett_qos_ps_buf_state); + +@@ -2581,25 +2620,25 @@ + 1, 1, buf_state); + + proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_ac, tvb, +- hdr_len - 1, 1, buf_ac, "Priority: %d (%s)", ++ qosoff + 1, 1, buf_ac, "Priority: %d (%s)", + buf_ac, wme_acs[buf_ac]); + + proto_tree_add_uint_format (qos_ps_buf_state_tree, hf_qos_buf_load, tvb, +- hdr_len - 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096)); ++ qosoff + 1, 1, buf_load, "Buffered load: %d ", (buf_load * 4096)); + */ + + } + } else if(qos_eosp) { + /* txop limit requested */ + proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb, +- hdr_len - 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254)); ++ qosoff + 1, 1, qos_field_content, "Queue Size: %d ", (qos_field_content * 254)); + } else { + /* queue size */ + proto_tree_add_uint_format (qos_tree, hf_qos_field_content, tvb, +- hdr_len - 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content); ++ qosoff + 1, 1, qos_field_content, "TXOP Limit Requested: %d ", qos_field_content); + } + +- proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, hdr_len - 2, 1, ++ proto_tree_add_uint (qos_tree, hf_qos_ack_policy, tvb, qosoff, 1, + qos_ack_policy); + + } /* end of qos control field */ +@@ -2957,7 +2996,17 @@ + dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) + { + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, +- pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE); ++ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE); ++} ++ ++/* ++ * Dissect 802.11 with a variable-length link-layer header and data padding. ++ */ ++static void ++dissect_ieee80211_datapad (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) ++{ ++ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, ++ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, TRUE); + } + + /* +@@ -2968,7 +3017,7 @@ + dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) + { + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE, +- pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE); ++ pinfo->pseudo_header->ieee_802_11.fcs_len, FALSE, FALSE); + } + + /* +@@ -2979,7 +3028,7 @@ + static void + dissect_ieee80211_bsfc (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) + { +- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE); ++ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, 0, TRUE, FALSE); + } + + /* +@@ -2989,7 +3038,7 @@ + static void + dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) + { +- dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE); ++ dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, 0, FALSE, FALSE); + } + + static void +@@ -3773,6 +3822,7 @@ + register_dissector("wlan", dissect_ieee80211, proto_wlan); + register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan); + register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan); ++ register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan); + register_init_routine(wlan_defragment_init); + + wlan_tap = register_tap("wlan"); diff --git a/net/wireshark/files/patch-epan_dissectors_packet-radiotap.c b/net/wireshark/files/patch-epan_dissectors_packet-radiotap.c new file mode 100644 index 000000000000..ece82f94e19e --- /dev/null +++ b/net/wireshark/files/patch-epan_dissectors_packet-radiotap.c @@ -0,0 +1,206 @@ +--- epan/dissectors/packet-radiotap.c.orig Mon Oct 10 06:23:07 2005 ++++ epan/dissectors/packet-radiotap.c Tue Dec 6 18:34:19 2005 +@@ -73,7 +73,6 @@ + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13, +- IEEE80211_RADIOTAP_FCS = 14, + IEEE80211_RADIOTAP_EXT = 31 + }; + +@@ -121,6 +120,11 @@ + #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received + * with fragmentation + */ ++#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ ++#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between ++ * 802.11 header and payload ++ * (to 32-bit boundary) ++ */ + + /* protocol */ + static int proto_radiotap = -1; +@@ -140,11 +144,14 @@ + static int hf_radiotap_db_antnoise = -1; + static int hf_radiotap_txpower = -1; + static int hf_radiotap_preamble = -1; ++static int hf_radiotap_fcs = -1; ++static int hf_radiotap_datapad = -1; + + static gint ett_radiotap = -1; + static gint ett_radiotap_present = -1; + + static dissector_handle_t ieee80211_handle; ++static dissector_handle_t ieee80211_datapad_handle; + + static void + dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +@@ -190,6 +197,12 @@ + { 0, NULL }, + }; + ++ static const value_string truefalse_type[] = { ++ { 0, "False" }, ++ { 1, "True" }, ++ { 0, NULL }, ++ }; ++ + static hf_register_info hf[] = { + { &hf_radiotap_version, + { "Header revision", "radiotap.version", +@@ -208,6 +221,14 @@ + { "Preamble", "radiotap.flags.preamble", + FT_UINT32, BASE_DEC, VALS(preamble_type), 0x0, "", HFILL } }, + ++ /* XXX for debugging */ ++ { &hf_radiotap_fcs, ++ { "FCS", "radiotap.flags.fcs", ++ FT_UINT32, BASE_DEC, VALS(truefalse_type), 0x0, "", HFILL } }, ++ { &hf_radiotap_datapad, ++ { "DATAPAD", "radiotap.flags.datapad", ++ FT_UINT32, BASE_DEC, VALS(truefalse_type), 0x0, "", HFILL } }, ++ + { &hf_radiotap_mactime, + { "MAC timestamp", "radiotap.mactime", + FT_UINT64, BASE_DEC, NULL, 0x0, "", HFILL } }, +@@ -257,6 +278,7 @@ + static int + ieee80211_mhz2ieee(int freq, int flags) + { ++#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990) + if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ + if (freq == 2484) + return 14; +@@ -265,16 +287,28 @@ + else + return 15 + ((freq - 2512) / 20); + } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */ +- return (freq - 5000) / 5; ++ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) ++ return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5; ++ if (freq <= 5000) ++ return (freq - 4000) / 5; ++ else ++ return (freq - 5000) / 5; + } else { /* either, guess */ + if (freq == 2484) + return 14; + if (freq < 2484) + return (freq - 2407) / 5; +- if (freq < 5000) +- return 15 + ((freq - 2512) / 20); ++ if (freq < 5000) { ++ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) ++ return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400)/5; ++ else if (freq > 4900) ++ return (freq - 4000) / 5; ++ else ++ return 15 + ((freq - 2512) / 20); ++ } + return (freq - 5000) / 5; + } ++#undef IS_CHAN_IN_PUBLIC_SAFETY_BAND + } + + static void +@@ -294,7 +328,7 @@ + guint32 length; + guint32 rate, freq, flags; + gint8 dbm; +- guint8 db; ++ guint8 db, rflags; + guint32 present, next_present; + int bit; + +@@ -334,6 +368,7 @@ + */ + offset += sizeof(struct ieee80211_radiotap_header); + ++ rflags = 0; + for (; present; present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); +@@ -344,45 +379,16 @@ + switch (bit) { + case IEEE80211_RADIOTAP_FLAGS: + if (tree) { ++ rflags = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(radiotap_tree, hf_radiotap_preamble, +- tvb, 0, 0, (tvb_get_guint8(tvb, offset) & +- IEEE80211_RADIOTAP_F_SHORTPRE) != 0); ++ tvb, 0, 0, (rflags&IEEE80211_RADIOTAP_F_SHORTPRE) != 0); ++ proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs, ++ tvb, 0, 0, (rflags&IEEE80211_RADIOTAP_F_FCS) != 0); ++ proto_tree_add_uint(radiotap_tree, hf_radiotap_datapad, ++ tvb, 0, 0, (rflags&IEEE80211_RADIOTAP_F_DATAPAD) != 0); + } + offset++; + /* XXX CFP, WEP, FRAG */ +-#if 0 +- capability = tvb_get_letohs (tvb, offset); +- +- cap_item = proto_tree_add_uint_format (tree, ff_capture, +- tvb, offset, 2, +- capability, +- "Capability Information: 0x%04X", +- capability); +- cap_tree = proto_item_add_subtree (cap_item, ett_cap_tree); +- proto_tree_add_boolean (cap_tree, ff_cf_ess, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_cf_ibss, tvb, offset, 2, +- capability); +- if (ESS_SET (capability) != 0) /* This is an AP */ +- proto_tree_add_uint (cap_tree, ff_cf_ap_poll, tvb, offset, 2, +- capability); +- +- else /* This is a STA */ +- proto_tree_add_uint (cap_tree, ff_cf_sta_poll, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_cf_privacy, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_cf_preamble, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_cf_pbcc, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_cf_agility, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_short_slot_time, tvb, offset, 2, +- capability); +- proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2, +- capability); +-#endif + break; + case IEEE80211_RADIOTAP_RATE: + rate = tvb_get_guint8(tvb, offset) & 0x7f; +@@ -480,8 +486,8 @@ + break; + case IEEE80211_RADIOTAP_TSFT: + if (tree) { +- proto_tree_add_item(radiotap_tree, hf_radiotap_mactime, +- tvb, offset, 8, FALSE); ++ proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime, ++ tvb, offset, 8, tvb_get_letoh64(tvb, offset)); + } + offset+=8; + break; +@@ -495,8 +501,11 @@ + } + } + ++ if (rflags & IEEE80211_RADIOTAP_F_FCS) ++ pinfo->pseudo_header->ieee_802_11.fcs_len = 4; + /* dissect the 802.11 header next */ +- call_dissector(ieee80211_handle, ++ call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ? ++ ieee80211_datapad_handle : ieee80211_handle, + tvb_new_subset(tvb, length, -1, -1), pinfo, tree); + #undef BITNO_32 + #undef BITNO_16 +@@ -513,6 +522,7 @@ + + /* handle for 802.11 dissector */ + ieee80211_handle = find_dissector("wlan"); ++ ieee80211_datapad_handle = find_dissector("wlan_datapad"); + + radiotap_handle = create_dissector_handle(dissect_radiotap, proto_radiotap); + |