pcaprub 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ = FAQ
2
+
3
+ Enough already! How does this work by example!?
4
+
5
+ #!/usr/bin/env ruby
6
+ require "rubygems"
7
+ require "pcaprub"
8
+
9
+ class CaptureExample
10
+
11
+ def initialize()
12
+ #interface configuration
13
+ @dev = ::Pcap.lookupdev
14
+ #promiscous_mode = true
15
+ @promiscous_mode = false
16
+ @timeout = 0
17
+
18
+ #packet information
19
+ @capture_packets = 100
20
+ @snaplength = 65535
21
+ @bpf = "ip and not dst net 110.0.0.0/8"
22
+ end
23
+
24
+ def getpackets
25
+ system("ifconfig", @dev, "up")
26
+
27
+ capture = ::Pcap.open_live(@dev, @snaplength, @promiscous_mode, @timeout)
28
+ capture.setfilter(@bpf)
29
+
30
+ begin
31
+ puts "Started capture..(#{@dev} => \"#{@bpf}\")"
32
+ capture.each do |packet|
33
+ # Handling the number of packets to process
34
+ @capture_packets -= 1
35
+ if @capture_packets == 0
36
+ break
37
+ end
38
+ end
39
+
40
+ # ^C to stop sniffing
41
+ rescue Interrupt
42
+ puts "\nPacket Capture stopped by interrupt signal."
43
+
44
+ rescue Exception => e
45
+ puts "\nERROR: #{e}"
46
+ retry
47
+ end
48
+
49
+ puts "Captured #{100 - @capture_packets} packets"
50
+
51
+ return capture
52
+
53
+ end
54
+
55
+ end
56
+
57
+
58
+ mycapture = CaptureExample.new()
59
+ packet_capture = mycapture.getpackets
60
+ puts "capture.stats['recv'] = #{packet_capture.stats['recv']}"
61
+ puts "capture.stats['drop'] = #{packet_capture.stats['drop']}"
62
+
@@ -1,11 +1,11 @@
1
1
  = pcaprub
2
2
 
3
- This goal of this project is to provide a consistent interface to LBL's libpcap
4
- packet capture library. This project was created because the currently
5
- available ruby-pcap library is poorly designed and has been unmaintained since
6
- 2000. This does not provide packet processing functionality, it simply provides
7
- the interface for capturing packets. For packet processing capability, see the
8
- PacketRub project (http://packetrub.rubyforge.org).
3
+ This goal of this project is to provide a consistent interface
4
+ to LBL's libpcap packet capture library. This project was created
5
+ because the currently available ruby-pcap library is poorly designed
6
+ and has been unmaintained since 2000. This does not provide packet
7
+ processing functionality, it simply provides the interface for
8
+ capturing packets. For packet processing capability.
9
9
 
10
10
  Requirements:
11
11
  libpcap - http://www.tcpdump.org
@@ -30,11 +30,17 @@ The Git Repo on Github @shadowbq is forked from the Metasploit SVN repo
30
30
 
31
31
  === Notes on other repositories
32
32
 
33
- The latest community svn version can be obtained from Subversion:
34
- svn checkout http://pcaprub.rubyforge.org/svn/trunk/
35
-
36
- The Metasploit Project also provides a Subversion repository:
33
+ The Metasploit Project also provides a Subversion repository: (0.9-dev)
37
34
  svn checkout http://metasploit.com/svn/framework3/trunk/external/pcaprub/
38
35
 
39
- (credits: github.com/dxoigmn/pcaprub)
36
+ Packetfu Project also provides a listing (0.9-dev)
37
+ http://code.google.com/p/packetfu/source/browse/#svn/trunk/pcaprub_linux
38
+
39
+ The Outdate RubyForge svn version can be obtained from Subversion: (0.7-dev)
40
+ svn checkout http://pcaprub.rubyforge.org/svn/trunk/
41
+ http download Public Rubyforge (0.6)
42
+
43
+ Additonal Github Repos
44
+ github.com/dxoigmn/pcaprub (0.8-dev)
45
+ github.com/spox /pcaprub-spox (0.8-dev+)
40
46
 
data/Rakefile CHANGED
@@ -80,6 +80,7 @@ Rake::RDocTask.new do |rdoc|
80
80
  rdoc.rdoc_dir = 'rdoc'
81
81
  rdoc.title = "pcaprub #{version}"
82
82
  rdoc.rdoc_files.include('README*')
83
+ rdoc.rdoc_files.include('FAQ*')
83
84
  rdoc.rdoc_files.include('LICENSE*')
84
85
  rdoc.rdoc_files.include('lib/**/*.rb')
85
86
  rdoc.rdoc_files.include('ext/**/*.c')
@@ -0,0 +1,82 @@
1
+ = Usage of Pcaprub
2
+
3
+ Pcaprub is a ruby wrapper to the libpcap libary. It provides a common method to access the c bindings defined in libpcap.
4
+
5
+ == Basics of Pcaprub
6
+
7
+ require "rubygems"
8
+ require "pcaprub"
9
+
10
+ mypcap = Pcap.new
11
+
12
+
13
+ == Setting up a live Capture
14
+
15
+ dev = ::Pcap.lookupdev
16
+
17
+ snaplength = 65535
18
+ promiscous_mode = true
19
+ timeout = 0
20
+
21
+ system("ifconfig", dev, "up")
22
+
23
+ capture = ::Pcap.open_live(dev, snaplength, promiscous_mode, timeout)
24
+
25
+ == Open an existing pcap file
26
+
27
+ pcapfile = File.dirname(__FILE__) + "/foo.pcap"
28
+
29
+ if(not File.exists?(pcapfile))
30
+ raise RuntimeError, "The PCAP file #{pcapfile} could not be found"
31
+ end
32
+
33
+ capture = ::Pcap.open_offline(pcapfile)
34
+
35
+ == Setting a BPF Filter
36
+
37
+ bpf = "ip and not net 10.0.0.0/8"
38
+
39
+ capture.setfilter(bpf)
40
+
41
+ == Reading Capture Statistics
42
+
43
+ Packets Received
44
+ capture.stats['recv']
45
+
46
+ Packets Dropped
47
+ capture.stats['drop']
48
+
49
+ Packets Dropped by Interface
50
+ capture.stats['ifdrop']
51
+
52
+ == Running the Capture
53
+
54
+ Sniffing a set number of packets and also letting the user Interrupt Early
55
+
56
+ capture_packets = 100
57
+
58
+ begin
59
+ capture.each do |packet|
60
+ p packet
61
+ # Handling the number of packets to process
62
+ capture_packets -= 1
63
+ if capture_packets == 0
64
+ break
65
+ end
66
+ end
67
+
68
+ # ^C to stop sniffing
69
+ rescue Interrupt
70
+ puts "\nPacket Capture stopped by interrupt signal."
71
+
72
+ rescue Exception => e
73
+ puts "\nERROR: #{e}"
74
+ retry
75
+ end
76
+
77
+ == Examming the DataLink
78
+
79
+ Ethernet or Linux loopback
80
+ if capture.datalink == Pcap::DLT_EN10MB
81
+ puts "Ethernet 10MB Link detected"
82
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.9.1
@@ -35,13 +35,20 @@ typedef struct rbpcapjob {
35
35
  int wtf;
36
36
  } rbpcapjob_t;
37
37
 
38
+ /*
39
+ * returns the version of Pcaprub extension
40
+ */
38
41
  static VALUE
39
42
  rbpcap_s_version(VALUE class)
40
43
  {
41
44
  return rb_str_new2(PCAPRUB_VERSION);
42
45
  }
43
46
 
44
-
47
+ /*
48
+ * Return the name of a network device on the system.
49
+ *
50
+ * The pcap_lookupdev subroutine gets a network device suitable for use with the pcap_open_live and the pcap_lookupnet subroutines. If no interface can be found, or none are configured to be up, Null is returned. In the case of multiple network devices attached to the system, the pcap_lookupdev subroutine returns the first one it finds to be up, other than the loopback interface. (Loopback is always ignored.)
51
+ */
45
52
  static VALUE
46
53
  rbpcap_s_lookupdev(VALUE self)
47
54
  {
@@ -81,6 +88,9 @@ rbpcap_s_lookupdev(VALUE self)
81
88
  return ret_dev;
82
89
  }
83
90
 
91
+ /*
92
+ * Returns the network address and subnet mask for a network device.
93
+ */
84
94
  static VALUE
85
95
  rbpcap_s_lookupnet(VALUE self, VALUE dev)
86
96
  {
@@ -122,7 +132,9 @@ static void rbpcap_free(rbpcap_t *rbp) {
122
132
  rbp->pdt = NULL;
123
133
  free(rbp);
124
134
  }
125
-
135
+ /*
136
+ * Creates a new Pcap instance and returns the object itself.
137
+ */
126
138
  static VALUE
127
139
  rbpcap_new_s(VALUE class)
128
140
  {
@@ -138,6 +150,22 @@ rbpcap_new_s(VALUE class)
138
150
  return self;
139
151
  }
140
152
 
153
+ /*
154
+ * call-seq:
155
+ * setfilter(filter)
156
+ *
157
+ * Provide a valid bpf-filter to apply to the packet capture
158
+ *
159
+ * # Show me all SYN packets:
160
+ * bpf-filter = "tcp[13] & 2 != 0"
161
+ * capture.setfilter(bpf-filter)
162
+ *
163
+ * Examples:
164
+ * * "net 10.0.0.0/8"
165
+ * * "not tcp and dst host 192.168.1.1"
166
+ *
167
+ * Returns the object itself.
168
+ */
141
169
  static VALUE
142
170
  rbpcap_setfilter(VALUE self, VALUE filter)
143
171
  {
@@ -166,7 +194,7 @@ rbpcap_setfilter(VALUE self, VALUE filter)
166
194
  return self;
167
195
  }
168
196
 
169
-
197
+ // transparent method
170
198
  static VALUE
171
199
  rbpcap_open_live(VALUE self, VALUE iface,VALUE snaplen,VALUE promisc, VALUE timeout)
172
200
  {
@@ -218,6 +246,15 @@ rbpcap_open_live(VALUE self, VALUE iface,VALUE snaplen,VALUE promisc, VALUE time
218
246
  return self;
219
247
  }
220
248
 
249
+ /*
250
+ *
251
+ * call-seq:
252
+ * open_live(iface, snaplen, promisc, timeout) -> self
253
+ *
254
+ * capture = ::Pcap.open_live(@dev, @snaplength, @promiscous_mode, @timeout)
255
+ *
256
+ * Returns the object itself.
257
+ */
221
258
  static VALUE
222
259
  rbpcap_open_live_s(VALUE class, VALUE iface, VALUE snaplen, VALUE promisc, VALUE timeout)
223
260
  {
@@ -225,6 +262,7 @@ rbpcap_open_live_s(VALUE class, VALUE iface, VALUE snaplen, VALUE promisc, VALUE
225
262
  return rbpcap_open_live(iPcap, iface, snaplen, promisc, timeout);
226
263
  }
227
264
 
265
+ // transparent method
228
266
  static VALUE
229
267
  rbpcap_open_offline(VALUE self, VALUE filename)
230
268
  {
@@ -250,7 +288,15 @@ rbpcap_open_offline(VALUE self, VALUE filename)
250
288
  return self;
251
289
  }
252
290
 
253
-
291
+ /*
292
+ *
293
+ * call-seq:
294
+ * open_offline(filename) -> self
295
+ *
296
+ * capture = ::Pcap.open_offline(filename)
297
+ *
298
+ * Returns the object itself.
299
+ */
254
300
  static VALUE
255
301
  rbpcap_open_offline_s(VALUE class, VALUE filename)
256
302
  {
@@ -259,6 +305,7 @@ rbpcap_open_offline_s(VALUE class, VALUE filename)
259
305
  return rbpcap_open_offline(iPcap, filename);
260
306
  }
261
307
 
308
+ // transparent method
262
309
  static VALUE
263
310
  rbpcap_open_dead(VALUE self, VALUE linktype, VALUE snaplen)
264
311
  {
@@ -283,6 +330,22 @@ rbpcap_open_dead(VALUE self, VALUE linktype, VALUE snaplen)
283
330
  return self;
284
331
  }
285
332
 
333
+ /*
334
+ *
335
+ * call-seq:
336
+ * open_dead(linktype, snaplen) -> self
337
+ *
338
+ * open a fake Pcap for compiling filters or opening a capture for output
339
+ *
340
+ * ::Pcap.open_dead() is used for creating a pcap structure to use when
341
+ * calling the other functions like compiling BPF code.
342
+ *
343
+ * * linktype specifies the link-layer type
344
+ *
345
+ * * snaplen specifies the snapshot length
346
+ *
347
+ * Returns the object itself.
348
+ */
286
349
  static VALUE
287
350
  rbpcap_open_dead_s(VALUE class, VALUE linktype, VALUE snaplen)
288
351
  {
@@ -291,7 +354,12 @@ rbpcap_open_dead_s(VALUE class, VALUE linktype, VALUE snaplen)
291
354
  return rbpcap_open_dead(iPcap, linktype, snaplen);
292
355
  }
293
356
 
294
-
357
+ /*
358
+ * call-seq:
359
+ * dump_open(filename)
360
+ *
361
+ * dump_open() is called to open a "savefile" for writing
362
+ */
295
363
  static VALUE
296
364
  rbpcap_dump_open(VALUE self, VALUE filename)
297
365
  {
@@ -309,7 +377,17 @@ rbpcap_dump_open(VALUE self, VALUE filename)
309
377
  return self;
310
378
  }
311
379
 
312
- //not sure if this deviates too much from the way the rest of this class works?
380
+
381
+ /*
382
+ * call-seq:
383
+ * dump(caplen, pktlen, packet)
384
+ *
385
+ * not sure if this deviates too much from the way the rest of this class works?
386
+ *
387
+ * Writes packet capture date to a binary file assigned with dump_open().
388
+ *
389
+ * Returns the object itself.
390
+ */
313
391
  static VALUE
314
392
  rbpcap_dump(VALUE self, VALUE caplen, VALUE pktlen, VALUE packet)
315
393
  {
@@ -338,6 +416,14 @@ rbpcap_dump(VALUE self, VALUE caplen, VALUE pktlen, VALUE packet)
338
416
  return self;
339
417
  }
340
418
 
419
+ /*
420
+ * call-seq:
421
+ * inject(payload)
422
+ *
423
+ * inject() transmit a raw packet through the network interface
424
+ *
425
+ * Returns the number of bytes written on success else raise failure.
426
+ */
341
427
  static VALUE
342
428
  rbpcap_inject(VALUE self, VALUE payload)
343
429
  {
@@ -368,6 +454,12 @@ static void rbpcap_handler(rbpcapjob_t *job, struct pcap_pkthdr *hdr, u_char *pk
368
454
  job->hdr = *hdr;
369
455
  }
370
456
 
457
+ /*
458
+ *
459
+ * Returns the next packet from the packet capture device.
460
+ *
461
+ * If the next() is unsuccessful, Null is returned.
462
+ */
371
463
  static VALUE
372
464
  rbpcap_next(VALUE self)
373
465
  {
@@ -396,6 +488,13 @@ rbpcap_next(VALUE self)
396
488
  return Qnil;
397
489
  }
398
490
 
491
+ /*
492
+ * call-seq:
493
+ * each() { |packet| ... }
494
+ *
495
+ * Yields each packet from the capture to the passed-in block in turn.
496
+ *
497
+ */
399
498
  static VALUE
400
499
  rbpcap_capture(VALUE self)
401
500
  {
@@ -417,7 +516,14 @@ rbpcap_capture(VALUE self)
417
516
  return self;
418
517
  }
419
518
 
420
-
519
+ /*
520
+ * call-seq:
521
+ * datalink()
522
+ *
523
+ * Returns the integer datalink value unless capture
524
+ *
525
+ * foo.bar unless capture.datalink == Pcap::DLT_EN10MB
526
+ */
421
527
  static VALUE
422
528
  rbpcap_datalink(VALUE self)
423
529
  {
@@ -430,6 +536,13 @@ rbpcap_datalink(VALUE self)
430
536
  return INT2NUM(pcap_datalink(rbp->pd));
431
537
  }
432
538
 
539
+ /*
540
+ * call-seq:
541
+ * snapshot()
542
+ *
543
+ * Returns the snapshot length, which is the number of bytes to save for each packet captured.
544
+ *
545
+ */
433
546
  static VALUE
434
547
  rbpcap_snapshot(VALUE self)
435
548
  {
@@ -442,7 +555,16 @@ rbpcap_snapshot(VALUE self)
442
555
  return INT2NUM(pcap_snapshot(rbp->pd));
443
556
  }
444
557
 
445
- //returns a hash
558
+ /*
559
+ * call-seq:
560
+ * stats()
561
+ *
562
+ * Returns a hash with statistics of the packet capture
563
+ *
564
+ * - ["recv"] # number of packets received
565
+ * - ["drop"] # number of packets dropped
566
+ *
567
+ */
446
568
  static VALUE
447
569
  rbpcap_stats(VALUE self)
448
570
  {
@@ -460,7 +582,8 @@ rbpcap_stats(VALUE self)
460
582
  hash = rb_hash_new();
461
583
  rb_hash_aset(hash, rb_str_new2("recv"), UINT2NUM(stat.ps_recv));
462
584
  rb_hash_aset(hash, rb_str_new2("drop"), UINT2NUM(stat.ps_drop));
463
- rb_hash_aset(hash, rb_str_new2("idrop"), UINT2NUM(stat.ps_ifdrop));
585
+ // drops by interface XXX not yet supported under pcap.h 2.4
586
+ // rb_hash_aset(hash, rb_str_new2("idrop"), UINT2NUM(stat.ps_ifdrop));
464
587
  return hash;
465
588
  }
466
589
 
@@ -474,20 +597,9 @@ Init_pcaprub()
474
597
  */
475
598
  rb_cPcap = rb_define_class("Pcap", rb_cObject);
476
599
 
477
- /*
478
- * Document-module-function: Version
479
- * return the version of Pcaprub extension
480
- */
481
600
  rb_define_module_function(rb_cPcap, "version", rbpcap_s_version, 0);
482
601
 
483
- /*
484
- * return the device id
485
- */
486
- rb_define_module_function(rb_cPcap, "lookupdev", rbpcap_s_lookupdev, 0);
487
-
488
- /*
489
- * return the net
490
- */
602
+ rb_define_module_function(rb_cPcap, "lookupdev", rbpcap_s_lookupdev, 0);
491
603
  rb_define_module_function(rb_cPcap, "lookupnet", rbpcap_s_lookupnet, 1);
492
604
 
493
605
  rb_define_const(rb_cPcap, "DLT_NULL", INT2NUM(DLT_NULL));
@@ -520,48 +632,18 @@ Init_pcaprub()
520
632
  rb_define_singleton_method(rb_cPcap, "dump_open", rbpcap_dump_open, 1);
521
633
 
522
634
 
523
- /*
524
- * Document-method: dump
525
- */
526
635
  rb_define_method(rb_cPcap, "dump", rbpcap_dump, 3);
527
-
528
- /*
529
- * Document-method: each
530
- */
531
636
  rb_define_method(rb_cPcap, "each", rbpcap_capture, 0);
532
-
533
- /*
534
- * Document-method: next
535
- */
536
637
  rb_define_method(rb_cPcap, "next", rbpcap_next, 0);
537
-
538
- /*
539
- * Document-method: setfilter
540
- */
541
638
  rb_define_method(rb_cPcap, "setfilter", rbpcap_setfilter, 1);
542
-
543
- /*
544
- * Document-method: inject
545
- */
546
639
  rb_define_method(rb_cPcap, "inject", rbpcap_inject, 1);
547
-
548
- /*
549
- * Document-method: datalink
550
- */
551
640
  rb_define_method(rb_cPcap, "datalink", rbpcap_datalink, 0);
552
-
553
- /*
554
- * Document-method: snapshot
555
- */
556
641
  rb_define_method(rb_cPcap, "snapshot", rbpcap_snapshot, 0);
557
642
 
558
643
  /*
559
644
  * Document-method: snaplen
645
+ * Alias of snapshot
560
646
  */
561
647
  rb_define_method(rb_cPcap, "snaplen", rbpcap_snapshot, 0);
562
-
563
- /*
564
- * Document-method: stats
565
- */
566
648
  rb_define_method(rb_cPcap, "stats", rbpcap_stats, 0);
567
649
  }
@@ -1 +1 @@
1
- require File.expand_path(File.dirname(__FILE__)) + "/pcaprub.so"
1
+ require File.expand_path(File.dirname(__FILE__)) + "/pcaprub.so"
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pcaprub}
8
- s.version = "0.9.0"
8
+ s.version = "0.9.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["shadowbq"]
12
- s.date = %q{2010-02-08}
12
+ s.date = %q{2010-02-09}
13
13
  s.description = %q{libpcap bindings for ruby}
14
14
  s.email = %q{shadowbq@gmail.com}
15
15
  s.extensions = ["ext/pcaprub/extconf.rb"]
@@ -20,9 +20,11 @@ Gem::Specification.new do |s|
20
20
  s.files = [
21
21
  ".document",
22
22
  ".gitignore",
23
+ "FAQ.rdoc",
23
24
  "LICENSE",
24
25
  "README.rdoc",
25
26
  "Rakefile",
27
+ "USAGE.rdoc",
26
28
  "VERSION",
27
29
  "ext/pcaprub/extconf.rb",
28
30
  "ext/pcaprub/pcaprub.c",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pcaprub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - shadowbq
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-08 00:00:00 -05:00
12
+ date: 2010-02-09 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,9 +25,11 @@ extra_rdoc_files:
25
25
  files:
26
26
  - .document
27
27
  - .gitignore
28
+ - FAQ.rdoc
28
29
  - LICENSE
29
30
  - README.rdoc
30
31
  - Rakefile
32
+ - USAGE.rdoc
31
33
  - VERSION
32
34
  - ext/pcaprub/extconf.rb
33
35
  - ext/pcaprub/pcaprub.c