00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_FRAME_STATS_STATS_HH_
00023 # define WIFI_FRAME_STATS_STATS_HH_
00024
00025 extern "C"
00026 {
00027 # include <stdint.h>
00028 }
00029
00030 # include <map>
00031 # include <utility>
00032
00033 # include <boost/tuple/tuple.hpp>
00034 # include <boost/tuple/tuple_comparison.hpp>
00035 # include <boost/optional.hpp>
00036
00037 # include <wipal/wifi/frame/stats/delimiter_frames.hh>
00038 # include <wipal/wifi/frame/stats/simple_counters.hh>
00039 # include <wipal/wifi/frame/stats/gap_lengths.hh>
00040 # include <wipal/wifi/frame/stats/missed_estimations.hh>
00041 # include <wipal/wifi/frame/stats/tfi_plot.hh>
00042 # include <wipal/wifi/frame/stats/bss_stats.hh>
00043 # include <wipal/wifi/frame/stats/ssid_stats.hh>
00044 # include <wipal/wifi/frame/stats/activity.hh>
00045 # include <wipal/wifi/frame/stats/growth.hh>
00046 # include <wipal/tool/microseconds.hh>
00047 # include <wipal/wifi/addr.hh>
00048 # include <wipal/wifi/frame/seqctl.hh>
00049 # include <wipal/wifi/frame/dissector/default_hooks.hh>
00050 # include <wipal/wifi/frame/mgt.hh>
00051
00052 namespace wifi
00053 {
00054
00055 namespace frame
00056 {
00057
00058 namespace stats
00059 {
00060
00061 struct stats: public abstract_stats
00062 {
00063 stats();
00064
00065 template <class PhyHeader, class Frame>
00066 void
00067 account(const Frame& f);
00068
00069 void restart();
00070 std::ostream& print(std::ostream& o) const;
00071
00072 enum { growth_epoch = 60 * 1000 * 1000 };
00073
00074 enum transmitter_type { unknown, client, ap };
00075
00076
00077 typedef growth<addr, growth_epoch> addr_growth;
00078 typedef growth<addr, growth_epoch> bssid_growth;
00079 typedef growth<addr, growth_epoch> ibssid_growth;
00080 typedef growth<std::string, growth_epoch> ssid_growth;
00081 typedef growth<addr, growth_epoch> ap_growth;
00082
00083 const delimiter_frames& delimiter_frames_get() const;
00084 const simple_counters& simple_counters_get() const;
00085 const gap_lengths& gap_lengths_get() const;
00086 const missed_estimations& missed_estimations_get() const;
00087 const tfi_plot& tfi_plot_get() const;
00088 const bss_stats& bss_stats_get() const;
00089 const ssid_stats& ssid_stats_get() const;
00090 const activity& activity_get() const;
00091 const addr_growth& addr_growth_get() const;
00092 const bssid_growth& bssid_growth_get() const;
00093 const ibssid_growth& ibssid_growth_get() const;
00094 const ssid_growth& ssid_growth_get() const;
00095 const ap_growth& ap_growth_get() const;
00096
00097 private:
00098 struct beacon_body
00099 {
00100 uint64_t timestamp;
00101 uint16_t beacon_interval;
00102 uint16_t capability;
00103 uint8_t ssid_id;
00104 uint8_t ssid_len;
00105 uint8_t ssid[];
00106 } __attribute__((packed));
00107
00108 enum
00109 {
00110 state_lifetime = 60 * 1000 * 1000,
00111 min_frame_sending_time = 106
00112 };
00113
00114 struct state
00115 {
00116 state(unsigned last_frame_id,
00117 const seqctl& last_sc,
00118 const tool::microseconds& last_rx_stamp);
00119
00120 unsigned last_frame_id;
00121 seqctl last_sc;
00122 tool::microseconds last_rx_stamp;
00123 };
00124
00125 typedef boost::tuple<addr, addr, uint8_t> state_id;
00126 typedef std::map<state_id, state> state_map;
00127
00128 typedef std::pair<const mgt::header*, size_t> beacon_header;
00129
00130 struct hooks: public dissector_default_hooks
00131 {
00132 hooks(stats& parent);
00133
00134 void invalid_type_or_subtype_hook(const void*, size_t,
00135 dissector_status::status);
00136 void addr_hook(const void*, size_t, unsigned, const addr&);
00137 void seq_ctl_hook(const void*, size_t, unsigned, unsigned);
00138 void qos_ctl_hook(const void*, size_t,
00139 unsigned, bool, unsigned, unsigned);
00140 void beacon_hook(const mgt::header*, size_t);
00141
00142 typedef boost::optional<seqctl> optional_seqctl;
00143 typedef boost::optional<state_id> optional_state_id;
00144 typedef boost::optional<beacon_header> optional_beacon_header;
00145
00146 unsigned type;
00147 unsigned subtype;
00148 bool retx;
00149 optional_seqctl sc;
00150 optional_state_id id;
00151 transmitter_type txer_type;
00152 optional_beacon_header beacon;
00153
00154 private:
00155 const addr* receiver;
00156 stats* parent;
00157 };
00158
00159 private:
00160 typedef dissector<hooks> stats_dissector;
00161
00162 template <class Frame>
00163 void
00164 update_states(const Frame& f, const stats_dissector& d);
00165
00166 template <class PhyHeader, class Frame>
00167 void
00168 account_frame(const Frame& f, const stats_dissector& d);
00169
00170
00171 void account_beacon(const tool::microseconds& tstamp,
00172 const mgt::header* header,
00173 size_t caplen,
00174 bool ibss);
00175 void account_miss();
00176 void account_gap(unsigned gaplen);
00177 void account_expired();
00178 void account_out_of_order();
00179 void account_duplicate();
00180 void account_seq_anomaly();
00181 void account_addr(const addr& a);
00182
00183 state_map states_;
00184 std::set<addr> aps_;
00185
00186 delimiter_frames df_;
00187 simple_counters sc_;
00188 gap_lengths gl_;
00189 missed_estimations me_;
00190 tfi_plot tp_;
00191 bss_stats bs_;
00192 ssid_stats ss_;
00193 activity ay_;
00194 addr_growth ag_;
00195 bssid_growth bg_;
00196 bssid_growth ig_;
00197 ssid_growth sg_;
00198 ap_growth pg_;
00199 };
00200
00201 }
00202
00203 }
00204
00205 }
00206
00207 # include "stats.hxx"
00208
00209 #endif // ! WIFI_FRAME_STATS_STATS_HH_