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/bin/pcap +62 -5
- data/bin/rpcap +62 -6
- data/lib/diy/builder.rb +14 -16
- data/lib/diy/controller.rb +50 -33
- data/lib/diy/device_finder.rb +26 -0
- data/lib/diy/dig.rb +7 -6
- data/lib/diy/logger.rb +7 -0
- data/lib/diy/offline.rb +98 -28
- data/lib/diy/packet.rb +17 -0
- data/lib/diy/pcap.rb +40 -17
- data/lib/diy/strategy_builder.rb +5 -12
- data/lib/diy/utils.rb +12 -0
- data/lib/diy/version.rb +5 -5
- data/lib/diy/worker.rb +49 -0
- data/lib/diy/worker_keeper.rb +25 -0
- data/simple/4000port.rb +20 -0
- data/simple/4000port/r1.dat +0 -0
- data/simple/4000port/r3.dat +0 -0
- data/simple/4000port/r4.dat +0 -0
- data/simple/4000port/r6.dat +0 -0
- data/simple/4000port/r7.dat +0 -0
- data/simple/4000port/s1.dat +0 -0
- data/simple/4000port/s2.dat +0 -0
- data/simple/4000port/s3.dat +0 -0
- data/simple/4000port/s4.dat +0 -0
- data/simple/4000port/s5.dat +0 -0
- data/simple/4000port/s6.dat +0 -0
- data/simple/4000port/s8.dat +0 -0
- data/simple/howto.vsd +0 -0
- data/spec/controller_spec.rb +36 -0
- data/spec/device_finder_spec.rb +16 -0
- data/spec/offline_spec.rb +26 -29
- data/spec/worker_spec.rb +58 -0
- metadata +24 -9
- data/lib/diy/queue.rb +0 -174
- data/lib/diy/recver.rb +0 -33
- data/lib/diy/sender.rb +0 -26
- data/spec/builder_spec.rb +0 -82
- data/spec/queue_spec.rb +0 -84
- data/spec/sender_spec.rb +0 -21
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 <<
|
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 <<
|
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
|
52
|
+
send_pkt(pkt)
|
48
53
|
else
|
49
|
-
recv_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
|
62
|
+
send_pkt(pkt)
|
58
63
|
else
|
59
|
-
recv_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
|
-
|
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
|
-
|
75
|
-
|
76
|
-
logger.info
|
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
|
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
|
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
|
-
|
127
|
+
def size
|
128
|
+
@pkt.size
|
129
|
+
end
|
130
|
+
|
131
|
+
attr_reader :pkt, :pos, :filename
|
109
132
|
end
|
110
133
|
end
|
data/lib/diy/strategy_builder.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
require 'logger'
|
3
3
|
module DIY
|
4
4
|
class StrategyBuilder
|
5
|
-
def initialize
|
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
|
26
|
-
|
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
|
-
|
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.
|
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
|
-
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
|
data/simple/4000port.rb
ADDED
@@ -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
|
11
|
-
|
12
|
-
offline = DIY::Offline.new(
|
13
|
-
|
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
|
17
|
-
files = [ "helper/
|
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
|
-
|
15
|
+
22.times { offline.nexts }
|
16
|
+
offline.nexts.size.should == 1
|
20
17
|
end
|
21
18
|
|
22
|
-
it "should get
|
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
|
-
|
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
|
30
|
-
files = [ "helper/
|
31
|
+
it "should get another two" do
|
32
|
+
files = [ "helper/http.pcap", "helper/gre.pcap" ]
|
31
33
|
offline = DIY::Offline.new(files)
|
32
|
-
offline.
|
33
|
-
offline.should
|
34
|
-
offline.
|
35
|
-
|
36
|
-
offline.
|
37
|
-
offline.
|
38
|
-
offline.
|
39
|
-
offline.
|
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
|