DIY-pcap 0.0.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/diy/packet.rb ADDED
@@ -0,0 +1,17 @@
1
+ module DIY
2
+ class Packet
3
+ def initialize( content, detail_msg = nil )
4
+ @content = content
5
+ @detail_msg = detail_msg
6
+ end
7
+ attr_reader :content, :detail_msg
8
+
9
+ def to_s
10
+ @content
11
+ end
12
+
13
+ def inspect
14
+ "#{Utils.pp(@content)} : from #{@detail_msg}"
15
+ end
16
+ end
17
+ end
data/lib/diy/pcap.rb CHANGED
@@ -17,15 +17,20 @@ module DIY
17
17
  attr_accessor :timeout, :dir, :device_name
18
18
 
19
19
  def send(pkt_dir)
20
- @pkt_stack << Packet.new( pkt_dir2pkt(pkt_dir), Packet::SEND)
20
+ @pkt_stack << PacketEx.new( pkt_dir2pkt(pkt_dir), PacketEx::SEND, pkt_dir)
21
21
  end
22
22
 
23
23
  def recv(pkt_dir)
24
- @pkt_stack << Packet.new( pkt_dir2pkt(pkt_dir), Packet::RECV)
24
+ @pkt_stack << PacketEx.new( pkt_dir2pkt(pkt_dir), PacketEx::RECV, pkt_dir)
25
25
  end
26
26
 
27
27
  def pkt_dir2pkt(dir)
28
- File.read( File.join( @dir, dir ) )
28
+ #~ File.read( File.join( @dir, dir ) )
29
+ ret = ""
30
+ File.open( File.join( @dir, dir), "rb") do |f|
31
+ ret += f.read(65535) until f.eof?
32
+ end
33
+ ret
29
34
  end
30
35
 
31
36
  def run
@@ -44,9 +49,9 @@ module DIY
44
49
  def run_client
45
50
  @pkt_stack.each do |pkt|
46
51
  if pkt.to_outer?
47
- send_pkt(pkt.pkt)
52
+ send_pkt(pkt)
48
53
  else
49
- recv_pkt(pkt.pkt)
54
+ recv_pkt(pkt)
50
55
  end
51
56
  end
52
57
  end
@@ -54,33 +59,46 @@ module DIY
54
59
  def run_server
55
60
  @pkt_stack.each do |pkt|
56
61
  if pkt.to_inner?
57
- send_pkt(pkt.pkt)
62
+ send_pkt(pkt)
58
63
  else
59
- recv_pkt(pkt.pkt)
64
+ recv_pkt(pkt)
60
65
  end
61
66
  end
62
67
  end
63
68
 
64
69
  def send_pkt(pkt)
65
70
  sleep 1
66
- logger.info("send pkt: [ #{Time.now} ]#{pkt[0..10].dump}...")
67
- @driver.inject(pkt)
71
+ logger.info("send pkt: [ #{Time.now} ]#{pkt.pkt[0..10].dump}(file: #{pkt.filename}, size: #{pkt.size})...")
72
+ pkt = pkt.pkt
73
+ pkt = fill60(pkt)
74
+ @driver.send_packet(pkt)
68
75
  end
69
76
 
70
77
  def recv_pkt(pkt)
71
- logger.info("I hope pkt: #{pkt[0..10].dump}")
78
+ logger.info("I hope pkt: #{pkt.pkt[0..10].dump}(file: #{pkt.filename}, size: #{pkt.size})...")
79
+ pkt = pkt.pkt
80
+ pkt = fill60(pkt)
72
81
  @driver.loop do |this, new_pkt|
73
82
  #~ logger.info("recv pkt: [ #{new_pkt.time} ]: #{new_pkt.body[0..10].dump}..." )
74
- if new_pkt.body == pkt
75
- logger.info("recv pkt: [ #{new_pkt.time} ]: #{new_pkt.body[0..10].dump}..." )
76
- logger.info "got the same pkt,stop"
83
+ new_pkt_body = fill60(new_pkt.body)
84
+ if new_pkt_body == pkt
85
+ logger.info("recv pkt: [ #{new_pkt.time} ]: #{new_pkt_body[0..10].dump}..." )
86
+ logger.info "got the same pkt,next"
77
87
  return true
78
88
  end
79
89
  end
80
90
  end
81
91
 
92
+ def fill60(pkt)
93
+ if pkt.size < 60
94
+ logger.debug "pkt size #{pkt.size} less than 60, fill with zero"
95
+ pkt += "0" * (60 - pkt.size)
96
+ end
97
+ pkt
98
+ end
99
+
82
100
  def logger
83
- @@logger ||= Logger.new(STDOUT)
101
+ @@logger ||= DIY::Logger
84
102
  end
85
103
 
86
104
  def logger=(logger)
@@ -89,12 +107,13 @@ module DIY
89
107
 
90
108
  end
91
109
 
92
- class Packet
110
+ class PacketEx
93
111
  SEND = 1
94
112
  RECV = 0
95
- def initialize( pkt, pos )
113
+ def initialize( pkt, pos, filename = nil )
96
114
  @pkt = pkt
97
115
  @pos = pos
116
+ @filename = filename
98
117
  end
99
118
 
100
119
  def to_outer?
@@ -105,6 +124,10 @@ module DIY
105
124
  @pos == RECV
106
125
  end
107
126
 
108
- attr_reader :pkt, :pos
127
+ def size
128
+ @pkt.size
129
+ end
130
+
131
+ attr_reader :pkt, :pos, :filename
109
132
  end
110
133
  end
@@ -2,10 +2,9 @@
2
2
  require 'logger'
3
3
  module DIY
4
4
  class StrategyBuilder
5
- def initialize(queue)
5
+ def initialize
6
6
  @ins = []
7
7
  @logger = DIY::Logger
8
- @queue = queue
9
8
  end
10
9
  attr_reader :queue
11
10
 
@@ -22,27 +21,21 @@ module DIY
22
21
  @logger
23
22
  end
24
23
 
25
- def recv_pkt(pkt)
26
- recv_pkt_queue(queue,pkt)
27
- end
28
-
29
- def recv_pkt_queue(queue, recv_pkt)
30
- hope_pkt = queue.peek
31
- logger.debug("recv_pkt, I hope: #{ hope_pkt[0..10].dump rescue nil }...")
24
+ def call(hope_pkt, recv_pkt, queue)
25
+ logger.debug("recv_pkt, I hope: #{ Utils.pp(hope_pkt) rescue nil }...")
32
26
 
33
27
  return if hope_pkt.nil?
34
28
 
35
29
  @ins.each do |strategy|
36
30
  begin
37
- ret = strategy.call(hope_pkt, recv_pkt, queue)
31
+ ret = strategy.call(hope_pkt.content, recv_pkt.content, queue)
38
32
  rescue Exception => e
39
33
  logger.error("user strategy exception: #{e.class} -> #{e.message}")
40
34
  raise
41
- #TODO 也许仅仅忽略?
42
35
  else
43
36
  if ret == Strategy::OK
44
37
  logger.info("pkt same:")
45
- queue.pop
38
+ queue.shift
46
39
  return
47
40
  elsif ret == Strategy::OK_NO_POP
48
41
  logger.info("pkt skip:")
data/lib/diy/utils.rb CHANGED
@@ -3,17 +3,29 @@ module DIY
3
3
  class << self
4
4
  # 漂亮输出包的前十个内容
5
5
  def pp(pkt)
6
+ pkt = pkt.content if pkt.kind_of?(DIY::Packet)
6
7
  return nil if pkt.nil?
7
8
  ( pkt[0..10] + "..." ).dump
8
9
  end
9
10
 
10
11
  def src_mac(pkt)
12
+ pkt = pkt.content if pkt.kind_of?(DIY::Packet)
11
13
  pkt[6..11]
12
14
  end
13
15
 
14
16
  def dst_mac(pkt)
17
+ pkt = pkt.content if pkt.kind_of?(DIY::Packet)
15
18
  pkt[0..5]
16
19
  end
20
+
21
+ def wait_until( timeout = 20, &block )
22
+ timeout(timeout) do
23
+ loop do
24
+ break if block.call
25
+ sleep 0.01
26
+ end
27
+ end
28
+ end
17
29
  end
18
30
  end
19
31
  end
data/lib/diy/version.rb CHANGED
@@ -1,5 +1,5 @@
1
- module DIY
2
- class PCAP
3
- VERSION = "0.0.4"
4
- end
5
- end
1
+ module DIY
2
+ class PCAP
3
+ VERSION = "0.2.0"
4
+ end
5
+ end
data/lib/diy/worker.rb ADDED
@@ -0,0 +1,49 @@
1
+ # encoding : utf-8
2
+ require 'diy/packet'
3
+ require 'drb'
4
+ module DIY
5
+ include DRbUndumped
6
+ class Worker
7
+ def initialize(live)
8
+ @live = live
9
+ @recv_t = nil
10
+ @start = false
11
+ loop_recv
12
+ end
13
+
14
+ # 发包
15
+ def inject(pkts)
16
+ pkts.each do |pkt|
17
+ DIY::Logger.info "send pkt: #{pkt.inspect}"
18
+ @live.send_packet(pkt.content)
19
+ end
20
+ end
21
+
22
+ def loop_recv
23
+ @recv_t = Thread.new do
24
+ DIY::Logger.info "start thread recving pkt..."
25
+ @live.loop do |this, pkt|
26
+ next unless @start
27
+ @block.call(pkt.body) if @block
28
+ end
29
+ end
30
+ end
31
+
32
+ #收包
33
+ def ready(&block)
34
+ DIY::Logger.info("start recv pkt")
35
+ @block = block
36
+ @start = true
37
+ end
38
+
39
+ def terminal
40
+ DIY::Logger.info("stop recv pkt")
41
+ @start = false
42
+ end
43
+
44
+ def inspect
45
+ "<Worker: #{@live.net}>"
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,25 @@
1
+ # encoding : utf-8
2
+ require 'drb'
3
+ require 'diy/worker'
4
+
5
+ module DIY
6
+ # 创建DRb服务
7
+ class WorkerKeeper
8
+ def initialize(worker, uri)
9
+ @worker = worker
10
+ @uri = uri
11
+ end
12
+
13
+ def run
14
+ DIY::Logger.info "serving at #{@uri}"
15
+ DRb.start_service(@uri, @worker)
16
+ running = true
17
+ trap("INT") { running = false }
18
+ while running
19
+ sleep 0.5
20
+ end
21
+ DIY::Logger.info "bye..."
22
+ DRb.stop_service
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.join( File.dirname(__FILE__), '..', 'lib' )
2
+ require 'rubygems'
3
+ require 'diy/pcap'
4
+
5
+ # client and server
6
+ DIY::PCAP.new do |s|
7
+ s.dir = File.join( File.dirname(__FILE__), '4000port')
8
+ s.send("s1.dat")
9
+ s.recv("r1.dat")
10
+ s.send("s2.dat")
11
+ s.send("s3.dat")
12
+ s.recv("r3.dat")
13
+ s.send("s4.dat")
14
+ s.recv("r4.dat")
15
+ s.send("s5.dat")
16
+ s.send("s6.dat")
17
+ s.recv("r6.dat")
18
+ s.recv("r7.dat")
19
+ s.send("s8.dat")
20
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/simple/howto.vsd ADDED
Binary file
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe DIY::Builder do
4
+
5
+ before(:each) do
6
+ @device_name = FFI::PCap.dump_devices[0][0]
7
+ DIY::Logger.info( "Initialize Live: #{@device_name}" )
8
+ @live = FFI::PCap::Live.new(:dev=>@device_name, :handler => FFI::PCap::Handler, :promisc => true)
9
+ @live2 = FFI::PCap::Live.new(:dev=>@device_name, :handler => FFI::PCap::Handler, :promisc => true)
10
+
11
+ @curi = "druby://localhost:7878"
12
+ @suri = "druby://localhost:7879"
13
+
14
+ end
15
+
16
+ it "#run" do
17
+ # client create
18
+ Thread.abort_on_exception = true
19
+ client_t = Thread.new do
20
+ client = DIY::Worker.new(@live)
21
+ DIY::WorkerKeeper.new(client, @curi).run
22
+ end
23
+
24
+ server_t = Thread.new do
25
+ server = DIY::Worker.new(@live2)
26
+ DIY::WorkerKeeper.new(server, @suri).run
27
+ end
28
+
29
+ sleep 1
30
+ builder = DIY::Builder.new do
31
+ pcapfiles "helper/http.pcap"
32
+ use DIY::SimpleStrategy.new
33
+ end
34
+ builder.run
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'diy/device_finder'
3
+
4
+ describe DIY::DeviceFinder do
5
+ it "#devices" do
6
+ DIY::DeviceFinder.devices
7
+ end
8
+
9
+ it "#pp_devices" do
10
+ DIY::DeviceFinder.pp_devices
11
+ end
12
+
13
+ it "#smart_select" do
14
+ DIY::DeviceFinder.smart_select.should be_kind_of(String)
15
+ end
16
+ end
data/spec/offline_spec.rb CHANGED
@@ -1,47 +1,44 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe DIY::Offline do
4
- it "should get single pkt" do
5
- file = "helper/gre.pcap"
6
- offline = DIY::Offline.new(file)
7
- offline.next.body.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt1' ) )
8
- end
9
4
 
10
- it "should get single pkt nil " do
11
- file = "helper/gre.pcap"
12
- offline = DIY::Offline.new(file)
13
- lambda { while( offline.next ) do ; end }.should_not raise_error
5
+ it "should get next pcap" do
6
+ files = [ "helper/gre.pcap", "helper/app.pcap" ]
7
+ offline = DIY::Offline.new(files)
8
+ offline.next_pcap
9
+ lambda { offline.next_pcap }.should raise_error(DIY::EOFError)
14
10
  end
15
11
 
16
- it "should get correct pkt in two files" do
17
- files = [ "helper/gre.pcap", "helper/app.pcap" ]
12
+ it "should get next special first_pkt" do
13
+ files = [ "helper/app.pcap", "helper/gre.pcap" ]
18
14
  offline = DIY::Offline.new(files)
19
- lambda { while( offline.next ) do ; end }.should_not raise_error
15
+ 22.times { offline.nexts }
16
+ offline.nexts.size.should == 1
20
17
  end
21
18
 
22
- it "should get next pcap" do
19
+ it "should get nexts two" do
23
20
  files = [ "helper/gre.pcap", "helper/app.pcap" ]
24
21
  offline = DIY::Offline.new(files)
22
+ offline.nexts.size.should == 1
23
+ offline.nexts.size.should == 2
24
+ offline.nexts.size.should == 2
25
25
  offline.next_pcap
26
- lambda { offline.next_pcap }.should raise_error(DIY::EOFError)
26
+ offline.nexts.size.should == 1
27
+ offline.nexts.size.should == 7
28
+ lambda { loop do offline.nexts end }.should raise_error(DIY::EOFError)
27
29
  end
28
30
 
29
- it "should get correct first_pkt flag" do
30
- files = [ "helper/gre.pcap", "helper/app.pcap" ]
31
+ it "should get another two" do
32
+ files = [ "helper/http.pcap", "helper/gre.pcap" ]
31
33
  offline = DIY::Offline.new(files)
32
- offline.next
33
- offline.should be_first_pkt
34
- offline.fullname.should == "pkt: `helper/gre.pcap: 1th' "
35
- offline.next
36
- offline.should_not be_first_pkt
37
- offline.fullname.should == "pkt: `helper/gre.pcap: 2th' "
38
- offline.next_pcap
39
- offline.next
40
- offline.fullname.should == "pkt: `helper/app.pcap: 1th' "
41
- offline.should be_first_pkt
42
- offline.next
43
- offline.should_not be_first_pkt
44
- offline.fullname.should == "pkt: `helper/app.pcap: 2th' "
34
+ offline.nexts.size.should == 1
35
+ offline.nexts.size.should == 1
36
+ offline.nexts.size.should == 1
37
+ #change to next
38
+ offline.nexts.size.should == 1
39
+ offline.nexts.size.should == 2
40
+ offline.nexts.size.should == 2
41
+ lambda { loop do offline.nexts end }.should raise_error(DIY::EOFError)
45
42
  end
46
43
 
47
44
  end