summaryrefslogtreecommitdiff
path: root/libopie2/opienet/opcap.cpp
authormickeyl <mickeyl>2003-10-04 01:34:13 (UTC)
committer mickeyl <mickeyl>2003-10-04 01:34:13 (UTC)
commita4793f5226e9eb5c8a718cca9335c23530e08b08 (patch) (side-by-side diff)
tree9e18d900f9c0a96170c8221ba4e60e7b7937cf39 /libopie2/opienet/opcap.cpp
parente2716e3862915582d0ce48aaacc967f5b0cf6550 (diff)
downloadopie-a4793f5226e9eb5c8a718cca9335c23530e08b08.zip
opie-a4793f5226e9eb5c8a718cca9335c23530e08b08.tar.gz
opie-a4793f5226e9eb5c8a718cca9335c23530e08b08.tar.bz2
Although not yet complete, the DHCP decoding is now usable
Diffstat (limited to 'libopie2/opienet/opcap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index f1f2b4b..7a6f61b 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -156,520 +156,602 @@ int OPacket::len() const
/*======================================================================================
* 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..." );
qDebug( "fromPort = %d", fromPort() );
qDebug( " toPort = %d", toPort() );
// TODO: Make this a case or a hash if we know more udp protocols
if ( fromPort() == UDP_PORT_BOOTPS || fromPort() == UDP_PORT_BOOTPC ||
toPort() == UDP_PORT_BOOTPS || toPort() == UDP_PORT_BOOTPC )
{
qDebug( "seems to be part of a DHCP conversation => creating DHCP packet." );
new ODHCPPacket( end, (const struct dhcp_packet*) (data+1), this );
}
}
OUDPPacket::~OUDPPacket()
{
}
int OUDPPacket::fromPort() const
{
return EXTRACT_16BITS( &_udphdr->source );
}
int OUDPPacket::toPort() const
{
return EXTRACT_16BITS( &_udphdr->dest );
}
int OUDPPacket::length() const
{
return EXTRACT_16BITS( &_udphdr->len );
}
int OUDPPacket::checksum() const
{
return EXTRACT_16BITS( &_udphdr->check );
}
/*======================================================================================
* ODHCPPacket
*======================================================================================*/
ODHCPPacket::ODHCPPacket( const unsigned char* end, const struct dhcp_packet* data, QObject* parent )
:QObject( parent, "DHCP" ), _dhcphdr( data )
{
qDebug( "ODHCPPacket::ODHCPPacket(): decoding DHCP information..." );
+ qDebug( "DHCP opcode seems to be %02d - '%s'", _dhcphdr->op, isRequest() ? "REQUEST" : "REPLY" );
+ qDebug( "clientAddress: %s", (const char*) clientAddress().toString() );
+ qDebug( " yourAddress: %s", (const char*) yourAddress().toString() );
+ qDebug( "serverAddress: %s", (const char*) serverAddress().toString() );
+ qDebug( " relayAddress: %s", (const char*) relayAddress().toString() );
+ qDebug( "parsing DHCP options..." );
+
+ _type = 0;
+
+ const unsigned char* option = &_dhcphdr->options[4];
+ char tag = -1;
+ char len = -1;
+
+ while ( ( tag = *option++ ) != -1 /* end of option field */ )
+ {
+ len = *option++;
+ qDebug( "recognized DHCP option #%d, length %d", tag, len );
+
+ if ( tag == DHO_DHCP_MESSAGE_TYPE )
+ _type = *option;
+
+ option += len;
+ if ( option >= end )
+ {
+ qWarning( "DHCP parsing ERROR: sanity check says the packet is at its end!" );
+ break;
+ }
+ }
+
+ qDebug( "DHCP type seems to be '%s'", (const char*) type() );
}
ODHCPPacket::~ODHCPPacket()
{
}
+bool ODHCPPacket::isRequest() const
+{
+ return ( _dhcphdr->op == 01 );
+}
+
+
+bool ODHCPPacket::isReply() const
+{
+ return ( _dhcphdr->op == 02 );
+}
+
+
+QString ODHCPPacket::type() const
+{
+ switch ( _type )
+ {
+ case 1: return "DISCOVER";
+ case 2: return "OFFER";
+ case 3: return "REQUEST";
+ case 4: return "DECLINE";
+ case 5: return "ACK";
+ case 6: return "NAK";
+ case 7: return "RELEASE";
+ case 8: return "INFORM";
+ default: qWarning( "ODHCPPacket::type(): invalid DHCP type (%d) !", _dhcphdr->op ); return "<unknown>";
+ }
+}
+
+
+QHostAddress ODHCPPacket::clientAddress() const
+{
+ return EXTRACT_32BITS( &_dhcphdr->ciaddr );
+}
+
+
+QHostAddress ODHCPPacket::yourAddress() const
+{
+ return EXTRACT_32BITS( &_dhcphdr->yiaddr );
+}
+
+
+QHostAddress ODHCPPacket::serverAddress() const
+{
+ return EXTRACT_32BITS( &_dhcphdr->siaddr );
+}
+
+
+QHostAddress ODHCPPacket::relayAddress() const
+{
+ return EXTRACT_32BITS( &_dhcphdr->giaddr );
+}
+
/*======================================================================================
* 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()
{
}
int OTCPPacket::fromPort() const
{
return EXTRACT_16BITS( &_tcphdr->source );
}
int OTCPPacket::toPort() const
{
return EXTRACT_16BITS( &_tcphdr->dest );
}
int OTCPPacket::seq() const
{
return EXTRACT_16BITS( &_tcphdr->seq );
}
int OTCPPacket::ack() const
{
return EXTRACT_16BITS( &_tcphdr->ack_seq );
}
int OTCPPacket::window() const
{
return EXTRACT_16BITS( &_tcphdr->window );
}
int OTCPPacket::checksum() const
{
return EXTRACT_16BITS( &_tcphdr->check );
}
/*======================================================================================
* 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 ) );
}
int OWaveLanPacket::type() const
{
return FC_TYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
}
int OWaveLanPacket::version() const
{
return FC_VERSION( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
}
bool OWaveLanPacket::fromDS() const
{
return FC_FROM_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
}
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 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..." );
qDebug( "Detected subtype is '%s'", (const char*) managementType() );
// 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::managementType() const
{
switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) )
{
case ST_ASSOC_REQUEST: return "AssociationRequest"; break;
case ST_ASSOC_RESPONSE: return "AssociationResponse"; break;
case ST_REASSOC_REQUEST: return "ReassociationRequest"; break;
case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break;
case ST_PROBE_REQUEST: return "ProbeRequest"; break;
case ST_PROBE_RESPONSE: return "ProbeResponse"; break;
case ST_BEACON: return "Beacon"; break;
case ST_ATIM: return "Atim"; break;
case ST_DISASSOC: return "Disassociation"; break;
case ST_AUTH: return "Authentication"; break;
case ST_DEAUTH: return "Deathentication"; break;
default:
qWarning( "OWaveLanManagementPacket::managementType(): unhandled subtype %d", FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) );
return "Unknown";
}
}
int OWaveLanManagementPacket::beaconInterval() const
{
return EXTRACT_LE_16BITS( &_body->beacon_interval );
}
int OWaveLanManagementPacket::capabilities() const
{
return EXTRACT_LE_16BITS( &_body->capability_info );
}