author | mickeyl <mickeyl> | 2003-05-04 20:38:24 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-05-04 20:38:24 (UTC) |
commit | 09dceae91b14a4b2d936ebfc6c7c276686c2b98c (patch) (side-by-side diff) | |
tree | b8ebc6f92ca0008a90ef036c3c5ba873a2f59670 /libopie2 | |
parent | 8409a251d52b59585889e1bcaa278a6b847db2fc (diff) | |
download | opie-09dceae91b14a4b2d936ebfc6c7c276686c2b98c.zip opie-09dceae91b14a4b2d936ebfc6c7c276686c2b98c.tar.gz opie-09dceae91b14a4b2d936ebfc6c7c276686c2b98c.tar.bz2 |
add parsing of ARP packets
-rw-r--r-- | libopie2/opienet/802_11_user.h | 47 | ||||
-rw-r--r-- | libopie2/opienet/opcap.cpp | 65 | ||||
-rw-r--r-- | libopie2/opienet/opcap.h | 24 |
3 files changed, 110 insertions, 26 deletions
diff --git a/libopie2/opienet/802_11_user.h b/libopie2/opienet/802_11_user.h index cd98503..ad84514 100644 --- a/libopie2/opienet/802_11_user.h +++ b/libopie2/opienet/802_11_user.h @@ -1,216 +1,217 @@ #ifndef IEEE_802_11 #define IEEE_802_11 enum ieee_802_11_link_status_failure_reason { reserved0, Unspecified=1, Previous_not_valid, Sender_Quits_ESS_or_IBSS, Due_Inactivity, AP_Overload, Class_2_from_NonAuth, Class_3_from_NonAuth, Sender_Quits_BSS, Association_requester_not_authenticated, Reserved10 }; #define IEEE_802_11_LINK_STATUS_FAILURE_REASON_STRINGS \ { \ {reserved0, 0xff," Reserved reason "},\ {Unspecified, 0xff," Unspecified Reason "},\ {Previous_not_valid, 0xff," Previous Authentication no longer valid "},\ {Sender_Quits_ESS_or_IBSS,0xff," Deauthenticated because sending station is leaving (has left) IBSS or ESS "},\ {Due_Inactivity, 0xff," Disassociated due to inactivity "},\ {AP_Overload, 0xff," Disassociated because AP is unable to handle all currently associated stations "},\ {Class_2_from_NonAuth, 0xff," Class 2 frame received from non-Authenticated station"},\ {Class_3_from_NonAuth, 0xff," Class 3 frame received from nonAssociated station"},\ {Sender_Quits_BSS, 0xff," Disassociated because sending station is leaving (has left) BSS"},\ {Association_requester_not_authenticated,0xff," Station requesting (Re)Association is not Authenticated with responding station"},\ {Reserved10, 0xff," Reserved"},\ {0,0,NULL}\ }; struct ieee_802_11_header { u_int16_t frame_control;// needs to be subtyped 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]; }; struct ieee_802_3_header { u_int16_t status; u_int16_t payload_length; u_int8_t dst_mac[6]; u_int8_t src_mac[6]; }; #define P80211_OUI_LEN 3 -struct ieee_802_11_snap_header { - - u_int8_t dsap; /* always 0xAA */ - u_int8_t ssap; /* always 0xAA */ - u_int8_t ctrl; /* always 0x03 */ - u_int8_t oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __attribute__ ((packed)); - -#define P80211_LLC_OUI_LEN 3 - -struct ieee_802_11_802_1H_header { - - u_int8_t dsap; - u_int8_t ssap; /* always 0xAA */ - u_int8_t ctrl; /* always 0x03 */ - u_int8_t oui[P80211_OUI_LEN]; /* organizational universal id */ - u_int16_t unknown1; /* packet type ID fields */ - u_int16_t unknown2; /* here is something like length in some cases */ -} __attribute__ ((packed)); - struct ieee_802_11_802_2_header { u_int8_t dsap; u_int8_t ssap; /* always 0xAA */ u_int8_t ctrl; /* always 0x03 */ u_int8_t oui[P80211_OUI_LEN]; /* organizational universal id */ u_int16_t type; /* packet type ID field */ +}; -} __attribute__ ((packed)); - +/* See RFC 826 for protocol description. ARP packets are variable + in size; the arphdr structure defines the fixed-length portion. + Protocol type values are the same as those for 10 Mb/s Ethernet. + It is followed by the variable-sized fields ar_sha, arp_spa, + arp_tha and arp_tpa in that order, according to the lengths + specified. Field names used correspond to RFC 826. */ + +#define ETH_ALEN 6 + +struct myarphdr +{ + unsigned short int ar_hrd; /* Format of hardware address. */ + unsigned short int ar_pro; /* Format of protocol address. */ + unsigned char ar_hln; /* Length of hardware address. */ + unsigned char ar_pln; /* Length of protocol address. */ + unsigned short int ar_op; /* ARP opcode (command). */ + /* Ethernet looks like this : This bit is variable sized + however... */ + unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */ + unsigned char ar_sip[4]; /* Sender IP address. */ + unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */ + unsigned char ar_tip[4]; /* Target IP address. */ +}; // following is incoplete and may be incorrect and need reorganization #define ieee_802_11_frame_type_Management 0x00 #define ieee_802_11_frame_type_Control 0x01 #define ieee_802_11_frame_type_Data 0x10 #define ieee_802_11_frame_type_Reserved 0x11 #define ieee_802_11_frame_subtype_Association_Req 0x0 // Association Request #define ieee_802_11_frame_subtype_Association_Resp 0x1 // Association Response #define ieee_802_11_frame_subtype_Reassociation_Req 0x2 // Reassociation Request #define ieee_802_11_frame_subtype_Reassociation_Resp 0x3 // Reassociation Response #define ieee_802_11_frame_subtype_Probe_Req 0x4 // Probe Request #define ieee_802_11_frame_subtype_Probe_Resp 0x5 // Probe Response #define ieee_802_11_frame_subtype_Beacon 0x8 // Beacon #define ieee_802_11_frame_subtype_ATIM 0x9 // ATIM #define ieee_802_11_frame_subtype_Disassociation 0xA // Disassociation #define ieee_802_11_frame_subtype_Authentication 0xB // Authentication #define ieee_802_11_frame_subtype_Deauthentication 0xC // Deauthentication #define ieee_802_11_frame_subtype_PS_Poll 0xA // PS-Poll #define ieee_802_11_frame_subtype_RTS 0xB // RTS #define ieee_802_11_frame_subtype_CTS 0xC // CTS #define ieee_802_11_frame_subtype_ACK 0xD // ACK #define ieee_802_11_frame_subtype_CFEnd 0xE // CF-End #define ieee_802_11_frame_subtype_CFEnd_CFAck 0xF // CF-End + CF-Ack #define ieee_802_11_frame_subtype_Data 0x0 // Data #define ieee_802_11_frame_subtype_Data_CFAck 0x1 // Data + CF-Ack #define ieee_802_11_frame_subtype_Data_CF_Poll 0x2 // Data + CF-Poll #define ieee_802_11_frame_subtype_Data_CF_AckCF_Poll 0x3 // Data + CF-Ack + CF-Poll #define ieee_802_11_frame_subtype_NullFunction 0x4 // Null Function (no data) #define ieee_802_11_frame_subtype_CF_Ack 0x5 // CF-Ack (no data) #define ieee_802_11_frame_subtype_CF_Poll 0x6 // CF-Poll (no data) #define ieee_802_11_frame_subtype_CF_AckCF_Poll 0x7 // CF-Ack + CF-Poll (no data) #define ieee_802_11_frame_subtype_strings {\ { ieee_802_11_frame_subtype_Association_Req, 0xF,"f Association Request"},\ { ieee_802_11_frame_subtype_Association_Resp, 0xF,"1 Association Response"},\ { ieee_802_11_frame_subtype_Reassociation_Req, 0xF,"2 Reassociation Request"},\ { ieee_802_11_frame_subtype_Reassociation_Resp, 0xF,"3 Reassociation Response"},\ { ieee_802_11_frame_subtype_Probe_Req , 0xF,"4 Probe Request"},\ { ieee_802_11_frame_subtype_Probe_Resp , 0xF,"5 Probe Response"},\ { ieee_802_11_frame_subtype_Beacon , 0xF,"8 Beacon"},\ { ieee_802_11_frame_subtype_ATIM , 0xF,"9 ATIM"},\ { ieee_802_11_frame_subtype_Disassociation, 0xF,"A Disassociation"},\ { ieee_802_11_frame_subtype_Authentication, 0xF,"B Authentication"},\ { ieee_802_11_frame_subtype_Deauthentication, 0xF,"C Deauthentication"},\ { ieee_802_11_frame_subtype_PS_Poll , 0xF,"A PS-Poll"},\ { ieee_802_11_frame_subtype_RTS , 0xF,"B RTS"},\ { ieee_802_11_frame_subtype_CTS , 0xF,"C CTS"},\ { ieee_802_11_frame_subtype_ACK , 0xF,"D ACK"},\ { ieee_802_11_frame_subtype_CFEnd , 0xF,"E CF-End"},\ { ieee_802_11_frame_subtype_CFEnd_CFAck , 0xF,"F CF-End + CF-Ack"},\ { ieee_802_11_frame_subtype_Data , 0xF,"0 Data"},\ { ieee_802_11_frame_subtype_Data_CFAck , 0xF,"1 Data + CF-Ack"},\ { ieee_802_11_frame_subtype_Data_CFPoll , 0xF,"2 Data + CF-Poll"},\ { ieee_802_11_frame_subtype_Data_CFAck_CFPoll, 0xF,"3 Data + CF-Ack + CF-Poll"},\ { ieee_802_11_frame_subtype_Null_Function , 0xF,"4 Null Function (no data)"},\ { ieee_802_11_frame_subtype_CFAck , 0xF,"5 CF-Ack (no data)"},\ { ieee_802_11_frame_subtype_CFPoll , 0xF,"6 CF-Poll (no data)"},\ { ieee_802_11_frame_subtype_CFAck_CFPoll, 0xF,"y7 CF-Ack + CF-Poll (no data)"},\ { 0,0,NULL}\ } struct ieee_802_11_frame_subtype_class { u_int8_t subtype; u_int8_t mask; u_int8_t klass; u_int8_t type; }; #define ieee_802_11_frame_subtype_classes {\ { ieee_802_11_frame_subtype_Association_Req, 0xF,2,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Association_Resp, 0xF,2,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Reassociation_Req, 0xF,2,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Reassociation_Resp, 0xF,2,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Probe_Req , 0xF,1,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Probe_Resp , 0xF,1,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Beacon , 0xF,1,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_ATIM , 0xF,1,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Disassociation, 0xF,2,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Authentication, 0xF,1,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_Deauthentication, 0xF,3,ieee_802_11_frame_type_Management},\ { ieee_802_11_frame_subtype_PS-Poll , 0xF,3,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_RTS , 0xF,1,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_CTS , 0xF,1,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_ACK , 0xF,1,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_CFEnd , 0xF,1,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_CFEnd_CFAck , 0xF,1,ieee_802_11_frame_type_Control},\ { ieee_802_11_frame_subtype_Data , 0xF,3,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_Data_CFAck , 0xF,3,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_Data_CF_Poll 0xF,3,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_Data_CF_AckCF_Poll, 0xF,3,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_NullFunction 0xF,1,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_CF_Ack , 0xF,1,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_CF_Poll , 0xF,1,ieee_802_11_frame_type_Data},\ { ieee_802_11_frame_subtype_CF_AckCF_Poll, 0xF,1,ieee_802_11_frame_type_Data},\ { 0,0,NULL}\ } #define IEEE802_11_FC_LEN 2 #define T_MGMT 0x0 /* management */ #define T_CTRL 0x1 /* control */ #define T_DATA 0x2 /* data */ #define T_RESV 0x3 /* reserved */ #define ST_ASSOC_REQUEST 0x0 #define ST_ASSOC_RESPONSE 0x1 #define ST_REASSOC_REQUEST 0x2 #define ST_REASSOC_RESPONSE 0x3 #define ST_PROBE_REQUEST 0x4 #define ST_PROBE_RESPONSE 0x5 /* RESERVED 0x6 */ /* RESERVED 0x7 */ #define ST_BEACON 0x8 #define ST_ATIM 0x9 #define ST_DISASSOC 0xA #define ST_AUTH 0xB #define ST_DEAUTH 0xC /* RESERVED 0xD */ /* RESERVED 0xE */ /* RESERVED 0xF */ #define CTRL_PS_POLL 0xA #define CTRL_RTS 0xB #define CTRL_CTS 0xC #define CTRL_ACK 0xD diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index 675818e..e2ab6d7 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -33,385 +33,443 @@ /* OPIE */ #include <opie2/opcap.h> /* QT */ #include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects) #include <qsocketnotifier.h> #include <qobjectlist.h> /*====================================================================================== * OPacket *======================================================================================*/ OPacket::OPacket( int datalink, 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 ); switch ( datalink ) { case DLT_EN10MB: qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" ); new OEthernetPacket( _end, (const struct ether_header*) data, this ); break; case DLT_IEEE802_11: qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" ); new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this ); break; case DLT_PRISM_HEADER: qDebug( "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" ); new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) data, this ); break; default: qWarning( "OPacket::OPacket(): Received Packet over unsupported datalink '%s'!", datalink ); } } OPacket::~OPacket() { } timevalstruct OPacket::timeval() const { return _hdr.ts; } int OPacket::caplen() const { return _hdr.caplen; } void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l ) { if (!l) return; QObject* o = l->first(); while ( o ) { stats[o->name()]++; updateStats( stats, const_cast<QObjectList*>( o->children() ) ); o = l->next(); } } QString OPacket::dump( int bpl ) const { static int index = 0; index++; int len = _hdr.caplen; QString str; str.sprintf( "\n<----- Packet #%04d Len = 0x%X (%d) ----->\n\n", index, len, len ); str.append( "0000: " ); QString tmp; QString bytes; QString chars; for ( int i = 0; i < len; ++i ) { tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp ); if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] ); else chars.append( '.' ); if ( !((i+1) % bpl) ) { str.append( bytes ); str.append( ' ' ); str.append( chars ); str.append( '\n' ); tmp.sprintf( "%04X: ", i+1 ); str.append( tmp ); bytes = ""; chars = ""; } } if ( (len % bpl) ) { str.append( bytes.leftJustify( 1 + 3*bpl ) ); str.append( chars ); } str.append( '\n' ); return str; } int OPacket::len() const { return _hdr.len; } /*====================================================================================== * OEthernetPacket *======================================================================================*/ 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( 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 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( 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 { return _iphdr->tos; } int OIPPacket::len() const { return EXTRACT_16BITS( &_iphdr->tot_len ); } int OIPPacket::id() const { return EXTRACT_16BITS( &_iphdr->id ); } int OIPPacket::offset() const { return EXTRACT_16BITS( &_iphdr->frag_off ); } int OIPPacket::ttl() const { return _iphdr->ttl; } int OIPPacket::protocol() const { return _iphdr->protocol; } int OIPPacket::checksum() const { return EXTRACT_16BITS( &_iphdr->check ); } /*====================================================================================== + * OARPPacket + *======================================================================================*/ + + +OARPPacket::OARPPacket( const unsigned char* end, const struct myarphdr* data, QObject* parent ) + :QObject( parent, "ARP" ), _arphdr( data ) +{ + qDebug( "OARPPacket::OARPPacket(): decoding ARP header..." ); + qDebug( "ARP type seems to be %02d - '%s'", EXTRACT_16BITS( &_arphdr->ar_op ), (const char*) type() ); + qDebug( "Sender: MAC %s = IP %s", (const char*) senderMacAddress().toString(), (const char*) senderIPV4Address().toString() ); + qDebug( "Target: MAC %s = IP %s", (const char*) targetMacAddress().toString(), (const char*) targetIPV4Address().toString() ); +} + + +OARPPacket::~OARPPacket() +{ +} + + +QString OARPPacket::type() const +{ + switch ( EXTRACT_16BITS( &_arphdr->ar_op ) ) + { + case 1: return "REQUEST"; + case 2: return "REPLY"; + case 3: return "RREQUEST"; + case 4: return "RREPLY"; + case 8: return "InREQUEST"; + case 9: return "InREPLY"; + case 10: return "NAK"; + default: qWarning( "OARPPacket::type(): invalid ARP type!" ); return "<unknown>"; + } +} + + +QHostAddress OARPPacket::senderIPV4Address() const +{ + return EXTRACT_32BITS( &_arphdr->ar_sip ); +} + + +QHostAddress OARPPacket::targetIPV4Address() const +{ + return EXTRACT_32BITS( &_arphdr->ar_tip ); +} + + +OMacAddress OARPPacket::senderMacAddress() const +{ + return OMacAddress( _arphdr->ar_sha ); +} + + +OMacAddress OARPPacket::targetMacAddress() const +{ + return OMacAddress( _arphdr->ar_tha ); +} + + +/*====================================================================================== * OUDPPacket *======================================================================================*/ 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 unsigned char* end, const struct tcphdr* data, QObject* parent ) :QObject( parent, "TCP" ), _tcphdr( data ) { qDebug( "OTCPPacket::OTCPPacket(): decoding TCP header..." ); } OTCPPacket::~OTCPPacket() { } /*====================================================================================== * OPrismHeaderPacket *======================================================================================*/ OPrismHeaderPacket::OPrismHeaderPacket( const unsigned char* end, const struct prism_hdr* data, QObject* parent ) :QObject( parent, "Prism" ), _header( data ) { qDebug( "OPrismHeaderPacket::OPrismHeaderPacket(): decoding PRISM header..." ); qDebug( "Signal Strength = %d", data->signal.data ); new OWaveLanPacket( end, (const struct ieee_802_11_header*) (data+1), this ); } OPrismHeaderPacket::~OPrismHeaderPacket() { } unsigned int OPrismHeaderPacket::signalStrength() const { return _header->signal.data; } /*====================================================================================== * OWaveLanPacket *======================================================================================*/ 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( "payload is encrypted: %s", usesWep() ? "yes" : "no" ); 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( 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_control_header*) data, this ); break; default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type '%d'!", 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 ); } OMacAddress OWaveLanPacket::macAddress3() const { return OMacAddress( _wlanhdr->mac3 ); } OMacAddress OWaveLanPacket::macAddress4() const { return OMacAddress( _wlanhdr->mac4 ); } int OWaveLanPacket::subType() const { return FC_SUBTYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } @@ -605,257 +663,258 @@ OWaveLanManagementCF::OWaveLanManagementCF( const unsigned char* end, const stru 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 unsigned char* end, const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Data" ), _header( data ) { qDebug( "OWaveLanDataPacket::OWaveLanDataPacket(): decoding frame..." ); const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header ); #warning The next line works for most cases, but can not be correct generally! if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6; // compensation for missing last address new OLLCPacket( end, (const struct ieee_802_11_802_2_header*) payload, this ); } OWaveLanDataPacket::~OWaveLanDataPacket() { } /*====================================================================================== * OLLCPacket *======================================================================================*/ OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent ) :QObject( parent, "802.11 LLC" ), _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( end, (const struct iphdr*) (data+1), this ); break; - default: qDebug( "OLLCPacket::OLLCPacket(): Unknown Encapsulation Type" ); + case ETH_P_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; + default: qWarning( "OLLCPacket::OLLCPacket(): Unknown Encapsulation (type=%04X)", EXTRACT_16BITS( &_header->type ) ); } } } OLLCPacket::~OLLCPacket() { } /*====================================================================================== * OWaveLanControlPacket *======================================================================================*/ OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* end, const struct ieee_802_11_control_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Data" ), _header( data ) { qDebug( "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." ); //TODO: Implement this } OWaveLanControlPacket::~OWaveLanControlPacket() { } /*====================================================================================== * OPacketCapturer *======================================================================================*/ OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _pcd( 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; } if ( _pcd ) { pcap_dump_close( _pcd ); _pcd = 0; } pcap_close( _pch ); _open = false; } qDebug( "OPacketCapturer::close() --- dumping capturing statistics..." ); qDebug( "--------------------------------------------------" ); for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it ) qDebug( "%s : %d", (const char*) it.key(), it.data() ); qDebug( "--------------------------------------------------" ); } 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 ( _pcd ) pcap_dump( (u_char*) _pcd, &header, pdata ); diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h index bee0ca0..5a50d9b 100644 --- a/libopie2/opienet/opcap.h +++ b/libopie2/opienet/opcap.h @@ -313,254 +313,278 @@ class OWaveLanManagementDS : public QObject 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 unsigned char*, const struct ieee_802_11_data_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanDataPacket(); private: const struct ieee_802_11_data_header* _header; }; /*====================================================================================== * OWaveLanControlPacket - type: control (T_CTRL) *======================================================================================*/ class OWaveLanControlPacket : public QObject { Q_OBJECT public: OWaveLanControlPacket( const unsigned char*, const struct ieee_802_11_control_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanControlPacket(); private: const struct ieee_802_11_control_header* _header; }; /*====================================================================================== * OLLCPacket - IEEE 802.2 Link Level Control *======================================================================================*/ class OLLCPacket : public QObject { Q_OBJECT public: 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 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; }; /*====================================================================================== + * OARPPacket + *======================================================================================*/ + +class OARPPacket : public QObject +{ + Q_OBJECT + + public: + OARPPacket( const unsigned char*, const struct myarphdr*, QObject* parent = 0 ); + virtual ~OARPPacket(); + + QHostAddress senderIPV4Address() const; + OMacAddress senderMacAddress() const; + QHostAddress targetIPV4Address() const; + OMacAddress targetMacAddress() const; + + //int type() const; + QString type() const; + + private: + const struct myarphdr* _arphdr; +}; + +/*====================================================================================== * OUDPPacket *======================================================================================*/ class OUDPPacket : public QObject { Q_OBJECT public: 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 unsigned char*, const struct tcphdr*, QObject* parent = 0 ); virtual ~OTCPPacket(); int fromPort() const; int toPort() const; private: const struct tcphdr* _tcphdr; }; /*====================================================================================== * OPacketCapturer *======================================================================================*/ /** * @brief A class based wrapper for network packet capturing. * * This class is the base of a high-level interface to the well known packet capturing * library libpcap. ... */ class OPacketCapturer : public QObject { Q_OBJECT public: /** * Constructor. */ OPacketCapturer( QObject* parent = 0, const char* name = 0 ); /** * Destructor. */ ~OPacketCapturer(); /** * Setting the packet capturer to use blocking IO calls can be useful when * not using the socket notifier, e.g. without an application object. */ void setBlocking( bool ); /** * @returns true if the packet capturer uses blocking IO calls. */ bool blocking() const; /** * Closes the packet capturer. This is automatically done in the destructor. */ void close(); /** * @returns the data link type. * @see <pcap.h> for possible values. */ int dataLink() const; /** * @returns the filedescriptor of the packet capturer. This is only useful, if * not using the socket notifier, e.g. without an application object. */ int fileno() const; /** * @returns the next @ref OPacket from the packet capturer. * @note If blocking mode is true then this call might block. */ OPacket* next(); /** * Open the packet capturer to capture packets in live-mode from @a interface. * If a @a filename is given, all captured packets are output to a tcpdump-compatible capture file. */ bool open( const QString& interface, const QString& filename = QString::null ); /** * Open the packet capturer to capture packets in offline-mode from @a file. */ bool open( const QFile& file ); /** * @returns true if the packet capturer is open */ bool isOpen() const; const QMap<QString,int>& statistics() const; signals: /** * This signal is emitted, when a packet has been received. */ 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 pcap_dumper_t* _pcd; // pcap dumper handle QSocketNotifier* _sn; // socket notifier for main loop mutable char _errbuf[PCAP_ERRBUF_SIZE]; // holds error strings from libpcap QMap<QString, int> _stats; // statistics; }; #endif // OPCAP_H |