author | mickeyl <mickeyl> | 2003-03-30 01:41:56 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-03-30 01:41:56 (UTC) |
commit | 99899abc80a8aa05044eeecd8a061b0a8efaa713 (patch) (side-by-side diff) | |
tree | 45db7a60f17d00ae72d0e8d6b986d5be10232c6c /libopie2/opienet | |
parent | 340cb7e64fb898966996b00b93c03ca05a347aa5 (diff) | |
download | opie-99899abc80a8aa05044eeecd8a061b0a8efaa713.zip opie-99899abc80a8aa05044eeecd8a061b0a8efaa713.tar.gz opie-99899abc80a8aa05044eeecd8a061b0a8efaa713.tar.bz2 |
- add classes for 802.11 tagged values
- adjust miniwellenreiter accordingly
-rw-r--r-- | libopie2/opienet/802_11_user.h | 54 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 40 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.h | 7 | ||||
-rw-r--r-- | libopie2/opienet/opcap.cpp | 253 | ||||
-rw-r--r-- | libopie2/opienet/opcap.h | 166 |
5 files changed, 444 insertions, 76 deletions
diff --git a/libopie2/opienet/802_11_user.h b/libopie2/opienet/802_11_user.h index 0b3f198..ffdcb93 100644 --- a/libopie2/opienet/802_11_user.h +++ b/libopie2/opienet/802_11_user.h @@ -234,53 +234,53 @@ struct ieee_802_11_frame_subtype_class { struct ieee_802_11_mgmt_header { u_int16_t fc; u_int16_t duration; u_int8_t da[6]; u_int8_t sa[6]; u_int8_t bssid[6]; u_int16_t seq_ctrl; }; struct ieee_802_11_data_header { u_int16_t frame_control; u_int16_t duration; u_int8_t mac1[6]; u_int8_t mac2[6]; u_int8_t mac3[6]; u_int16_t SeqCtl; u_int8_t mac4[6]; // u_int16_t gapLen; // u_int8_t gap[8]; }; -#define CAPABILITY_ESS(cap) ((cap) & 0x0001) -#define CAPABILITY_IBSS(cap) ((cap) & 0x0002) -#define CAPABILITY_CFP(cap) ((cap) & 0x0004) -#define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) -#define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) +#define CAPABILITY_ESS(cap) ((cap) & 0x0001) +#define CAPABILITY_IBSS(cap) ((cap) & 0x0002) +#define CAPABILITY_CFP(cap) ((cap) & 0x0004) +#define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) +#define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) struct ssid_t { u_int8_t element_id; u_int8_t length; u_char ssid[33]; /* 32 + 1 for null */ }; struct rates_t { u_int8_t element_id; u_int8_t length; u_int8_t rate[8]; }; struct challenge_t { u_int8_t element_id; u_int8_t length; u_int8_t text[254]; /* 1-253 + 1 for null */ }; struct fh_t { u_int8_t element_id; @@ -297,77 +297,85 @@ struct ds_t { u_int8_t length; u_int8_t channel; }; struct cf_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int16_t max_duration; u_int16_t dur_remaing; }; struct tim_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int8_t bitmap_control; u_int8_t bitmap[251]; }; -#define E_SSID 0 -#define E_RATES 1 -#define E_FH 2 -#define E_DS 3 -#define E_CF 4 -#define E_TIM 5 -#define E_IBSS 6 -#define E_CHALLENGE 16 -#define E_CISCO 133 + +struct ibss_t { + u_int8_t element_id; + u_int8_t length; + u_int16_t atim_window; +}; + + +#define E_SSID 0 +#define E_RATES 1 +#define E_FH 2 +#define E_DS 3 +#define E_CF 4 +#define E_TIM 5 +#define E_IBSS 6 +#define E_CHALLENGE 16 +#define E_CISCO 133 struct ieee_802_11_mgmt_body { - u_int8_t timestamp[8]; - u_int16_t beacon_interval; + u_int8_t timestamp[8]; + u_int16_t beacon_interval; // u_int16_t listen_interval; // u_int16_t status_code; // u_int16_t aid; // u_char ap[6]; // u_int16_t reason_code; // u_int16_t auth_alg; // u_int16_t auth_trans_seq_num; // struct challenge_t challenge; - u_int16_t capability_info; - struct ssid_t ssid; - struct rates_t rates; - struct ds_t ds; - struct cf_t cf; - struct fh_t fh; - struct tim_t tim; + u_int16_t capability_info; +// struct ssid_t ssid; +// struct rates_t rates; +// struct ds_t ds; +// struct cf_t cf; +// struct fh_t fh; +// struct tim_t tim; }; struct ieee_802_11_data_body { //FIXME }; struct ctrl_rts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; #define CTRL_RTS_LEN (2+2+6+6+4) struct ctrl_cts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index 1d3b9fe..25c70e0 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -270,236 +270,254 @@ bool ONetworkInterface::setPromiscuousMode( bool b ) else _ifr.ifr_flags &= (~IFF_PROMISC); return ioctl( SIOCSIFFLAGS ); } bool ONetworkInterface::promiscuousMode() const { ioctl( SIOCGIFFLAGS ); return _ifr.ifr_flags & IFF_PROMISC; } bool ONetworkInterface::isWireless() const { return ioctl( SIOCGIWNAME ); } /*====================================================================================== * OChannelHopper *======================================================================================*/ OChannelHopper::OChannelHopper( OWirelessNetworkInterface* iface ) :QObject( 0, "Mickey's funky hopper" ), - _iface( iface ), _interval( 0 ), _channel( 0 ), _tid( 0 ) + _iface( iface ), _interval( 0 ), _channel( 1 ), _tid( 0 ), + _maxChannel( iface->channels()+1 ) { } OChannelHopper::~OChannelHopper() { } +bool OChannelHopper::isActive() const +{ + return _tid; +} + + +int OChannelHopper::channel() const +{ + return _channel; +} + + void OChannelHopper::timerEvent( QTimerEvent* ) { - //FIXME: Get available channels from OWirelessNetworkInterface - if ( --_channel < 0 ) _channel = 13; + if ( !--_channel ) _channel = _maxChannel; _iface->setChannel( _channel ); qDebug( "OChannelHopper::timerEvent(): set channel %d on interface '%s'", _channel, (const char*) _iface->name() ); } void OChannelHopper::setInterval( int interval ) { if ( interval == _interval ) return; if ( _interval ) killTimer( _tid ); + _tid = 0; _interval = interval; if ( _interval ) { _tid = startTimer( interval ); } } int OChannelHopper::interval() const { return _interval; } /*====================================================================================== * OWirelessNetworkInterface *======================================================================================*/ OWirelessNetworkInterface::OWirelessNetworkInterface( const QString& name ) - :ONetworkInterface( name ), _hopper( this ) + :ONetworkInterface( name ), _hopper( 0 ) { qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" ); init(); } OWirelessNetworkInterface::~OWirelessNetworkInterface() { } iwreqstruct& OWirelessNetworkInterface::iwr() const { return _iwr; } void OWirelessNetworkInterface::init() { qDebug( "OWirelessNetworkInterface::init()" ); memset( &_iwr, 0, sizeof( struct iwreq ) ); // IEEE802.11(b) radio frequency channels //FIXME: get these directly from the interface //FIXME: check if these channels are off-by-one iwrangestruct range; _iwr.u.data.pointer = (char*) ⦥ _iwr.u.data.length = sizeof( iwrangestruct ); if ( !wioctl( SIOCGIWRANGE ) ) { qDebug( "OWirelessNetworkInterface::init(): SIOCGIWRANGE failed (%s)", strerror( errno ) ); return; } - //TODO: Find out what the difference between num_channel and - // num_frequency is about. - for ( int i = 0; i < range.num_frequency; ++i ) { int freq = (int) ( double( range.freq[i].m ) * pow( 10, range.freq[i].e ) / 1000000.0 ); - _channels.insert( freq, i ); + _channels.insert( freq, i+1 ); } } QString OWirelessNetworkInterface::associatedAP() const { //FIXME: use OMacAddress QString mac; if ( ioctl( SIOCGIWAP ) ) { mac.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", _ifr.ifr_hwaddr.sa_data[0]&0xff, _ifr.ifr_hwaddr.sa_data[1]&0xff, _ifr.ifr_hwaddr.sa_data[2]&0xff, _ifr.ifr_hwaddr.sa_data[3]&0xff, _ifr.ifr_hwaddr.sa_data[4]&0xff, _ifr.ifr_hwaddr.sa_data[5]&0xff ); } else { mac = "<Unknown>"; } return mac; } int OWirelessNetworkInterface::channel() const { + //FIXME: When monitoring enabled, then use it + //FIXME: to gather the current RF channel + //FIXME: Until then, get active channel from hopper. + if ( _hopper && _hopper->isActive() ) + return _hopper->channel(); + if ( !wioctl( SIOCGIWFREQ ) ) { return -1; } else { - //FIXME: This is off-by-one !? Why? return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10, _iwr.u.freq.e ) / 1000000) ]; } } void OWirelessNetworkInterface::setChannel( int c ) const { if ( !_mon ) { memset( &_iwr, 0, sizeof( iwreqstruct ) ); _iwr.u.freq.m = c; _iwr.u.freq.e = 0; wioctl( SIOCSIWFREQ ); } else { _mon->setChannel( c ); } } double OWirelessNetworkInterface::frequency() const { if ( !wioctl( SIOCGIWFREQ ) ) { return -1.0; } else { return double( _iwr.u.freq.m ) * pow( 10, _iwr.u.freq.e ) / 1000000000.0; } } int OWirelessNetworkInterface::channels() const { return _channels.count(); } void OWirelessNetworkInterface::setChannelHopping( int interval ) { - _hopper.setInterval( interval ); + if ( !_hopper ) _hopper = new OChannelHopper( this ); + _hopper->setInterval( interval ); + //FIXME: When and by whom will the channel hopper be deleted? } int OWirelessNetworkInterface::channelHopping() const { - return _hopper.interval(); + return _hopper->interval(); } void OWirelessNetworkInterface::setMonitorMode( bool b ) { if ( _mon ) _mon->setEnabled( b ); else qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" ); } + bool OWirelessNetworkInterface::monitorMode() const { return _mon ? _mon->enabled() : false; } QString OWirelessNetworkInterface::nickName() const { char str[IW_ESSID_MAX_SIZE]; _iwr.u.data.pointer = &str[0]; _iwr.u.data.length = IW_ESSID_MAX_SIZE; if ( !wioctl( SIOCGIWNICKN ) ) { return "<unknown>"; } else { str[_iwr.u.data.length] = 0x0; // some drivers (e.g. wlan-ng) don't zero-terminate the string return str; } } QString OWirelessNetworkInterface::SSID() const diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h index 9a68a74..936ac85 100644 --- a/libopie2/opienet/onetwork.h +++ b/libopie2/opienet/onetwork.h @@ -121,114 +121,117 @@ class ONetworkInterface OMacAddress macAddress() const; protected: const QString _name; const int _sfd; mutable ifreqstruct _ifr; OMonitoringInterface* _mon; protected: ifreqstruct& ifr() const; virtual void init(); bool ioctl( int call ) const; bool ioctl( int call, ifreqstruct& ) const; }; /*====================================================================================== * OChannelHopper *======================================================================================*/ class OChannelHopper : public QObject { public: OChannelHopper( OWirelessNetworkInterface* ); virtual ~OChannelHopper(); + bool isActive() const; + int channel() const; virtual void timerEvent( QTimerEvent* ); void setInterval( int ); int interval() const; private: OWirelessNetworkInterface* _iface; int _interval; int _channel; int _tid; + int _maxChannel; }; /*====================================================================================== * OWirelessNetworkInterface *======================================================================================*/ class OWirelessNetworkInterface : public ONetworkInterface { friend class OMonitoringInterface; friend class OCiscoMonitoringInterface; friend class OWlanNGMonitoringInterface; friend class OHostAPMonitoringInterface; friend class OOrinocoMonitoringInterface; public: enum Mode { AdHoc, Managed, Monitor }; OWirelessNetworkInterface( const QString& name ); virtual ~OWirelessNetworkInterface(); virtual void setChannel( int ) const; virtual int channel() const; virtual double frequency() const; virtual int channels() const; //virtual double frequency(int) const; virtual void setMode( Mode ) {}; virtual bool mode() const {}; virtual void setMonitorMode( bool ); virtual bool monitorMode() const; - virtual void setChannelHopping( int interval ); + virtual void setChannelHopping( int interval = 0 ); virtual int channelHopping() const; virtual void setNickName( const QString& ) {}; virtual QString nickName() const; virtual bool isAssociated() const {}; virtual QString associatedAP() const; virtual void setSSID( const QString& ); virtual QString SSID() const; protected: mutable iwreqstruct _iwr; QMap<int,int> _channels; protected: virtual void init(); iwreqstruct& iwr() const; bool wioctl( int call ) const; bool wioctl( int call, iwreqstruct& ) const; private: - OChannelHopper _hopper; + OChannelHopper* _hopper; }; /*====================================================================================== * OMonitoringInterface *======================================================================================*/ class OMonitoringInterface { public: OMonitoringInterface(); OMonitoringInterface( ONetworkInterface* ); virtual ~OMonitoringInterface(); public: virtual void setEnabled( bool ); virtual bool enabled() const; virtual void setChannel( int ); virtual QString name() const = 0; protected: bool _enabled; diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index 48f874f..913d42e 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -28,57 +28,60 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* OPIE */ #include <opie2/opcap.h> /* QT */ #include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects) #include <qsocketnotifier.h> /*====================================================================================== * OPacket *======================================================================================*/ OPacket::OPacket( packetheaderstruct header, const unsigned char* data, QObject* parent ) :QObject( parent, "Generic" ), _hdr( header ), _data( data ) { qDebug( "OPacket::OPacket(): (Len %d, CapLen %d)" /*, ctime((const time_t*) header.ts.tv_sec)*/, header.len, header.caplen ); + _end = (unsigned char*) data + header.len; + qDebug( "OPacket::data @ %0x, end @ %0x", data, _end ); + if ( packetCapturer()->dataLink() == DLT_EN10MB ) { qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" ); - new OEthernetPacket( (const struct ether_header*) data, this ); + new OEthernetPacket( _end, (const struct ether_header*) data, this ); } else { qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" ); - new OWaveLanPacket( (const struct ieee_802_11_header*) data, this ); + new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this ); } } OPacket::~OPacket() { } OPacketCapturer* OPacket::packetCapturer() const { return parent()->inherits( "OPacketCapturer" ) ? static_cast<OPacketCapturer*>( parent() ) : 0; } timevalstruct OPacket::timeval() const { return _hdr.ts; } int OPacket::caplen() const { return _hdr.caplen; @@ -88,115 +91,115 @@ int OPacket::caplen() const void OPacket::dump() const { printf( "OPacket::dump()\n" ); printf( "----------------\n" ); for ( int i = 0; i < _hdr.caplen; ++i ) { printf( "%02x ", _data[i] ); if ( !((i+1) % 32) ) printf( "\n" ); } printf( "\n\n" ); } int OPacket::len() const { return _hdr.len; } /*====================================================================================== * OEthernetPacket *======================================================================================*/ -OEthernetPacket::OEthernetPacket( const struct ether_header* data, QObject* parent ) +OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent ) :QObject( parent, "Ethernet" ), _ether( data ) { qDebug( "Source = %s", (const char*) sourceAddress().toString() ); qDebug( "Destination = %s", (const char*) destinationAddress().toString() ); if ( sourceAddress() == OMacAddress::broadcast ) qDebug( "Source is broadcast address" ); if ( destinationAddress() == OMacAddress::broadcast ) qDebug( "Destination is broadcast address" ); switch ( type() ) { - case ETHERTYPE_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break; + case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; case ETHERTYPE_ARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = ARP" ); break; } case ETHERTYPE_REVARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" ); break; } default: qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" ); } } OEthernetPacket::~OEthernetPacket() { } OMacAddress OEthernetPacket::sourceAddress() const { return OMacAddress( _ether->ether_shost ); } OMacAddress OEthernetPacket::destinationAddress() const { return OMacAddress( _ether->ether_dhost ); } int OEthernetPacket::type() const { return ntohs( _ether->ether_type ); } /*====================================================================================== * OIPPacket *======================================================================================*/ -OIPPacket::OIPPacket( const struct iphdr* data, QObject* parent ) +OIPPacket::OIPPacket( const unsigned char* end, const struct iphdr* data, QObject* parent ) :QObject( parent, "IP" ), _iphdr( data ) { qDebug( "OIPPacket::OIPPacket(): decoding IP header..." ); //qDebug( "FromAddress: %s", (const char*) inet_ntoa( *src ) ); //qDebug( " ToAddress: %s", (const char*) inet_ntoa( *dst ) ); qDebug( "FromAddress: %s", (const char*) fromIPAddress().toString() ); qDebug( " toAddress: %s", (const char*) toIPAddress().toString() ); switch ( protocol() ) { - case IPPROTO_UDP: new OUDPPacket( (const struct udphdr*) (data+1), this ); break; - case IPPROTO_TCP: new OTCPPacket( (const struct tcphdr*) (data+1), this ); break; + case IPPROTO_UDP: new OUDPPacket( end, (const struct udphdr*) (data+1), this ); break; + case IPPROTO_TCP: new OTCPPacket( end, (const struct tcphdr*) (data+1), this ); break; default: qDebug( "OIPPacket::OIPPacket(): unknown IP protocol type = %d", protocol() ); } } OIPPacket::~OIPPacket() { } QHostAddress OIPPacket::fromIPAddress() const { return EXTRACT_32BITS( &_iphdr->saddr ); } QHostAddress OIPPacket::toIPAddress() const { return EXTRACT_32BITS( &_iphdr->saddr ); } int OIPPacket::tos() const { @@ -223,102 +226,102 @@ int OIPPacket::offset() const int OIPPacket::ttl() const { return _iphdr->ttl; } int OIPPacket::protocol() const { return _iphdr->protocol; } int OIPPacket::checksum() const { return EXTRACT_16BITS( &_iphdr->check ); } /*====================================================================================== * OUDPPacket *======================================================================================*/ -OUDPPacket::OUDPPacket( const struct udphdr* data, QObject* parent ) +OUDPPacket::OUDPPacket( const unsigned char* end, const struct udphdr* data, QObject* parent ) :QObject( parent, "UDP" ), _udphdr( data ) { qDebug( "OUDPPacket::OUDPPacket(): decoding UDP header..." ); } OUDPPacket::~OUDPPacket() { } /*====================================================================================== * OTCPPacket *======================================================================================*/ -OTCPPacket::OTCPPacket( const struct tcphdr* data, QObject* parent ) +OTCPPacket::OTCPPacket( const unsigned char* end, const struct tcphdr* data, QObject* parent ) :QObject( parent, "TCP" ), _tcphdr( data ) { qDebug( "OTCPPacket::OTCPPacket(): decoding TCP header..." ); } OTCPPacket::~OTCPPacket() { } /*====================================================================================== * OWaveLanPacket *======================================================================================*/ -OWaveLanPacket::OWaveLanPacket( const struct ieee_802_11_header* data, QObject* parent ) +OWaveLanPacket::OWaveLanPacket( const unsigned char* end, const struct ieee_802_11_header* data, QObject* parent ) :QObject( parent, "802.11" ), _wlanhdr( data ) { qDebug( "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." ); qDebug( "type: %0X", type() ); qDebug( "subType: %0X", subType() ); qDebug( "duration: %d", duration() ); qDebug( "powermanagement: %d", usesPowerManagement() ); qDebug( "wep: %d", usesWep() ); qDebug( "MAC1: %s", (const char*) macAddress1().toString() ); qDebug( "MAC2: %s", (const char*) macAddress2().toString() ); qDebug( "MAC3: %s", (const char*) macAddress3().toString() ); qDebug( "MAC4: %s", (const char*) macAddress4().toString() ); switch ( type() ) { - case T_MGMT: new OWaveLanManagementPacket( (const struct ieee_802_11_mgmt_header*) data, this ); break; - case T_DATA: new OWaveLanDataPacket( (const struct ieee_802_11_data_header*) data, this ); break; - //case T_CTRL: new OWaveLanControlPacket( (const struct ieee_802_11_ctrl_header*) data, this ); break; + case T_MGMT: new OWaveLanManagementPacket( end, (const struct ieee_802_11_mgmt_header*) data, this ); break; + case T_DATA: new OWaveLanDataPacket( end, (const struct ieee_802_11_data_header*) data, this ); break; + //case T_CTRL: new OWaveLanControlPacket( end, (const struct ieee_802_11_ctrl_header*) data, this ); break; default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown type!" ); } } OWaveLanPacket::~OWaveLanPacket() { } int OWaveLanPacket::duration() const { return _wlanhdr->duration; } OMacAddress OWaveLanPacket::macAddress1() const { return OMacAddress( _wlanhdr->mac1 ); } OMacAddress OWaveLanPacket::macAddress2() const { return OMacAddress( _wlanhdr->mac2 ); @@ -362,247 +365,441 @@ bool OWaveLanPacket::fromDS() const bool OWaveLanPacket::toDS() const { return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesPowerManagement() const { return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesWep() const { return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } /*====================================================================================== * OWaveLanManagementPacket *======================================================================================*/ -OWaveLanManagementPacket::OWaveLanManagementPacket( const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) +OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Management" ), _header( data ), _body( (const struct ieee_802_11_mgmt_body*) (data+1) ) { qDebug( "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." ); switch ( ((OWaveLanPacket*) this->parent() )->subType() ) { case ST_BEACON: { - qDebug( "TYPE: BEACON FRAME" ); - qDebug( "ESSID: %s", (const char*) SSID() ); - break; + // nice, received a beacon... + } + } + + // grab tagged values + const unsigned char* ptr = (const unsigned char*) (_body+1); + while (ptr < end) + { + switch ( *ptr ) + { + case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break; + case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break; + case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break; + case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break; + case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break; + case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break; + case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break; + case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break; } + ptr+= ( ( struct ssid_t* ) ptr )->length; // skip length of tagged value + ptr+= 2; // skip tag ID and length } } OWaveLanManagementPacket::~OWaveLanManagementPacket() { } -QString OWaveLanManagementPacket::SSID() const +int OWaveLanManagementPacket::beaconInterval() const +{ + return EXTRACT_LE_16BITS( &_body->beacon_interval ); +} + + +int OWaveLanManagementPacket::capabilities() const +{ + return EXTRACT_LE_16BITS( &_body->capability_info ); +} + + +bool OWaveLanManagementPacket::canESS() const { - int length = _body->ssid.length; + return CAPABILITY_ESS( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canIBSS() const +{ + return CAPABILITY_IBSS( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canCFP() const +{ + return CAPABILITY_CFP( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canCFP_REQ() const +{ + return CAPABILITY_CFP_REQ( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canPrivacy() const +{ + return CAPABILITY_PRIVACY( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +/*====================================================================================== + * OWaveLanManagementSSID + *======================================================================================*/ + +OWaveLanManagementSSID::OWaveLanManagementSSID( const unsigned char* end, const struct ssid_t* data, QObject* parent ) + :QObject( parent, "802.11 SSID" ), _data( data ) +{ + qDebug( "OWaveLanManagementSSID()" ); +} + + +OWaveLanManagementSSID::~OWaveLanManagementSSID() +{ +} + + +QString OWaveLanManagementSSID::ID() const +{ + int length = _data->length; if ( length > 32 ) length = 32; char essid[length+1]; - memcpy( &essid, _body->ssid.ssid, length ); + memcpy( &essid, &_data->ssid, length ); essid[length] = 0x0; return essid; } /*====================================================================================== + * OWaveLanManagementRates + *======================================================================================*/ + +OWaveLanManagementRates::OWaveLanManagementRates( const unsigned char* end, const struct rates_t* data, QObject* parent ) + :QObject( parent, "802.11 Rates" ), _data( data ) +{ + qDebug( "OWaveLanManagementRates()" ); +} + + +OWaveLanManagementRates::~OWaveLanManagementRates() +{ +} + +/*====================================================================================== + * OWaveLanManagementCF + *======================================================================================*/ + +OWaveLanManagementCF::OWaveLanManagementCF( const unsigned char* end, const struct cf_t* data, QObject* parent ) + :QObject( parent, "802.11 CF" ), _data( data ) +{ + qDebug( "OWaveLanManagementCF()" ); +} + + +OWaveLanManagementCF::~OWaveLanManagementCF() +{ +} + +/*====================================================================================== + * OWaveLanManagementFH + *======================================================================================*/ + +OWaveLanManagementFH::OWaveLanManagementFH( const unsigned char* end, const struct fh_t* data, QObject* parent ) + :QObject( parent, "802.11 FH" ), _data( data ) +{ + qDebug( "OWaveLanManagementFH()" ); +} + + +OWaveLanManagementFH::~OWaveLanManagementFH() +{ +} + +/*====================================================================================== + * OWaveLanManagementDS + *======================================================================================*/ + +OWaveLanManagementDS::OWaveLanManagementDS( const unsigned char* end, const struct ds_t* data, QObject* parent ) + :QObject( parent, "802.11 DS" ), _data( data ) +{ + qDebug( "OWaveLanManagementDS()" ); +} + + +OWaveLanManagementDS::~OWaveLanManagementDS() +{ +} + + +int OWaveLanManagementDS::channel() const +{ + return _data->channel; +} + +/*====================================================================================== + * OWaveLanManagementTim + *======================================================================================*/ + +OWaveLanManagementTim::OWaveLanManagementTim( const unsigned char* end, const struct tim_t* data, QObject* parent ) + :QObject( parent, "802.11 Tim" ), _data( data ) +{ + qDebug( "OWaveLanManagementTim()" ); +} + + +OWaveLanManagementTim::~OWaveLanManagementTim() +{ +} + +/*====================================================================================== + * OWaveLanManagementIBSS + *======================================================================================*/ + +OWaveLanManagementIBSS::OWaveLanManagementIBSS( const unsigned char* end, const struct ibss_t* data, QObject* parent ) + :QObject( parent, "802.11 IBSS" ), _data( data ) +{ + qDebug( "OWaveLanManagementIBSS()" ); +} + + +OWaveLanManagementIBSS::~OWaveLanManagementIBSS() +{ +} + +/*====================================================================================== + * OWaveLanManagementChallenge + *======================================================================================*/ + +OWaveLanManagementChallenge::OWaveLanManagementChallenge( const unsigned char* end, const struct challenge_t* data, QObject* parent ) + :QObject( parent, "802.11 Challenge" ), _data( data ) +{ + qDebug( "OWaveLanManagementChallenge()" ); +} + + +OWaveLanManagementChallenge::~OWaveLanManagementChallenge() +{ +} + +/*====================================================================================== * OWaveLanDataPacket *======================================================================================*/ -OWaveLanDataPacket::OWaveLanDataPacket( const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) +OWaveLanDataPacket::OWaveLanDataPacket( const unsigned char* end, const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Data" ), _header( data ) { //qDebug( "size of header = %d", sizeof( struct ieee_802_11_data_header ) ); //qDebug( "header: %0x", data ); const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header ); //qDebug( "payload: %0x", payload ); if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6; // compensation for missing last address - new OLLCPacket( (const struct ieee_802_11_802_2_header*) payload, this ); + new OLLCPacket( end, (const struct ieee_802_11_802_2_header*) payload, this ); } OWaveLanDataPacket::~OWaveLanDataPacket() { } /*====================================================================================== * OLLCPacket *======================================================================================*/ -OLLCPacket::OLLCPacket( const struct ieee_802_11_802_2_header* data, QObject* parent ) +OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent ) :QObject( parent, "802.11 802_2" ), _header( data ) { qDebug( "OLLCPacket::OLLCPacket(): decoding frame..." ); if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) ) { qDebug( "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type=%04X)", EXTRACT_16BITS( &_header->type ) ); switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h { - case ETH_P_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break; + case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; default: qDebug( "OLLCPacket::OLLCPacket(): Unknown Encapsulation Type" ); } } } OLLCPacket::~OLLCPacket() { } /*====================================================================================== * OPacketCapturer *======================================================================================*/ OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) :QObject( parent, name ), _name( QString::null ), _open( false ), - _pch( 0 ) + _pch( 0 ), _sn( 0 ) { } OPacketCapturer::~OPacketCapturer() { if ( _open ) { qDebug( "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." ); close(); } } void OPacketCapturer::setBlocking( bool b ) { if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 ) { qDebug( "OPacketCapturer::setBlocking(): blocking mode changed successfully." ); } else { qDebug( "OPacketCapturer::setBlocking(): can't change blocking mode: %s", _errbuf ); } } bool OPacketCapturer::blocking() const { int b = pcap_getnonblock( _pch, _errbuf ); if ( b == -1 ) { qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf ); return -1; } return !b; } void OPacketCapturer::close() { if ( _open ) { + if ( _sn ) + { + _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); + delete _sn; + } pcap_close( _pch ); _open = false; } } int OPacketCapturer::dataLink() const { return pcap_datalink( _pch ); } int OPacketCapturer::fileno() const { if ( _open ) { return pcap_fileno( _pch ); } else { return -1; } } OPacket* OPacketCapturer::next() { packetheaderstruct header; + qDebug( "==> OPacketCapturer::next()" ); const unsigned char* pdata = pcap_next( _pch, &header ); + qDebug( "<== OPacketCapturer::next()" ); + if ( header.len ) return new OPacket( header, pdata, this ); else return 0; } bool OPacketCapturer::open( const QString& name ) { if ( _open ) { if ( name == _name ) // ignore opening an already openend device { return true; } else // close the last opened device { close(); } } _name = name; pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] ); if ( handle ) { qDebug( "OPacketCapturer::open(): libpcap opened successfully." ); _pch = handle; _open = true; - // in case we have a qapp, create a socket notifier + // in case we have an application object, create a socket notifier if ( qApp ) { - QSocketNotifier* sn = new QSocketNotifier( fileno(), QSocketNotifier::Read, this ); - connect( sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); + _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); + connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); } return true; } else { qDebug( "OPacketCapturer::open(): can't open libpcap: %s", _errbuf ); return false; } } bool OPacketCapturer::isOpen() const { return _open; } void OPacketCapturer::readyToReceive() { qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(...)'" ); emit receivedPacket( next() ); } diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h index 65c550c..0b06572 100644 --- a/libopie2/opienet/opcap.h +++ b/libopie2/opienet/opcap.h @@ -39,256 +39,398 @@ extern "C" // work around a bpf/pcap conflict in recent headers { #include <pcap.h> } #include <netinet/ether.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <time.h> /* QT */ #include <qhostaddress.h> #include <qobject.h> #include <qstring.h> /* OPIE */ #include <opie2/onetutils.h> #include "802_11_user.h" /* TYPEDEFS */ typedef struct timeval timevalstruct; typedef struct pcap_pkthdr packetheaderstruct; /* FORWARDS */ class OPacketCapturer; +class QSocketNotifier; /*====================================================================================== * OPacket - A frame on the wire *======================================================================================*/ class OPacket : public QObject { Q_OBJECT public: OPacket( packetheaderstruct, const unsigned char*, QObject* parent ); virtual ~OPacket(); timevalstruct timeval() const; OPacketCapturer* packetCapturer() const; int caplen() const; int len() const; void dump() const; private: const packetheaderstruct _hdr; // pcap packet header const unsigned char* _data; // pcap packet data + const unsigned char* _end; // end of pcap packet data }; /*====================================================================================== * OEthernetPacket - DLT_EN10MB frame *======================================================================================*/ class OEthernetPacket : public QObject { Q_OBJECT public: - OEthernetPacket( const struct ether_header*, QObject* parent = 0 ); + OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 ); virtual ~OEthernetPacket(); OMacAddress sourceAddress() const; OMacAddress destinationAddress() const; int type() const; private: const struct ether_header* _ether; }; /*====================================================================================== * OWaveLanPacket - DLT_IEEE802_11 frame *======================================================================================*/ class OWaveLanPacket : public QObject { Q_OBJECT public: - OWaveLanPacket( const struct ieee_802_11_header*, QObject* parent = 0 ); + OWaveLanPacket( const unsigned char*, const struct ieee_802_11_header*, QObject* parent = 0 ); virtual ~OWaveLanPacket(); int duration() const; bool fromDS() const; bool toDS() const; virtual OMacAddress macAddress1() const; virtual OMacAddress macAddress2() const; virtual OMacAddress macAddress3() const; virtual OMacAddress macAddress4() const; bool usesPowerManagement() const; int type() const; int subType() const; int version() const; bool usesWep() const; private: const struct ieee_802_11_header* _wlanhdr; }; /*====================================================================================== * OWaveLanManagementPacket - type: management (T_MGMT) *======================================================================================*/ class OWaveLanManagementPacket : public QObject { Q_OBJECT public: - OWaveLanManagementPacket( const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 ); + OWaveLanManagementPacket( const unsigned char*, const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanManagementPacket(); - QString SSID() const; + int beaconInterval() const; + int capabilities() const; // generic + + bool canESS() const; + bool canIBSS() const; + bool canCFP() const; + bool canCFP_REQ() const; + bool canPrivacy() const; private: const struct ieee_802_11_mgmt_header* _header; const struct ieee_802_11_mgmt_body* _body; }; /*====================================================================================== + * OWaveLanManagementSSID + *======================================================================================*/ + +class OWaveLanManagementSSID : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementSSID( const unsigned char*, const struct ssid_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementSSID(); + + QString ID() const; + + private: + const struct ssid_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementRates + *======================================================================================*/ + +class OWaveLanManagementRates : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementRates( const unsigned char*, const struct rates_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementRates(); + + private: + const struct rates_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementCF + *======================================================================================*/ + +class OWaveLanManagementCF : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementCF( const unsigned char*, const struct cf_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementCF(); + + private: + const struct cf_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementFH + *======================================================================================*/ + +class OWaveLanManagementFH : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementFH( const unsigned char*, const struct fh_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementFH(); + + private: + const struct fh_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementDS + *======================================================================================*/ + +class OWaveLanManagementDS : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementDS( const unsigned char*, const struct ds_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementDS(); + + int channel() const; + + private: + const struct ds_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementTim + *======================================================================================*/ + +class OWaveLanManagementTim : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementTim( const unsigned char*, const struct tim_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementTim(); + + private: + const struct tim_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementIBSS + *======================================================================================*/ + +class OWaveLanManagementIBSS : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementIBSS( const unsigned char*, const struct ibss_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementIBSS(); + + private: + const struct ibss_t* _data; +}; + +/*====================================================================================== + * OWaveLanManagementChallenge + *======================================================================================*/ + +class OWaveLanManagementChallenge : public QObject +{ + Q_OBJECT + + public: + OWaveLanManagementChallenge( const unsigned char*, const struct challenge_t*, QObject* parent = 0 ); + virtual ~OWaveLanManagementChallenge(); + + private: + const struct challenge_t* _data; +}; + +/*====================================================================================== * OWaveLanDataPacket - type: data (T_DATA) *======================================================================================*/ class OWaveLanDataPacket : public QObject { Q_OBJECT public: - OWaveLanDataPacket( const struct ieee_802_11_data_header*, OWaveLanPacket* parent = 0 ); + OWaveLanDataPacket( const unsigned char*, const struct ieee_802_11_data_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanDataPacket(); private: const struct ieee_802_11_data_header* _header; }; /*====================================================================================== * OLLCPacket - IEEE 802.2 Link Level Control *======================================================================================*/ class OLLCPacket : public QObject { Q_OBJECT public: - OLLCPacket( const struct ieee_802_11_802_2_header* data, QObject* parent = 0 ); + OLLCPacket( const unsigned char*, const struct ieee_802_11_802_2_header* data, QObject* parent = 0 ); virtual ~OLLCPacket(); private: const struct ieee_802_11_802_2_header* _header; }; /*====================================================================================== * OIPPacket *======================================================================================*/ class OIPPacket : public QObject { Q_OBJECT public: - OIPPacket( const struct iphdr*, QObject* parent = 0 ); + OIPPacket( const unsigned char*, const struct iphdr*, QObject* parent = 0 ); virtual ~OIPPacket(); QHostAddress fromIPAddress() const; QHostAddress toIPAddress() const; int tos() const; int len() const; int id() const; int offset() const; int ttl() const; int protocol() const; int checksum() const; private: const struct iphdr* _iphdr; }; /*====================================================================================== * OUDPPacket *======================================================================================*/ class OUDPPacket : public QObject { Q_OBJECT public: - OUDPPacket( const struct udphdr*, QObject* parent = 0 ); + OUDPPacket( const unsigned char*, const struct udphdr*, QObject* parent = 0 ); virtual ~OUDPPacket(); int fromPort() const; int toPort() const; private: const struct udphdr* _udphdr; }; /*====================================================================================== * OTCPPacket *======================================================================================*/ class OTCPPacket : public QObject { Q_OBJECT public: - OTCPPacket( const struct tcphdr*, QObject* parent = 0 ); + OTCPPacket( const unsigned char*, const struct tcphdr*, QObject* parent = 0 ); virtual ~OTCPPacket(); int fromPort() const; int toPort() const; private: const struct tcphdr* _tcphdr; }; /*====================================================================================== * OPacketCapturer *======================================================================================*/ class OPacketCapturer : public QObject { Q_OBJECT public: OPacketCapturer( QObject* parent = 0, const char* name = 0 ); ~OPacketCapturer(); void setBlocking( bool ); bool blocking() const; void close(); int dataLink() const; int fileno() const; OPacket* next(); bool open( const QString& name ); bool isOpen() const; signals: void receivedPacket( OPacket* ); protected slots: void readyToReceive(); protected: - QString _name; // devicename - bool _open; // check this before doing pcap calls - pcap_t* _pch; // pcap library handle + QString _name; // devicename + bool _open; // check this before doing pcap calls + pcap_t* _pch; // pcap library handle + QSocketNotifier* _sn; // socket notifier for main loop mutable char _errbuf[PCAP_ERRBUF_SIZE]; }; #endif // OPCAP_H |