DIY-pcap 0.0.3 → 0.0.4
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/README.md +1 -1
- data/lib/diy/builder.rb +8 -4
- data/lib/diy/controller.rb +12 -3
- data/lib/diy/dig.rb +1 -1
- data/lib/diy/exceptions.rb +7 -0
- data/lib/diy/logger.rb +29 -5
- data/lib/diy/offline.rb +62 -0
- data/lib/diy/queue.rb +58 -15
- data/lib/diy/strategy.rb +2 -1
- data/lib/diy/strategy_builder.rb +10 -5
- data/lib/diy/utils.rb +14 -13
- data/lib/diy/version.rb +1 -1
- data/simple/diy-strategy-pcap.rb +8 -0
- data/simple/pcap.rb +1 -1
- data/simple/pcaps/app.pcap +0 -0
- data/spec/builder_spec.rb +75 -0
- data/spec/helper/app.pcap +0 -0
- data/spec/helper/gre.pcap +0 -0
- data/spec/helper/http.pcap +0 -0
- data/spec/helper/ssh.pcap +0 -0
- data/spec/logger_spec.rb +12 -0
- data/spec/offline_spec.rb +47 -0
- data/spec/queue_spec.rb +14 -7
- data/spec/utils_spec.rb +16 -0
- metadata +15 -9
data/README.md
CHANGED
data/lib/diy/builder.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module DIY
|
2
2
|
class Builder
|
3
|
-
def initialize(&block)
|
3
|
+
def initialize(server = false, &block)
|
4
4
|
@strategies = []
|
5
5
|
instance_eval(&block)
|
6
|
+
@server = server
|
6
7
|
end
|
7
8
|
|
8
9
|
def find_device
|
9
10
|
@device_name ||= FFI::PCap.dump_devices[0][0]
|
11
|
+
DIY::Logger.info( "Initialize Live: #{@device_name}" )
|
10
12
|
@live = FFI::PCap::Live.new(:dev=>@device_name, :handler => FFI::PCap::Handler, :promisc => true)
|
11
13
|
end
|
12
14
|
|
@@ -23,16 +25,18 @@ module DIY
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def pcapfile(pcaps)
|
26
|
-
|
28
|
+
DIY::Logger.info( "Initialize Offline: #{pcaps.to_a.join(', ')}" )
|
29
|
+
@offline = DIY::Offline.new(pcaps)
|
27
30
|
end
|
31
|
+
alias pcapfiles pcapfile
|
28
32
|
|
29
33
|
def run
|
30
34
|
@offline ||= FFI::PCap::Offline.new('pcaps/example.pcap')
|
31
|
-
@queue = Queue.new(@offline)
|
35
|
+
@queue = Queue.new(@offline, @server)
|
32
36
|
@strategy_builder = DIY::StrategyBuilder.new(@queue)
|
33
37
|
@strategies.each { |builder| @strategy_builder.add(builder) }
|
34
38
|
find_device
|
35
|
-
controller = Controller.new( @live, @
|
39
|
+
controller = Controller.new( @live, @strategy_builder )
|
36
40
|
controller.before_send(&@before_send_hook)
|
37
41
|
controller.run
|
38
42
|
end
|
data/lib/diy/controller.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding : utf-8
|
2
2
|
module DIY
|
3
3
|
class Controller
|
4
|
-
def initialize(live,
|
4
|
+
def initialize(live, strategy)
|
5
5
|
@live = live
|
6
6
|
@recver = Recver.new(@live)
|
7
7
|
@recver.add_watcher(strategy)
|
@@ -24,12 +24,21 @@ module DIY
|
|
24
24
|
|
25
25
|
begin
|
26
26
|
@queue.do_loop do |pkt|
|
27
|
+
logger.info "send pkt: #{Utils.pp(pkt)}"
|
27
28
|
@sender.inject(pkt)
|
28
29
|
end
|
29
30
|
@recver_t.join
|
30
|
-
rescue HopePacketTimeoutError
|
31
|
+
rescue HopePacketTimeoutError =>e
|
31
32
|
# next offline
|
32
|
-
|
33
|
+
DIY::Logger.warn("Timeout: #{e}")
|
34
|
+
old = e
|
35
|
+
begin
|
36
|
+
@queue.clear_and_next_pcap
|
37
|
+
retry
|
38
|
+
rescue EOFError
|
39
|
+
@recver.stop
|
40
|
+
raise old
|
41
|
+
end
|
33
42
|
rescue EOFError
|
34
43
|
@recver.stop
|
35
44
|
end
|
data/lib/diy/dig.rb
CHANGED
data/lib/diy/exceptions.rb
CHANGED
data/lib/diy/logger.rb
CHANGED
@@ -2,29 +2,53 @@ require 'logger'
|
|
2
2
|
|
3
3
|
module DIY
|
4
4
|
class Logger
|
5
|
+
@@logger_container = []
|
5
6
|
@@logger = ::Logger.new(STDOUT)
|
6
|
-
@@logger.level = ::Logger::
|
7
|
+
@@logger.level = ::Logger::INFO
|
7
8
|
@@logger.datetime_format = "%d-%b-%Y %H:%M:%S"
|
9
|
+
@@logger_container.unshift @@logger
|
8
10
|
class <<self
|
9
11
|
def debug(*arg)
|
10
|
-
@@logger
|
12
|
+
@@logger_container.each do |logger|
|
13
|
+
logger.debug(*arg)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
def info(*arg)
|
14
|
-
@@logger
|
18
|
+
@@logger_container.each do |logger|
|
19
|
+
logger.info(*arg)
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
def warn(*arg)
|
18
|
-
@@logger
|
24
|
+
@@logger_container.each do |logger|
|
25
|
+
logger.warn(*arg)
|
26
|
+
end
|
19
27
|
end
|
20
28
|
|
21
29
|
def error(*arg)
|
22
|
-
@@logger
|
30
|
+
@@logger_container.each do |logger|
|
31
|
+
logger.error(*arg)
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
def set(logger)
|
26
36
|
@@logger = logger
|
27
37
|
end
|
38
|
+
|
39
|
+
def add(logger)
|
40
|
+
@@logger_container << logger
|
41
|
+
end
|
42
|
+
alias << add
|
43
|
+
|
44
|
+
def clear
|
45
|
+
@@logger_container.clear
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear_and_add(logger)
|
49
|
+
clear
|
50
|
+
add(logger)
|
51
|
+
end
|
28
52
|
end
|
29
53
|
|
30
54
|
end
|
data/lib/diy/offline.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding : utf-8
|
2
|
+
|
3
|
+
module DIY
|
4
|
+
class Offline
|
5
|
+
def initialize( file_or_files)
|
6
|
+
@file_or_files = file_or_files
|
7
|
+
if file_or_files.kind_of?(String)
|
8
|
+
@off = FFI::PCap::Offline.new(file_or_files)
|
9
|
+
elsif file_or_files.kind_of?(Array)
|
10
|
+
raise ZeroOfflineError," no pcap files found " if file_or_files.empty?
|
11
|
+
@off = FFI::PCap::Offline.new(file_or_files[0])
|
12
|
+
@position = 0
|
13
|
+
end
|
14
|
+
@new_pcap = true
|
15
|
+
@num = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def next
|
19
|
+
pkt = @off.next
|
20
|
+
if pkt.nil?
|
21
|
+
begin
|
22
|
+
next_pcap
|
23
|
+
pkt = @off.next
|
24
|
+
rescue EOFError
|
25
|
+
pkt = nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#record num of pkt
|
30
|
+
@num += 1 if pkt
|
31
|
+
|
32
|
+
pkt
|
33
|
+
end
|
34
|
+
|
35
|
+
def first_pkt?
|
36
|
+
@num == 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def next_pcap
|
40
|
+
if @file_or_files.kind_of?(String) or @position >= @file_or_files.size - 1
|
41
|
+
raise EOFError, " end of pcaps "
|
42
|
+
end
|
43
|
+
@position += 1
|
44
|
+
DIY::Logger.info("pcap file changed: #{@file_or_files[@position]}")
|
45
|
+
@off = FFI::PCap::Offline.new(@file_or_files[@position])
|
46
|
+
@num = 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def filename
|
50
|
+
if @file_or_files.kind_of?(String)
|
51
|
+
@file_or_files
|
52
|
+
else
|
53
|
+
@file_or_files[@position]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def fullname
|
58
|
+
"pkt: `#{filename}: #{@num}th' "
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/diy/queue.rb
CHANGED
@@ -3,12 +3,14 @@ require 'timeout'
|
|
3
3
|
module DIY
|
4
4
|
class Queue
|
5
5
|
|
6
|
-
def initialize(offline)
|
6
|
+
def initialize(offline, force_server = false)
|
7
7
|
@expect_recv_queue = []
|
8
8
|
@offline = offline
|
9
9
|
@m = Mutex.new
|
10
10
|
# 暂存 next_send_pkt 数据
|
11
11
|
@tmp_send_pkt = nil
|
12
|
+
|
13
|
+
@force_server = force_server
|
12
14
|
end
|
13
15
|
|
14
16
|
def expect_recv_queue
|
@@ -18,16 +20,17 @@ module DIY
|
|
18
20
|
def pop
|
19
21
|
return nil if @expect_recv_queue.empty?
|
20
22
|
@m.synchronize {
|
21
|
-
return @expect_recv_queue.shift
|
23
|
+
return @expect_recv_queue.shift[0]
|
22
24
|
}
|
23
25
|
end
|
24
26
|
|
25
27
|
def delete(what)
|
26
|
-
if @expect_recv_queue.
|
28
|
+
if @expect_recv_queue.find { |i| i[0] == what }
|
27
29
|
@m.synchronize {
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
if @expect_recv_queue.find { |i| i[0] == what }
|
31
|
+
@expect_recv_queue.delete_if { |i| i[0] == what }
|
32
|
+
return what
|
33
|
+
end
|
31
34
|
}
|
32
35
|
end
|
33
36
|
return nil
|
@@ -35,13 +38,30 @@ module DIY
|
|
35
38
|
|
36
39
|
def delete_at(index)
|
37
40
|
@m.synchronize {
|
38
|
-
|
41
|
+
deleted = @expect_recv_queue.delete_at(index)
|
42
|
+
return deleted.nil? ? nil : deleted[0]
|
39
43
|
}
|
40
44
|
end
|
41
45
|
|
42
46
|
def peek
|
43
47
|
return nil if @expect_recv_queue.empty?
|
44
|
-
@expect_recv_queue[0]
|
48
|
+
@expect_recv_queue[0][0]
|
49
|
+
end
|
50
|
+
|
51
|
+
def peek_full
|
52
|
+
return nil if @expect_recv_queue.empty?
|
53
|
+
@expect_recv_queue[0]
|
54
|
+
end
|
55
|
+
|
56
|
+
def clear_and_next_pcap
|
57
|
+
@offline.next_pcap
|
58
|
+
clear
|
59
|
+
end
|
60
|
+
|
61
|
+
def clear
|
62
|
+
@m.synchronize {
|
63
|
+
return @expect_recv_queue.clear
|
64
|
+
}
|
45
65
|
end
|
46
66
|
|
47
67
|
# 处理发送报文
|
@@ -49,19 +69,37 @@ module DIY
|
|
49
69
|
# 等待接受报文完成后, 返回发送报文, 并重新填充接受报文
|
50
70
|
# TODO: 支持多个pcap文件
|
51
71
|
def next_send_pkt(&block)
|
52
|
-
|
72
|
+
begin
|
73
|
+
wait_until { @expect_recv_queue.empty? }
|
74
|
+
rescue HopePacketTimeoutError
|
75
|
+
raise HopePacketTimeoutError, "#{peek_full && peek_full[1]}"
|
76
|
+
end
|
53
77
|
if @tmp_send_pkt
|
54
78
|
pkt = @tmp_send_pkt
|
55
79
|
@tmp_send_pkt = nil
|
56
80
|
else
|
57
81
|
pkt = write_recv_pkt
|
58
|
-
|
82
|
+
begin
|
83
|
+
wait_until { @expect_recv_queue.empty? }
|
84
|
+
rescue HopePacketTimeoutError
|
85
|
+
raise HopePacketTimeoutError, "#{peek_full && peek_full[1]}"
|
86
|
+
end
|
59
87
|
end
|
60
|
-
raise EOFError, " no pkt to send" unless pkt
|
88
|
+
raise EOFError, " no pkt to send " unless pkt
|
61
89
|
pkt = pkt.copy
|
62
90
|
|
91
|
+
need_wait_for_seconds = nil
|
92
|
+
# 刚切换pcap文件后需要等待
|
93
|
+
if @offline.first_pkt?
|
94
|
+
need_wait_for_seconds = true
|
95
|
+
end
|
96
|
+
|
63
97
|
recv_pkt = write_recv_pkt
|
64
98
|
|
99
|
+
if need_wait_for_seconds
|
100
|
+
wait_for_seconds
|
101
|
+
end
|
102
|
+
|
65
103
|
yield(pkt.body) if block_given?
|
66
104
|
|
67
105
|
@tmp_send_pkt = recv_pkt.copy if recv_pkt
|
@@ -69,10 +107,15 @@ module DIY
|
|
69
107
|
end
|
70
108
|
alias_method :next, :next_send_pkt
|
71
109
|
|
110
|
+
def wait_for_seconds
|
111
|
+
DIY::Logger.info("new pcap file, sleep 3...")
|
112
|
+
sleep 3
|
113
|
+
end
|
114
|
+
|
72
115
|
def write_recv_pkt
|
73
|
-
while ( (recv_pkt = @offline.next) && ( set_first_gout(recv_pkt.body); comein?(recv_pkt.body) ) )
|
116
|
+
while ( (recv_pkt = @offline.next) && ( @offline.first_pkt? && set_first_gout(recv_pkt.body); comein?(recv_pkt.body) ) )
|
74
117
|
@m.synchronize {
|
75
|
-
@expect_recv_queue << recv_pkt.copy.body
|
118
|
+
@expect_recv_queue << [ recv_pkt.copy.body, @offline.fullname ]
|
76
119
|
}
|
77
120
|
end
|
78
121
|
recv_pkt
|
@@ -86,7 +129,7 @@ module DIY
|
|
86
129
|
end
|
87
130
|
|
88
131
|
def set_first_gout(pkt)
|
89
|
-
return @src_mac if @src_mac
|
132
|
+
#~ return @src_mac if @src_mac
|
90
133
|
if pkt.size < 12
|
91
134
|
raise PktError,"can't find src mac: error format packet"
|
92
135
|
end
|
@@ -107,7 +150,7 @@ module DIY
|
|
107
150
|
end
|
108
151
|
|
109
152
|
def server?
|
110
|
-
$SERVER
|
153
|
+
$SERVER || @force_server
|
111
154
|
end
|
112
155
|
|
113
156
|
def judge_direct(pkt,&block)
|
data/lib/diy/strategy.rb
CHANGED
@@ -3,7 +3,7 @@ module DIY
|
|
3
3
|
# 具体返回值含义见 @BasicStrategy
|
4
4
|
class Strategy
|
5
5
|
OK = true
|
6
|
-
OK_NO_POP = 1
|
6
|
+
OK_NO_POP = SKIP = 1
|
7
7
|
FAIL = false
|
8
8
|
NONE = nil
|
9
9
|
end
|
@@ -18,6 +18,7 @@ module DIY
|
|
18
18
|
# @return:
|
19
19
|
# OK : 匹配, 可以进行下一个报文的处理
|
20
20
|
# OK_NO_POP: 匹配了接收队列中的报文, 但是不需要框架自动pop掉期望报文( 注意, 你需要自行处于报文 )
|
21
|
+
# SKIP: 同上, 可用于跳过以后所有策略队列使用.
|
21
22
|
# FAIL: 肯定失败时使用
|
22
23
|
# NONE: 不匹配, 让框架进行下一个报文匹配
|
23
24
|
def call(hope_pkt, recv_pkt, queue)
|
data/lib/diy/strategy_builder.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# encoding : utf-8
|
2
|
+
require 'logger'
|
2
3
|
module DIY
|
3
4
|
class StrategyBuilder
|
4
5
|
def initialize(queue)
|
@@ -35,21 +36,25 @@ module DIY
|
|
35
36
|
begin
|
36
37
|
ret = strategy.call(hope_pkt, recv_pkt, queue)
|
37
38
|
rescue Exception => e
|
38
|
-
logger.error("strategy
|
39
|
+
logger.error("user strategy exception: #{e.class} -> #{e.message}")
|
39
40
|
raise
|
40
|
-
|
41
|
+
#TODO 也许仅仅忽略?
|
41
42
|
else
|
42
43
|
if ret == Strategy::OK
|
43
44
|
logger.info("pkt same:")
|
44
45
|
queue.pop
|
45
46
|
return
|
46
47
|
elsif ret == Strategy::OK_NO_POP
|
47
|
-
logger.info("pkt
|
48
|
+
logger.info("pkt skip:")
|
48
49
|
return
|
49
50
|
elsif ret == Strategy::FAIL
|
50
51
|
logger.warn("pkt fail:")
|
52
|
+
logger.warn("pkt fail: hope_pkt is #{Utils.pp(hope_pkt)}")
|
53
|
+
logger.warn("pkt fail: recv_pkt is #{Utils.pp(recv_pkt)}")
|
54
|
+
#TODO 也许需要将Queue输出?
|
55
|
+
raise UnExpectPacketError, "strategy FAIL"
|
51
56
|
elsif ret == Strategy::NONE
|
52
|
-
logger.debug("pkt jumpped:")
|
57
|
+
#~ logger.debug("pkt jumpped:")
|
53
58
|
next
|
54
59
|
end # end of if
|
55
60
|
end # end of begin
|
data/lib/diy/utils.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
module DIY
|
2
2
|
module Utils
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
class << self
|
4
|
+
# 漂亮输出包的前十个内容
|
5
|
+
def pp(pkt)
|
6
|
+
return nil if pkt.nil?
|
7
|
+
( pkt[0..10] + "..." ).dump
|
8
|
+
end
|
9
|
+
|
10
|
+
def src_mac(pkt)
|
11
|
+
pkt[6..11]
|
12
|
+
end
|
13
|
+
|
14
|
+
def dst_mac(pkt)
|
15
|
+
pkt[0..5]
|
16
|
+
end
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
data/lib/diy/version.rb
CHANGED
data/simple/diy-strategy-pcap.rb
CHANGED
@@ -5,6 +5,10 @@ class NoMacEqualStrategy < DIY::BasicStrategy
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
+
otherstr = lambda { |hope_pkt, recv_pkt, queue|
|
9
|
+
return DIY::Strategy::OK
|
10
|
+
}
|
11
|
+
|
8
12
|
nomac = NoMacEqualStrategy.new
|
9
13
|
|
10
14
|
change_mac = lambda do |pkt|
|
@@ -18,4 +22,8 @@ builder = DIY::Builder.new do
|
|
18
22
|
pcapfile "pcaps/gre.pcap"
|
19
23
|
end
|
20
24
|
|
25
|
+
logger = Logger.new(STDOUT)
|
26
|
+
logger.level = Logger::INFO
|
27
|
+
|
28
|
+
DIY::Logger.set(logger)
|
21
29
|
builder.run
|
data/simple/pcap.rb
CHANGED
Binary file
|
data/spec/builder_spec.rb
CHANGED
@@ -4,4 +4,79 @@ describe DIY::Builder do
|
|
4
4
|
it "should respond before_send" do
|
5
5
|
DIY::Builder.new { ; }.should be_respond_to("before_send")
|
6
6
|
end
|
7
|
+
|
8
|
+
it "should run two pcaps success " do
|
9
|
+
builder = DIY::Builder.new(true) do
|
10
|
+
use DIY::SimpleStrategy.new
|
11
|
+
pcapfile ["helper/ssh.pcap", "helper/http.pcap"]
|
12
|
+
end
|
13
|
+
|
14
|
+
b = Thread.new do
|
15
|
+
builder.run
|
16
|
+
end
|
17
|
+
|
18
|
+
builder2 = DIY::Builder.new do
|
19
|
+
use DIY::SimpleStrategy.new
|
20
|
+
pcapfile ["helper/ssh.pcap", "helper/http.pcap"]
|
21
|
+
end
|
22
|
+
builder2.run
|
23
|
+
b.join
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should run one pcap success" do
|
27
|
+
builder = DIY::Builder.new(true) do
|
28
|
+
use DIY::SimpleStrategy.new
|
29
|
+
pcapfile ["helper/ssh.pcap"]
|
30
|
+
end
|
31
|
+
|
32
|
+
b = Thread.new do
|
33
|
+
builder.run
|
34
|
+
end
|
35
|
+
|
36
|
+
builder2 = DIY::Builder.new do
|
37
|
+
use DIY::SimpleStrategy.new
|
38
|
+
pcapfile ["helper/ssh.pcap"]
|
39
|
+
end
|
40
|
+
builder2.run
|
41
|
+
b.join
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should run one pcap error" do
|
45
|
+
builder = DIY::Builder.new(true) do
|
46
|
+
use DIY::SimpleStrategy.new
|
47
|
+
pcapfile ["helper/ssh.pcap"]
|
48
|
+
end
|
49
|
+
|
50
|
+
b = Thread.new do
|
51
|
+
builder.run
|
52
|
+
end
|
53
|
+
|
54
|
+
builder2 = DIY::Builder.new do
|
55
|
+
use DIY::SimpleStrategy.new
|
56
|
+
pcapfile ["helper/http.pcap"]
|
57
|
+
end
|
58
|
+
lambda { builder2.run }.should raise_error(DIY::HopePacketTimeoutError)
|
59
|
+
lambda { b.join }.should raise_error(DIY::HopePacketTimeoutError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should run two pcap error" do
|
63
|
+
builder = DIY::Builder.new(true) do
|
64
|
+
use DIY::SimpleStrategy.new
|
65
|
+
pcapfile ["helper/ssh.pcap", "helper/http.pcap"]
|
66
|
+
end
|
67
|
+
|
68
|
+
b = Thread.new do
|
69
|
+
builder.run
|
70
|
+
end
|
71
|
+
|
72
|
+
builder2 = DIY::Builder.new do
|
73
|
+
use DIY::SimpleStrategy.new
|
74
|
+
pcapfile ["helper/http.pcap"]
|
75
|
+
end
|
76
|
+
lambda { builder2.run }.should raise_error(DIY::HopePacketTimeoutError)
|
77
|
+
lambda { b.join }.should raise_error(DIY::HopePacketTimeoutError)
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
7
82
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/logger_spec.rb
CHANGED
@@ -2,6 +2,18 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DIY::Logger do
|
4
4
|
it "#debug" do
|
5
|
+
lambda { DIY::Logger.info("hello world") }.should_not raise_error
|
5
6
|
lambda { DIY::Logger.debug("hello world") }.should_not raise_error
|
7
|
+
lambda { DIY::Logger.warn("hello world") }.should_not raise_error
|
8
|
+
lambda { DIY::Logger.error("hello world") }.should_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it "#add #clear" do
|
12
|
+
require 'logger'
|
13
|
+
logger = ::Logger.new(STDOUT)
|
14
|
+
DIY::Logger.add(logger)
|
15
|
+
lambda { DIY::Logger.info("hello world") }.should_not raise_error
|
16
|
+
DIY::Logger.clear_and_add(logger)
|
17
|
+
lambda { DIY::Logger.info("hello world") }.should_not raise_error
|
6
18
|
end
|
7
19
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
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
|
+
|
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
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should get correct pkt in two files" do
|
17
|
+
files = [ "helper/gre.pcap", "helper/app.pcap" ]
|
18
|
+
offline = DIY::Offline.new(files)
|
19
|
+
lambda { while( offline.next ) do ; end }.should_not raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should get next pcap" do
|
23
|
+
files = [ "helper/gre.pcap", "helper/app.pcap" ]
|
24
|
+
offline = DIY::Offline.new(files)
|
25
|
+
offline.next_pcap
|
26
|
+
lambda { offline.next_pcap }.should raise_error(DIY::EOFError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should get correct first_pkt flag" do
|
30
|
+
files = [ "helper/gre.pcap", "helper/app.pcap" ]
|
31
|
+
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' "
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/spec/queue_spec.rb
CHANGED
@@ -4,16 +4,18 @@ describe DIY::Queue do
|
|
4
4
|
before(:each) do
|
5
5
|
@device_name = FFI::PCap.dump_devices[0][0]
|
6
6
|
@live = FFI::PCap::Live.new(:dev=>@device_name, :handler => FFI::PCap::Handler, :promisc => true)
|
7
|
-
@
|
7
|
+
@pcap_name = "../simple/pcaps/gre.pcap"
|
8
|
+
@offline = DIY::Offline.new(@pcap_name)
|
8
9
|
end
|
9
10
|
|
10
11
|
it "#next_send_pkt" do
|
11
12
|
$SERVER = nil
|
12
13
|
q = DIY::Queue.new(@offline)
|
13
14
|
q.stub(:wait_until).and_return(true)
|
15
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
14
16
|
q.next_send_pkt.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt1' ) )
|
15
|
-
pkt1 = q.instance_variable_get("@expect_recv_queue")[0]
|
16
|
-
pkt2 = q.instance_variable_get("@expect_recv_queue")[1]
|
17
|
+
pkt1 = q.instance_variable_get("@expect_recv_queue")[0][0]
|
18
|
+
pkt2 = q.instance_variable_get("@expect_recv_queue")[1][0]
|
17
19
|
q.instance_variable_get("@expect_recv_queue").size.should == 2
|
18
20
|
pkt1.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
19
21
|
pkt2.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt3' ) )
|
@@ -27,21 +29,23 @@ describe DIY::Queue do
|
|
27
29
|
$SERVER = true
|
28
30
|
q = DIY::Queue.new(@offline)
|
29
31
|
q.stub(:wait_until).and_return(true)
|
32
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
30
33
|
q.next_send_pkt.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
31
|
-
q.instance_variable_get("@expect_recv_queue").should ==
|
34
|
+
q.instance_variable_get("@expect_recv_queue")[0][0].should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt1' ) )
|
32
35
|
q.instance_variable_set("@expect_recv_queue", [])
|
33
36
|
q.next_send_pkt.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt3' ) )
|
34
|
-
q.instance_variable_get("@expect_recv_queue").should ==
|
37
|
+
q.instance_variable_get("@expect_recv_queue")[0][0].should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt4' ))
|
38
|
+
q.instance_variable_get("@expect_recv_queue")[1][0].should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt5' ))
|
35
39
|
$SERVER = nil
|
36
40
|
end
|
37
41
|
|
38
42
|
it "#comein? server" do
|
39
43
|
$SERVER = true
|
40
44
|
q = DIY::Queue.new(@offline)
|
45
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
41
46
|
pkt = File.read( File.join( File.dirname(__FILE__), 'helper/pkt1' ) )
|
42
47
|
pkt2 = File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
43
|
-
q.set_first_gout(pkt)
|
44
|
-
q.set_first_gout(pkt2).should == pkt[6..11]
|
48
|
+
q.set_first_gout(pkt).should == pkt[6..11]
|
45
49
|
q.comein?(pkt).should == true
|
46
50
|
q.comein?(pkt2).should == false
|
47
51
|
$SERVER = nil
|
@@ -50,6 +54,7 @@ describe DIY::Queue do
|
|
50
54
|
it "#peek #pop" do
|
51
55
|
q = DIY::Queue.new(@offline)
|
52
56
|
q.stub(:wait_until).and_return(true)
|
57
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
53
58
|
q.next_send_pkt
|
54
59
|
q.peek.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
55
60
|
q.pop.should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
@@ -61,6 +66,7 @@ describe DIY::Queue do
|
|
61
66
|
it "#delete" do
|
62
67
|
q = DIY::Queue.new(@offline)
|
63
68
|
q.stub(:wait_until).and_return(true)
|
69
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
64
70
|
q.next_send_pkt
|
65
71
|
q.delete(File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )).should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
66
72
|
q.pop
|
@@ -70,6 +76,7 @@ describe DIY::Queue do
|
|
70
76
|
it "#delete_at" do
|
71
77
|
q = DIY::Queue.new(@offline)
|
72
78
|
q.stub(:wait_until).and_return(true)
|
79
|
+
q.stub(:wait_for_seconds).and_return(nil)
|
73
80
|
q.next_send_pkt
|
74
81
|
q.delete_at(0).should == File.read( File.join( File.dirname(__FILE__), 'helper/pkt2' ) )
|
75
82
|
end
|
data/spec/utils_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DIY::Utils do
|
4
|
+
it "#pp" do
|
5
|
+
DIY::Utils.pp('a' * 100).should == ('a' * 11 + '...').dump
|
6
|
+
end
|
7
|
+
|
8
|
+
it "#src_mac" do
|
9
|
+
DIY::Utils.src_mac( 'a' * 100 ).should == "a" * 6
|
10
|
+
end
|
11
|
+
|
12
|
+
it "#dst_mac" do
|
13
|
+
DIY::Utils.dst_mac( 'a' * 100 ).should == "a" * 6
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: DIY-pcap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- yafei Lee
|
@@ -15,7 +14,8 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2012-09-
|
17
|
+
date: 2012-09-13 00:00:00 +08:00
|
18
|
+
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: ffi-pcap
|
@@ -25,7 +25,6 @@ dependencies:
|
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
hash: 23
|
29
28
|
segments:
|
30
29
|
- 0
|
31
30
|
- 2
|
@@ -58,6 +57,7 @@ files:
|
|
58
57
|
- lib/diy/dig.rb
|
59
58
|
- lib/diy/exceptions.rb
|
60
59
|
- lib/diy/logger.rb
|
60
|
+
- lib/diy/offline.rb
|
61
61
|
- lib/diy/pcap.rb
|
62
62
|
- lib/diy/queue.rb
|
63
63
|
- lib/diy/recver.rb
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- simple/cmd-pcap.rb
|
71
71
|
- simple/diy-strategy-pcap.rb
|
72
72
|
- simple/pcap.rb
|
73
|
+
- simple/pcaps/app.pcap
|
73
74
|
- simple/pcaps/gre.pcap
|
74
75
|
- simple/pcaps/r1.dat
|
75
76
|
- simple/pcaps/r3-2.dat
|
@@ -79,15 +80,22 @@ files:
|
|
79
80
|
- simple/pcaps/s3.dat
|
80
81
|
- simple/pcaps/s4.dat
|
81
82
|
- spec/builder_spec.rb
|
83
|
+
- spec/helper/app.pcap
|
84
|
+
- spec/helper/gre.pcap
|
85
|
+
- spec/helper/http.pcap
|
82
86
|
- spec/helper/pkt1
|
83
87
|
- spec/helper/pkt2
|
84
88
|
- spec/helper/pkt3
|
85
89
|
- spec/helper/pkt4
|
86
90
|
- spec/helper/pkt5
|
91
|
+
- spec/helper/ssh.pcap
|
87
92
|
- spec/logger_spec.rb
|
93
|
+
- spec/offline_spec.rb
|
88
94
|
- spec/queue_spec.rb
|
89
95
|
- spec/sender_spec.rb
|
90
96
|
- spec/spec_helper.rb
|
97
|
+
- spec/utils_spec.rb
|
98
|
+
has_rdoc: true
|
91
99
|
homepage: ""
|
92
100
|
licenses: []
|
93
101
|
|
@@ -101,7 +109,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
109
|
requirements:
|
102
110
|
- - ">="
|
103
111
|
- !ruby/object:Gem::Version
|
104
|
-
hash: 3
|
105
112
|
segments:
|
106
113
|
- 0
|
107
114
|
version: "0"
|
@@ -110,14 +117,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
117
|
requirements:
|
111
118
|
- - ">="
|
112
119
|
- !ruby/object:Gem::Version
|
113
|
-
hash: 3
|
114
120
|
segments:
|
115
121
|
- 0
|
116
122
|
version: "0"
|
117
123
|
requirements: []
|
118
124
|
|
119
125
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.
|
126
|
+
rubygems_version: 1.3.7
|
121
127
|
signing_key:
|
122
128
|
specification_version: 3
|
123
129
|
summary: DIY pcap send and recv
|