DIY-pcap 0.0.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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