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 | |
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 @@ -42,63 +42,64 @@ struct ieee_802_11_header { // 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 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 @@ -145,33 +145,32 @@ QString OPacket::dump( int bpl ) const 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" ); @@ -196,33 +195,32 @@ 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() ); } @@ -274,32 +272,92 @@ 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() { } @@ -717,33 +775,34 @@ 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 ) 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 @@ -425,32 +425,56 @@ class OIPPacket : public QObject 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; |