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_FRAME_HXX_
00023 # define WIFI_FRAME_FRAME_HXX_
00024
00025 extern "C"
00026 {
00027 # include <netinet/in.h>
00028 }
00029
00030 # include "frame.hh"
00031
00032 # include <wipal/tool/endianness.hh>
00033 # include <wipal/wifi/frame/ctl.hh>
00034 # include <wipal/wifi/frame/mgt.hh>
00035 # include <wipal/wifi/frame/data.hh>
00036 # include <wipal/wifi/frame/dissector/dissector.hh>
00037 # include <wipal/wifi/frame/dissector/default_hooks.hh>
00038
00039 namespace wifi
00040 {
00041
00042 namespace frame
00043 {
00044
00045 inline
00046 unsigned
00047 protocol_version_of(const void* frame)
00048 {
00049 return (ntohs(tool::extract_unswapped_short(frame)) >> 8) & 0x2;
00050 }
00051
00052 inline
00053 type::frame_type
00054 type_of(const void* frame)
00055 {
00056 using tool::extract_unswapped_short;
00057 using type::frame_type;
00058
00059 return frame_type ((ntohs(extract_unswapped_short(frame)) >> 10) & 0x3);
00060 }
00061
00062 inline
00063 unsigned
00064 subtype_of(const void* frame)
00065 {
00066 return ntohs(tool::extract_unswapped_short(frame)) >> 12;
00067 }
00068
00069 inline
00070 uint8_t
00071 control_flags_of(const void* frame)
00072 {
00073 return ntohs(tool::extract_unswapped_short(frame));
00074 }
00075
00076 inline
00077 bool
00078 control_flag(const unsigned i, const void* frame)
00079 {
00080 const unsigned v = 1 << i;
00081
00082 return (control_flags_of(frame) & v) == v;
00083 }
00084
00085 inline
00086 bool
00087 to_ds(const void* frame)
00088 {
00089 return control_flag(0, frame);
00090 }
00091
00092 inline
00093 bool
00094 from_ds(const void* frame)
00095 {
00096 return control_flag(1, frame);
00097 }
00098
00099 inline
00100 unsigned
00101 duration_of(const void* frame)
00102 {
00103 const unsigned d =
00104 tool::extract_swapped_short(static_cast<const uint16_t*> (frame) + 1);
00105 return ntohs(d);
00106 }
00107
00108 inline
00109 const addr*
00110 transmitter_address(const void* frame)
00111 {
00112 switch (type_of(frame))
00113 {
00114 case type::management:
00115 return & static_cast<const mgt::header*> (frame)->
00116 addrs[mgt::header::sa];
00117
00118 case type::control:
00119 {
00120 using namespace ctl;
00121
00122 switch (subtype_of(frame))
00123 {
00124 case subtype::ps_poll:
00125 return & static_cast<const ps_poll::header*> (frame)->
00126 addrs[ps_poll::header::ta];
00127
00128 case subtype::rts:
00129 return & static_cast<const rts::header*> (frame)->
00130 addrs[rts::header::ta];
00131
00132 default:
00133 return 0;
00134 }
00135 }
00136
00137 case type::data:
00138 {
00139 typedef data::header_3addr header;
00140
00141 return & static_cast<const header*> (frame)->addrs[1];
00142 }
00143
00144 default:
00145 return 0;
00146 }
00147 }
00148
00150 struct bssid_address_hooks: public dissector_default_hooks
00151 {
00153 bssid_address_hooks() { res_ = 0; }
00154
00156 const addr* result() const { return res_; }
00157
00158 # ifndef DOXYGEN
00159 # define bssid_address_hooks_setup_hook(Type, Name) \
00160 void Name ## _hook(const Type::Name::header* h, size_t) \
00161 { \
00162 res_ = & h->addrs[Type::Name::header::bssid]; \
00163 }
00164
00165 protected:
00166 bssid_address_hooks_setup_hook(ctl, ps_poll)
00167 bssid_address_hooks_setup_hook(ctl, cf_end)
00168 bssid_address_hooks_setup_hook(ctl, cf_end_cf_ack)
00169 bssid_address_hooks_setup_hook(data, within_ibss)
00170 bssid_address_hooks_setup_hook(data, from_ds)
00171 bssid_address_hooks_setup_hook(data, to_ds)
00172
00173 # undef bssid_address_hooks_setup_hook
00174
00175 protected:
00176 void ap_to_ap_hook(const data::ap_to_ap::header* h, size_t)
00177 {
00178
00179 res_ = & h->addrs[data::ap_to_ap::header::ta];
00180 }
00181
00182 void management_addr3_hook(const mgt::header* h, size_t)
00183 {
00184 res_ = & h->addrs[mgt::header::bssid];
00185 }
00186
00187 # endif // ! DOXYGEN
00188
00189 private:
00190 const addr* res_;
00191 };
00192
00193 inline
00194 const addr*
00195 bssid_address(const void* frame, size_t caplen)
00196 {
00197 return dissector<bssid_address_hooks> (frame, caplen).result();
00198 }
00199
00200 }
00201
00202 }
00203
00204 #endif // ! WIFI_FRAME_FRAME_HXX