summaryrefslogtreecommitdiff
path: root/libopie2/opienet/opcap.cpp
Unidiff
Diffstat (limited to 'libopie2/opienet/opcap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp609
1 files changed, 609 insertions, 0 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
new file mode 100644
index 0000000..48f874f
--- a/dev/null
+++ b/libopie2/opienet/opcap.cpp
@@ -0,0 +1,609 @@
1/*
2                 This file is part of the Opie Project
3              Copyright (C) 2003 by the Wellenreiter team:
4 Martin J. Muench <mjm@remote-exploit.org>
5 Max Moser <mmo@remote-exploit.org
6 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
7 =.
8 .=l.
9           .>+-=
10 _;:,     .>    :=|. This program is free software; you can
11.> <`_,   >  .   <= redistribute it and/or modify it under
12:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
13.="- .-=="i,     .._ License as published by the Free Software
14 - .   .-<_>     .<> Foundation; either version 2 of the License,
15     ._= =}       : or (at your option) any later version.
16    .%`+i>       _;_.
17    .i_,=:_.      -<s. This program is distributed in the hope that
18     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
19    : ..    .:,     . . . without even the implied warranty of
20    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
21  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
22..}^=.=       =       ; Library General Public License for more
23++=   -.     .`     .: details.
24 :     =  ...= . :.=-
25 -.   .:....=;==+<; You should have received a copy of the GNU
26  -_. . .   )=.  = Library General Public License along with
27    --        :-=` this library; see the file COPYING.LIB.
28 If not, write to the Free Software Foundation,
29 Inc., 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA.
31
32*/
33
34/* OPIE */
35
36#include <opie2/opcap.h>
37
38/* QT */
39
40#include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects)
41#include <qsocketnotifier.h>
42
43/*======================================================================================
44 * OPacket
45 *======================================================================================*/
46
47OPacket::OPacket( packetheaderstruct header, const unsigned char* data, QObject* parent )
48 :QObject( parent, "Generic" ), _hdr( header ), _data( data )
49{
50 qDebug( "OPacket::OPacket(): (Len %d, CapLen %d)" /*, ctime((const time_t*) header.ts.tv_sec)*/, header.len, header.caplen );
51
52 if ( packetCapturer()->dataLink() == DLT_EN10MB )
53 {
54 qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" );
55 new OEthernetPacket( (const struct ether_header*) data, this );
56 }
57 else
58 {
59 qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" );
60 new OWaveLanPacket( (const struct ieee_802_11_header*) data, this );
61 }
62}
63
64
65OPacket::~OPacket()
66{
67}
68
69
70OPacketCapturer* OPacket::packetCapturer() const
71{
72 return parent()->inherits( "OPacketCapturer" ) ? static_cast<OPacketCapturer*>( parent() ) : 0;
73}
74
75
76timevalstruct OPacket::timeval() const
77{
78 return _hdr.ts;
79}
80
81
82int OPacket::caplen() const
83{
84 return _hdr.caplen;
85}
86
87
88void OPacket::dump() const
89{
90 printf( "OPacket::dump()\n" );
91 printf( "----------------\n" );
92
93 for ( int i = 0; i < _hdr.caplen; ++i )
94 {
95 printf( "%02x ", _data[i] );
96 if ( !((i+1) % 32) ) printf( "\n" );
97 }
98 printf( "\n\n" );
99}
100
101
102
103int OPacket::len() const
104{
105 return _hdr.len;
106}
107
108/*======================================================================================
109 * OEthernetPacket
110 *======================================================================================*/
111
112OEthernetPacket::OEthernetPacket( const struct ether_header* data, QObject* parent )
113 :QObject( parent, "Ethernet" ), _ether( data )
114
115{
116
117 qDebug( "Source = %s", (const char*) sourceAddress().toString() );
118 qDebug( "Destination = %s", (const char*) destinationAddress().toString() );
119
120 if ( sourceAddress() == OMacAddress::broadcast )
121 qDebug( "Source is broadcast address" );
122 if ( destinationAddress() == OMacAddress::broadcast )
123 qDebug( "Destination is broadcast address" );
124
125 switch ( type() )
126 {
127 case ETHERTYPE_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break;
128 case ETHERTYPE_ARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = ARP" ); break; }
129 case ETHERTYPE_REVARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" ); break; }
130 default: qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" );
131 }
132
133}
134
135
136OEthernetPacket::~OEthernetPacket()
137{
138}
139
140
141OMacAddress OEthernetPacket::sourceAddress() const
142{
143 return OMacAddress( _ether->ether_shost );
144}
145
146
147OMacAddress OEthernetPacket::destinationAddress() const
148{
149 return OMacAddress( _ether->ether_dhost );
150}
151
152int OEthernetPacket::type() const
153{
154 return ntohs( _ether->ether_type );
155}
156
157
158/*======================================================================================
159 * OIPPacket
160 *======================================================================================*/
161
162
163OIPPacket::OIPPacket( const struct iphdr* data, QObject* parent )
164 :QObject( parent, "IP" ), _iphdr( data )
165
166{
167 qDebug( "OIPPacket::OIPPacket(): decoding IP header..." );
168
169 //qDebug( "FromAddress: %s", (const char*) inet_ntoa( *src ) );
170 //qDebug( " ToAddress: %s", (const char*) inet_ntoa( *dst ) );
171
172 qDebug( "FromAddress: %s", (const char*) fromIPAddress().toString() );
173 qDebug( " toAddress: %s", (const char*) toIPAddress().toString() );
174
175 switch ( protocol() )
176 {
177 case IPPROTO_UDP: new OUDPPacket( (const struct udphdr*) (data+1), this ); break;
178 case IPPROTO_TCP: new OTCPPacket( (const struct tcphdr*) (data+1), this ); break;
179 default: qDebug( "OIPPacket::OIPPacket(): unknown IP protocol type = %d", protocol() );
180 }
181
182}
183
184OIPPacket::~OIPPacket()
185{
186}
187
188
189QHostAddress OIPPacket::fromIPAddress() const
190{
191 return EXTRACT_32BITS( &_iphdr->saddr );
192}
193
194
195QHostAddress OIPPacket::toIPAddress() const
196{
197 return EXTRACT_32BITS( &_iphdr->saddr );
198}
199
200
201int OIPPacket::tos() const
202{
203 return _iphdr->tos;
204}
205
206
207int OIPPacket::len() const
208{
209 return EXTRACT_16BITS( &_iphdr->tot_len );
210}
211
212
213int OIPPacket::id() const
214{
215 return EXTRACT_16BITS( &_iphdr->id );
216}
217
218
219int OIPPacket::offset() const
220{
221 return EXTRACT_16BITS( &_iphdr->frag_off );
222}
223
224
225int OIPPacket::ttl() const
226{
227 return _iphdr->ttl;
228}
229
230
231int OIPPacket::protocol() const
232{
233 return _iphdr->protocol;
234}
235
236
237int OIPPacket::checksum() const
238{
239 return EXTRACT_16BITS( &_iphdr->check );
240}
241
242/*======================================================================================
243 * OUDPPacket
244 *======================================================================================*/
245
246
247OUDPPacket::OUDPPacket( const struct udphdr* data, QObject* parent )
248 :QObject( parent, "UDP" ), _udphdr( data )
249
250{
251 qDebug( "OUDPPacket::OUDPPacket(): decoding UDP header..." );
252}
253
254OUDPPacket::~OUDPPacket()
255{
256}
257
258
259/*======================================================================================
260 * OTCPPacket
261 *======================================================================================*/
262
263
264OTCPPacket::OTCPPacket( const struct tcphdr* data, QObject* parent )
265 :QObject( parent, "TCP" ), _tcphdr( data )
266
267{
268 qDebug( "OTCPPacket::OTCPPacket(): decoding TCP header..." );
269}
270
271OTCPPacket::~OTCPPacket()
272{
273}
274
275
276/*======================================================================================
277 * OWaveLanPacket
278 *======================================================================================*/
279
280
281OWaveLanPacket::OWaveLanPacket( const struct ieee_802_11_header* data, QObject* parent )
282 :QObject( parent, "802.11" ), _wlanhdr( data )
283
284{
285 qDebug( "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." );
286 qDebug( "type: %0X", type() );
287 qDebug( "subType: %0X", subType() );
288 qDebug( "duration: %d", duration() );
289 qDebug( "powermanagement: %d", usesPowerManagement() );
290 qDebug( "wep: %d", usesWep() );
291 qDebug( "MAC1: %s", (const char*) macAddress1().toString() );
292 qDebug( "MAC2: %s", (const char*) macAddress2().toString() );
293 qDebug( "MAC3: %s", (const char*) macAddress3().toString() );
294 qDebug( "MAC4: %s", (const char*) macAddress4().toString() );
295
296 switch ( type() )
297 {
298 case T_MGMT: new OWaveLanManagementPacket( (const struct ieee_802_11_mgmt_header*) data, this ); break;
299 case T_DATA: new OWaveLanDataPacket( (const struct ieee_802_11_data_header*) data, this ); break;
300 //case T_CTRL: new OWaveLanControlPacket( (const struct ieee_802_11_ctrl_header*) data, this ); break;
301 default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown type!" );
302 }
303}
304
305OWaveLanPacket::~OWaveLanPacket()
306{
307}
308
309
310int OWaveLanPacket::duration() const
311{
312 return _wlanhdr->duration;
313}
314
315
316OMacAddress OWaveLanPacket::macAddress1() const
317{
318 return OMacAddress( _wlanhdr->mac1 );
319}
320
321
322OMacAddress OWaveLanPacket::macAddress2() const
323{
324 return OMacAddress( _wlanhdr->mac2 );
325}
326
327
328OMacAddress OWaveLanPacket::macAddress3() const
329{
330 return OMacAddress( _wlanhdr->mac3 );
331}
332
333
334OMacAddress OWaveLanPacket::macAddress4() const
335{
336 return OMacAddress( _wlanhdr->mac4 );
337}
338
339
340int OWaveLanPacket::subType() const
341{
342 return FC_SUBTYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
343}
344
345
346int OWaveLanPacket::type() const
347{
348 return FC_TYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
349}
350
351
352int OWaveLanPacket::version() const
353{
354 return FC_VERSION( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
355}
356
357
358bool OWaveLanPacket::fromDS() const
359{
360 return FC_FROM_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
361}
362
363
364bool OWaveLanPacket::toDS() const
365{
366 return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
367}
368
369
370bool OWaveLanPacket::usesPowerManagement() const
371{
372 return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
373}
374
375
376bool OWaveLanPacket::usesWep() const
377{
378 return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
379}
380
381
382/*======================================================================================
383 * OWaveLanManagementPacket
384 *======================================================================================*/
385
386OWaveLanManagementPacket::OWaveLanManagementPacket( const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent )
387 :QObject( parent, "802.11 Management" ), _header( data ),
388 _body( (const struct ieee_802_11_mgmt_body*) (data+1) )
389{
390 qDebug( "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." );
391
392 switch ( ((OWaveLanPacket*) this->parent() )->subType() )
393 {
394 case ST_BEACON:
395 {
396 qDebug( "TYPE: BEACON FRAME" );
397 qDebug( "ESSID: %s", (const char*) SSID() );
398 break;
399 }
400 }
401}
402
403
404OWaveLanManagementPacket::~OWaveLanManagementPacket()
405{
406}
407
408
409QString OWaveLanManagementPacket::SSID() const
410{
411 int length = _body->ssid.length;
412 if ( length > 32 ) length = 32;
413 char essid[length+1];
414 memcpy( &essid, _body->ssid.ssid, length );
415 essid[length] = 0x0;
416 return essid;
417}
418
419
420/*======================================================================================
421 * OWaveLanDataPacket
422 *======================================================================================*/
423
424OWaveLanDataPacket::OWaveLanDataPacket( const struct ieee_802_11_data_header* data, OWaveLanPacket* parent )
425 :QObject( parent, "802.11 Data" ), _header( data )
426{
427 //qDebug( "size of header = %d", sizeof( struct ieee_802_11_data_header ) );
428 //qDebug( "header: %0x", data );
429 const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header );
430 //qDebug( "payload: %0x", payload );
431
432 if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6; // compensation for missing last address
433
434 new OLLCPacket( (const struct ieee_802_11_802_2_header*) payload, this );
435}
436
437
438OWaveLanDataPacket::~OWaveLanDataPacket()
439{
440}
441
442
443/*======================================================================================
444 * OLLCPacket
445 *======================================================================================*/
446
447OLLCPacket::OLLCPacket( const struct ieee_802_11_802_2_header* data, QObject* parent )
448 :QObject( parent, "802.11 802_2" ), _header( data )
449{
450 qDebug( "OLLCPacket::OLLCPacket(): decoding frame..." );
451
452 if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) )
453 {
454 qDebug( "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type=%04X)", EXTRACT_16BITS( &_header->type ) );
455
456 switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h
457 {
458 case ETH_P_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break;
459 default: qDebug( "OLLCPacket::OLLCPacket(): Unknown Encapsulation Type" );
460 }
461
462 }
463}
464
465
466OLLCPacket::~OLLCPacket()
467{
468}
469
470/*======================================================================================
471 * OPacketCapturer
472 *======================================================================================*/
473
474OPacketCapturer::OPacketCapturer( QObject* parent, const char* name )
475 :QObject( parent, name ), _name( QString::null ), _open( false ),
476 _pch( 0 )
477{
478}
479
480
481OPacketCapturer::~OPacketCapturer()
482{
483 if ( _open )
484 {
485 qDebug( "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." );
486 close();
487 }
488}
489
490
491void OPacketCapturer::setBlocking( bool b )
492{
493 if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 )
494 {
495 qDebug( "OPacketCapturer::setBlocking(): blocking mode changed successfully." );
496 }
497 else
498 {
499 qDebug( "OPacketCapturer::setBlocking(): can't change blocking mode: %s", _errbuf );
500 }
501}
502
503
504bool OPacketCapturer::blocking() const
505{
506 int b = pcap_getnonblock( _pch, _errbuf );
507 if ( b == -1 )
508 {
509 qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf );
510 return -1;
511 }
512 return !b;
513}
514
515
516void OPacketCapturer::close()
517{
518 if ( _open )
519 {
520 pcap_close( _pch );
521 _open = false;
522 }
523}
524
525
526int OPacketCapturer::dataLink() const
527{
528 return pcap_datalink( _pch );
529}
530
531
532int OPacketCapturer::fileno() const
533{
534 if ( _open )
535 {
536 return pcap_fileno( _pch );
537 }
538 else
539 {
540 return -1;
541 }
542}
543
544
545OPacket* OPacketCapturer::next()
546{
547 packetheaderstruct header;
548 const unsigned char* pdata = pcap_next( _pch, &header );
549 if ( header.len )
550 return new OPacket( header, pdata, this );
551 else
552 return 0;
553}
554
555
556bool OPacketCapturer::open( const QString& name )
557{
558 if ( _open )
559 {
560 if ( name == _name ) // ignore opening an already openend device
561 {
562 return true;
563 }
564 else // close the last opened device
565 {
566 close();
567 }
568 }
569
570 _name = name;
571
572 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] );
573
574 if ( handle )
575 {
576 qDebug( "OPacketCapturer::open(): libpcap opened successfully." );
577 _pch = handle;
578 _open = true;
579
580 // in case we have a qapp, create a socket notifier
581 if ( qApp )
582 {
583 QSocketNotifier* sn = new QSocketNotifier( fileno(), QSocketNotifier::Read, this );
584 connect( sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
585 }
586
587 return true;
588 }
589 else
590 {
591 qDebug( "OPacketCapturer::open(): can't open libpcap: %s", _errbuf );
592 return false;
593 }
594
595}
596
597
598bool OPacketCapturer::isOpen() const
599{
600 return _open;
601}
602
603
604void OPacketCapturer::readyToReceive()
605{
606 qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(...)'" );
607 emit receivedPacket( next() );
608}
609