DIY-pcap 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/diy/builder.rb +8 -0
- data/lib/diy/controller.rb +61 -17
- data/lib/diy/exceptions.rb +4 -0
- data/lib/diy/live.rb +1 -1
- data/lib/diy/mac_learner.rb +77 -5
- data/lib/diy/offline.rb +25 -3
- data/lib/diy/parser/mu/pcap/ipv4.rb +2 -1
- data/lib/diy/strategy_builder.rb +1 -1
- data/lib/diy/utils.rb +18 -1
- data/lib/diy/version.rb +1 -1
- data/lib/diy/worker.rb +6 -1
- data/spec/controller_spec.rb +11 -0
- data/spec/helper/badtcp.dat +0 -0
- data/spec/mac_learner_spec.rb +62 -0
- data/spec/offline_spec.rb +19 -13
- data/spec/utils_spec.rb +17 -0
- metadata +9 -9
data/lib/diy/builder.rb
CHANGED
@@ -34,6 +34,10 @@ module DIY
|
|
34
34
|
@timeout = timeout
|
35
35
|
end
|
36
36
|
|
37
|
+
def error_on_stop(*)
|
38
|
+
@error_on_stop = true
|
39
|
+
end
|
40
|
+
|
37
41
|
def client(ip_or_iport)
|
38
42
|
@curi = ip_or_iport_with_default(ip_or_iport, 7878)
|
39
43
|
end
|
@@ -78,6 +82,9 @@ module DIY
|
|
78
82
|
if @filter
|
79
83
|
@client.filter(@filter)
|
80
84
|
@server.filter(@filter)
|
85
|
+
else
|
86
|
+
@client.filter("")
|
87
|
+
@server.filter("")
|
81
88
|
end
|
82
89
|
end
|
83
90
|
|
@@ -90,6 +97,7 @@ module DIY
|
|
90
97
|
controller = Controller.new( @client, @server, @offline, @strategy_builder )
|
91
98
|
controller.before_send(&@before_send_hook)
|
92
99
|
controller.timeout(@timeout) if @timeout
|
100
|
+
controller.error_on_stop if @error_on_stop
|
93
101
|
controller.run
|
94
102
|
end
|
95
103
|
|
data/lib/diy/controller.rb
CHANGED
@@ -10,9 +10,11 @@ module DIY
|
|
10
10
|
@strategy = strategy
|
11
11
|
@before_send = nil
|
12
12
|
@timeout = nil
|
13
|
+
@error_on_stop = nil
|
13
14
|
end
|
14
15
|
|
15
16
|
def run
|
17
|
+
do_trap
|
16
18
|
client = @client
|
17
19
|
server = @server
|
18
20
|
|
@@ -24,25 +26,40 @@ module DIY
|
|
24
26
|
|
25
27
|
loop do
|
26
28
|
begin
|
27
|
-
pkts = @offline.nexts
|
29
|
+
pkts, where = @offline.nexts
|
30
|
+
case where
|
31
|
+
when :A
|
32
|
+
client, server = @client, @server
|
33
|
+
when :B
|
34
|
+
client, server = @server, @client
|
35
|
+
end
|
28
36
|
one_round( client, server, pkts )
|
29
|
-
client, server = server, client
|
30
37
|
rescue HopePacketTimeoutError, UserError, FFI::PCap::LibError => e
|
31
38
|
DIY::Logger.warn( "Timeout: Hope packet is #{pkts[0].pretty_print} ") if e.kind_of?(HopePacketTimeoutError)
|
32
39
|
@fail_count += 1
|
33
|
-
|
34
|
-
@offline.next_pcap
|
35
|
-
server.terminal
|
36
|
-
rescue EOFError
|
40
|
+
if @error_on_stop and e.kind_of?(HopePacketTimeoutError)
|
37
41
|
client.terminal
|
38
42
|
server.terminal
|
43
|
+
DIY::Logger.info "Error_on_stop flag opened, stopping..."
|
44
|
+
DIY::Logger.info "Dump mac learn table(size is #{@offline.mac_learner.size})... "
|
45
|
+
DIY::Logger.info @offline.mac_learner.dump
|
39
46
|
break
|
40
47
|
end
|
41
|
-
|
48
|
+
#~ begin
|
49
|
+
#~ @offline.next_pcap
|
50
|
+
#~ server.terminal
|
51
|
+
#~ rescue EOFError
|
52
|
+
#~ client.terminal
|
53
|
+
#~ server.terminal
|
54
|
+
#~ break
|
55
|
+
#~ end
|
56
|
+
#~ client,server = @client, @server
|
42
57
|
rescue EOFError
|
43
58
|
client.terminal
|
44
59
|
server.terminal
|
45
60
|
break
|
61
|
+
ensure
|
62
|
+
#~ client, server = server, client
|
46
63
|
end
|
47
64
|
end
|
48
65
|
DRb.stop_service
|
@@ -50,6 +67,19 @@ module DIY
|
|
50
67
|
stats_result( end_time - start_time, @fail_count )
|
51
68
|
end
|
52
69
|
|
70
|
+
def do_trap
|
71
|
+
Signal.trap("INT") do
|
72
|
+
DIY::Logger.info "bye.."
|
73
|
+
stop
|
74
|
+
exit 0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def stop
|
79
|
+
@client.terminal
|
80
|
+
@server.terminal
|
81
|
+
end
|
82
|
+
|
53
83
|
def one_round( client, server, pkts )
|
54
84
|
@error_flag = nil
|
55
85
|
@round_count = 0 unless @round_count
|
@@ -58,22 +88,32 @@ module DIY
|
|
58
88
|
if pkts.size >= 10
|
59
89
|
DIY::Logger.info "queue size too big: #{pkts.size}, maybe something error"
|
60
90
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
91
|
+
|
92
|
+
recv_pkt_proc_set( pkts )
|
93
|
+
server.ready(&@recv_pkt_proc)
|
94
|
+
|
95
|
+
client_send(client, pkts)
|
96
|
+
wait_recv_ok(pkts)
|
97
|
+
server.terminal
|
98
|
+
end
|
99
|
+
|
100
|
+
# 设置回调入口, 由 worker 通过DRb 远程调用
|
101
|
+
def recv_pkt_proc_set(queue)
|
102
|
+
@queue_keeper = queue
|
103
|
+
# 不重新赋值, 防止 DRb 回收
|
104
|
+
@recv_pkt_proc ||= lambda do |recv_pkt|
|
64
105
|
begin
|
65
|
-
@
|
106
|
+
next if @error_flag # error accur waiting other thread do with it
|
107
|
+
@recv_pkt_keeper = Packet.new(recv_pkt)
|
108
|
+
@strategy.call(@queue_keeper.first, @recv_pkt_keeper, @queue_keeper)
|
66
109
|
rescue DIY::UserError =>e
|
67
110
|
DIY::Logger.warn("UserError Catch: " + e.inspect)
|
68
111
|
e.backtrace.each do |msg|
|
69
112
|
DIY::Logger.info(msg)
|
70
113
|
end
|
71
114
|
@error_flag = e
|
72
|
-
end
|
115
|
+
end
|
73
116
|
end
|
74
|
-
client_send(client, pkts)
|
75
|
-
wait_recv_ok(pkts)
|
76
|
-
server.terminal
|
77
117
|
end
|
78
118
|
|
79
119
|
def client_send(client, pkts)
|
@@ -108,9 +148,13 @@ module DIY
|
|
108
148
|
@timeout = timeout
|
109
149
|
end
|
110
150
|
|
151
|
+
def error_on_stop(*)
|
152
|
+
@error_on_stop = true
|
153
|
+
end
|
154
|
+
|
111
155
|
def stats_result( cost_time, fail_count )
|
112
|
-
DIY::Logger.info "
|
113
|
-
DIY::Logger.info "
|
156
|
+
DIY::Logger.info " Finished in #{cost_time} seconds"
|
157
|
+
DIY::Logger.info " #{offline_result}, #{fail_count} failures"
|
114
158
|
end
|
115
159
|
|
116
160
|
def offline_result
|
data/lib/diy/exceptions.rb
CHANGED
@@ -9,6 +9,10 @@ module DIY
|
|
9
9
|
# 没有报文被指定时
|
10
10
|
class ZeroOfflineError < Error; end
|
11
11
|
|
12
|
+
# 报文分解失败
|
13
|
+
class MacLearnConflictError < Error; end
|
14
|
+
class PacketInvalidError < Error; end
|
15
|
+
|
12
16
|
class UserError < Error
|
13
17
|
def initialize(real_exception)
|
14
18
|
@real_exception = real_exception
|
data/lib/diy/live.rb
CHANGED
@@ -6,7 +6,7 @@ module DIY
|
|
6
6
|
class Live
|
7
7
|
def initialize(device_name)
|
8
8
|
DIY::Logger.info( "Initialize Live: #{device_name}" )
|
9
|
-
@live = FFI::PCap::Live.new(:dev=>device_name, :handler => FFI::PCap::CopyHandler, :promisc => true)
|
9
|
+
@live = FFI::PCap::Live.new(:dev=>device_name, :handler => FFI::PCap::CopyHandler, :promisc => true, :timeout=>1)
|
10
10
|
DIY::Logger.info( "Listen on: #{net} " )
|
11
11
|
@running = false
|
12
12
|
@live.non_blocking= true
|
data/lib/diy/mac_learner.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module DIY
|
2
2
|
class MacLearner
|
3
|
+
BROAD_MAC = "\377" * 6 # ff:ff:ff:ff:ff:ff
|
4
|
+
GROUP_MAC = 1
|
5
|
+
LEARN_TIME = 60 * 5 # five minutes
|
3
6
|
def initialize(default_host = :A)
|
4
7
|
@default_host = default_host
|
5
8
|
@table = {}
|
@@ -13,20 +16,71 @@ module DIY
|
|
13
16
|
end
|
14
17
|
|
15
18
|
def _learn(mac, where)
|
16
|
-
|
19
|
+
# 除去组播与广播
|
20
|
+
return if mac == BROAD_MAC
|
21
|
+
return if mac[0] & GROUP_MAC == 1
|
22
|
+
set(mac, where)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(mac)
|
26
|
+
@table[mac] && @table[mac][0]
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_time(mac)
|
30
|
+
@table[mac] && @table[mac][1]
|
31
|
+
end
|
32
|
+
|
33
|
+
def set(mac, where)
|
34
|
+
time_now = Time.now
|
35
|
+
if @table[mac]
|
36
|
+
if @table[mac][0] != where
|
37
|
+
if (time_now - @table[mac][1]) <= LEARN_TIME
|
38
|
+
raise DIY::MacLearnConflictError, "Found mac learn port confict when set #{Utils.pp_mac(mac)} to #{where}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@table[mac] = [ where, time_now ]
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear(mac)
|
46
|
+
@table[mac] = nil
|
17
47
|
end
|
18
48
|
|
19
49
|
# 报告包所在的端口 A or B
|
20
50
|
# 如果包不在学习表内, 返回缺省端口(默认为A)
|
21
51
|
def tellme(packet)
|
52
|
+
valid!(packet)
|
22
53
|
src_p = src(packet)
|
23
|
-
|
24
|
-
|
54
|
+
dst_p = dst(packet)
|
55
|
+
|
56
|
+
if src_p == dst_p
|
57
|
+
DIY::Logger.debug("Found SRC mac is the same with DST mac: #{Utils.pp(packet)}")
|
58
|
+
#~ where = @default_host
|
59
|
+
#~ _learn(src_p, where)
|
60
|
+
#~ return where
|
61
|
+
end
|
62
|
+
|
63
|
+
if src_p != dst_p && get(src_p) && get(src_p) == get(dst_p)
|
64
|
+
#~ if (get_time(src_p) - get_time(dst_p)).abs <= LEARN_TIME
|
65
|
+
#~ DIY::Logger.warn "Found the same mac learner: packet is #{Utils.pp(packet)}"
|
66
|
+
raise DIY::MacLearnConflictError, "Found mac learn port confict"
|
67
|
+
#~ else
|
68
|
+
#~ cls = get_time(src_p) > get_time(dst_p) ? dst_p : src_p
|
69
|
+
#~ clear(cls)
|
70
|
+
#~ end
|
71
|
+
end
|
72
|
+
|
73
|
+
if get(src_p)
|
74
|
+
where = get(src_p)
|
75
|
+
_learn( src_p, where )
|
76
|
+
elsif get(dst_p)
|
77
|
+
where = other( get(dst_p) )
|
78
|
+
_learn( src_p, where )
|
25
79
|
else
|
26
80
|
where = @default_host
|
27
|
-
_learn(
|
81
|
+
_learn( src_p, where )
|
28
82
|
end
|
29
|
-
_learn(
|
83
|
+
_learn( dst_p, other(where) )
|
30
84
|
where
|
31
85
|
end
|
32
86
|
|
@@ -40,6 +94,20 @@ module DIY
|
|
40
94
|
end
|
41
95
|
end
|
42
96
|
|
97
|
+
def size
|
98
|
+
@table.size
|
99
|
+
end
|
100
|
+
|
101
|
+
def dump
|
102
|
+
ret = "begin dumpping...\n"
|
103
|
+
@table.each do |k, v|
|
104
|
+
mac = Utils.pp_mac(k)
|
105
|
+
ret += "#{mac} -> "
|
106
|
+
ret += "#{v[0]}, "
|
107
|
+
ret += "created at: #{ v[1].strftime("%H:%M:%S") }\n"
|
108
|
+
end
|
109
|
+
ret += "end dump...\n"
|
110
|
+
end
|
43
111
|
|
44
112
|
private
|
45
113
|
def src(packet)
|
@@ -49,5 +117,9 @@ module DIY
|
|
49
117
|
def dst(packet)
|
50
118
|
Utils.dst_mac(packet)
|
51
119
|
end
|
120
|
+
|
121
|
+
def valid!(packet)
|
122
|
+
raise DIY::PacketInvalidError, "packet too small" unless packet.size >= 12
|
123
|
+
end
|
52
124
|
end
|
53
125
|
end
|
data/lib/diy/offline.rb
CHANGED
@@ -6,6 +6,7 @@ module DIY
|
|
6
6
|
def initialize( pcap_files )
|
7
7
|
@pcap_files = [ pcap_files ] if pcap_files.kind_of?(String)
|
8
8
|
@pcap_files ||= pcap_files
|
9
|
+
raise ZeroOfflineError, "no files found" if @pcap_files.size == 0
|
9
10
|
@off = FFI::PCap::Offline.new(@pcap_files[0])
|
10
11
|
|
11
12
|
@ml = MacLearner.new
|
@@ -14,11 +15,27 @@ module DIY
|
|
14
15
|
@position = 0
|
15
16
|
# 记录包在当前文件的位置
|
16
17
|
@num = 0
|
18
|
+
# 记录所有包的个数
|
19
|
+
@total = 0
|
17
20
|
|
18
21
|
@tmp_pcap = nil
|
19
22
|
end
|
20
23
|
|
24
|
+
def mac_learner
|
25
|
+
@ml
|
26
|
+
end
|
27
|
+
|
21
28
|
def nexts
|
29
|
+
begin
|
30
|
+
return _nexts
|
31
|
+
rescue DIY::MacLearnConflictError, DIY::PacketInvalidError =>e
|
32
|
+
DIY::Logger.warn "Found Error when parse #{fullname}: #{e.message}"
|
33
|
+
next_pcap
|
34
|
+
retry
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def _nexts
|
22
39
|
ret = []
|
23
40
|
# 取一个
|
24
41
|
pkt = fetch_one
|
@@ -32,10 +49,14 @@ module DIY
|
|
32
49
|
|
33
50
|
loop do
|
34
51
|
pkt = fetch_one
|
35
|
-
return ret if pkt.nil?
|
52
|
+
return [ret, where] if pkt.nil?
|
53
|
+
#~ if pkt.nil?
|
54
|
+
#~ next_pcap
|
55
|
+
#~ pkt = fetch_one
|
56
|
+
#~ end
|
36
57
|
if @ml.tellme(pkt.content) != where
|
37
58
|
cached(pkt)
|
38
|
-
return ret
|
59
|
+
return [ret, where]
|
39
60
|
else
|
40
61
|
ret << pkt
|
41
62
|
end
|
@@ -55,6 +76,7 @@ module DIY
|
|
55
76
|
def next
|
56
77
|
pkt = @off.next
|
57
78
|
@num += 1
|
79
|
+
@total += 1
|
58
80
|
return nil if pkt.nil?
|
59
81
|
|
60
82
|
return Packet.new(pkt.copy.body, fullname)
|
@@ -100,7 +122,7 @@ module DIY
|
|
100
122
|
end
|
101
123
|
|
102
124
|
def now_size
|
103
|
-
@
|
125
|
+
@total
|
104
126
|
end
|
105
127
|
|
106
128
|
def files_size
|
data/lib/diy/strategy_builder.rb
CHANGED
data/lib/diy/utils.rb
CHANGED
@@ -16,7 +16,7 @@ module DIY
|
|
16
16
|
begin
|
17
17
|
new_pkt = pkt.dup
|
18
18
|
Mu::Pcap::Ethernet.from_bytes(new_pkt).to_s + size_print_str
|
19
|
-
rescue Mu::Pcap::ParseError =>e
|
19
|
+
rescue Mu::Pcap::ParseError, Exception =>e
|
20
20
|
DIY::Logger.debug "parse error from pkt: " + ( pkt[0..10] + "..." ).dump + size_print_str
|
21
21
|
return ( pkt[0..10] + "..." ).dump + size_print_str + "( parse failed )"
|
22
22
|
end
|
@@ -32,6 +32,15 @@ module DIY
|
|
32
32
|
pkt[0..5]
|
33
33
|
end
|
34
34
|
|
35
|
+
def pp_mac(mac)
|
36
|
+
raise "MAC MUST BE 6 sizes" unless mac.size == 6
|
37
|
+
begin
|
38
|
+
'%02x:%02x:%02x:%02x:%02x:%02x' % mac.unpack('C6')
|
39
|
+
rescue ArgumentError
|
40
|
+
mac.dump
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
35
44
|
def wait_until( timeout = 20, &block )
|
36
45
|
timeout(timeout) do
|
37
46
|
loop do
|
@@ -54,6 +63,14 @@ module DIY
|
|
54
63
|
new_bt
|
55
64
|
end
|
56
65
|
|
66
|
+
def print_backtrace(e)
|
67
|
+
DIY::Logger.info "Dump Exception: #{e.class} -> #{e.message}..."
|
68
|
+
e.backtrace.each do |msg|
|
69
|
+
DIY::Logger.info(msg)
|
70
|
+
end
|
71
|
+
DIY::Logger.info("Dump end!")
|
72
|
+
end
|
73
|
+
|
57
74
|
def ary_match(ary, msg)
|
58
75
|
ary.each do |e|
|
59
76
|
return true if /#{Regexp.escape(e)}/ === msg
|
data/lib/diy/version.rb
CHANGED
data/lib/diy/worker.rb
CHANGED
@@ -45,10 +45,14 @@ module DIY
|
|
45
45
|
begin
|
46
46
|
pkt = @queue.pop
|
47
47
|
#~ DIY::Logger.info "callback: #{pkt}"
|
48
|
-
@block.call(pkt) if @block
|
48
|
+
@block.call(pkt) if @start and @block
|
49
49
|
rescue DRb::DRbConnError
|
50
50
|
DIY::Logger.info "closed connection by controller"
|
51
|
+
@start = false
|
51
52
|
@queue.clear
|
53
|
+
rescue RangeError=>e
|
54
|
+
DIY::Utils.print_backtrace(e)
|
55
|
+
raise e
|
52
56
|
end
|
53
57
|
end
|
54
58
|
DIY::Logger.debug "stopped loop callback"
|
@@ -57,6 +61,7 @@ module DIY
|
|
57
61
|
|
58
62
|
#收包
|
59
63
|
def ready(&block)
|
64
|
+
@start = false
|
60
65
|
DIY::Logger.info("start recv pkt")
|
61
66
|
@block = block
|
62
67
|
@queue.clear
|
data/spec/controller_spec.rb
CHANGED
@@ -131,4 +131,15 @@ describe "Controller" do
|
|
131
131
|
lambda { build2.run }.should_not raise_error
|
132
132
|
end
|
133
133
|
|
134
|
+
it "#run with error_on_stop" do
|
135
|
+
build2 = DIY::Builder.new do
|
136
|
+
use DIY::SimpleStrategy.new
|
137
|
+
filter "not tcp"
|
138
|
+
error_on_stop
|
139
|
+
pcapfiles ["helper/http.pcap", "helper/gre.pcap"]
|
140
|
+
timeout 1
|
141
|
+
end
|
142
|
+
lambda { build2.run }.should_not raise_error
|
143
|
+
end
|
144
|
+
|
134
145
|
end
|
Binary file
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe DIY::MacLearner do
|
3
|
+
|
4
|
+
before(:each) do
|
5
|
+
@ml = DIY::MacLearner.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def make_packet(src, dst)
|
9
|
+
src = src * 6
|
10
|
+
dst = dst * 6
|
11
|
+
dst + src
|
12
|
+
end
|
13
|
+
|
14
|
+
it "#tellme new packet" do
|
15
|
+
pkt = make_packet( "\2", "\4")
|
16
|
+
@ml.tellme(pkt).should == :A
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#tellme again packet" do
|
20
|
+
pkt = make_packet( "\2", "\4" )
|
21
|
+
@ml.tellme(pkt)
|
22
|
+
@ml.tellme(pkt).should == :A
|
23
|
+
#~ @ml.instance_variable_get("@table").size.should == 1
|
24
|
+
b_pkt = make_packet( "\4" , "\2" )
|
25
|
+
@ml.tellme(b_pkt).should == :B
|
26
|
+
#~ @ml.instance_variable_get("@table").size.should == 2
|
27
|
+
# 另一个新包
|
28
|
+
c_pkt = make_packet( "\6", "\8" )
|
29
|
+
@ml.tellme(c_pkt).should == :A
|
30
|
+
#~ @ml.instance_variable_get("@table").size.should == 3
|
31
|
+
#~ pp @ml.instance_variable_get("@table")
|
32
|
+
# 目标地址选定的
|
33
|
+
d_pkt = make_packet( "\8", "\2")
|
34
|
+
@ml.tellme(d_pkt).should == :B
|
35
|
+
#~ pp @ml.instance_variable_get("@table")
|
36
|
+
@ml.instance_variable_get("@table")["\8"*6][0].should == :B
|
37
|
+
dd_pkt = make_packet( "\8", "\10")
|
38
|
+
@ml.tellme(dd_pkt).should == :B
|
39
|
+
# 有冲突的
|
40
|
+
e_pkt = make_packet( "\2", "\6" )
|
41
|
+
lambda { @ml.tellme(e_pkt) }.should raise_error(DIY::MacLearnConflictError)
|
42
|
+
# 解决冲突
|
43
|
+
#~ @ml.instance_variable_get("@table")[ "\6"*6 ][1] = Time.now - 10*60
|
44
|
+
#~ @ml.tellme(e_pkt).should == :A
|
45
|
+
#~ @ml.tellme(e_pkt).should == :A
|
46
|
+
|
47
|
+
# 源目的相同的
|
48
|
+
ee_pkt = make_packet( "\2", "\2")
|
49
|
+
lambda { @ml.tellme(ee_pkt) }.should raise_error(DIY::MacLearnConflictError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#tellme group and broad" do
|
53
|
+
@ml.tellme( make_packet("\2", "\377") ).should == :A
|
54
|
+
@ml.tellme( make_packet( "\377", "\2") ).should == :B
|
55
|
+
@ml.instance_variable_get("@table").size.should == 1
|
56
|
+
@ml.tellme( make_packet("\377", "\4") ).should == :A
|
57
|
+
|
58
|
+
@ml.tellme( make_packet("\1", "\4")).should == :A
|
59
|
+
@ml.tellme( make_packet("\6", "\1")).should == :A
|
60
|
+
@ml.tellme( make_packet("\4", "\1")).should == :B
|
61
|
+
end
|
62
|
+
end
|
data/spec/offline_spec.rb
CHANGED
@@ -9,35 +9,41 @@ describe DIY::Offline do
|
|
9
9
|
lambda { offline.next_pcap }.should raise_error(DIY::EOFError)
|
10
10
|
end
|
11
11
|
|
12
|
+
it "no file" do
|
13
|
+
lambda { DIY::Offline.new([]) }.should raise_error(DIY::ZeroOfflineError)
|
14
|
+
end
|
15
|
+
|
12
16
|
it "should get next special first_pkt" do
|
13
17
|
files = [ "helper/app.pcap", "helper/gre.pcap" ]
|
14
18
|
offline = DIY::Offline.new(files)
|
15
19
|
22.times { offline.nexts }
|
16
|
-
offline.nexts.size.should == 1
|
20
|
+
offline.nexts[0].size.should == 1
|
17
21
|
end
|
18
22
|
|
19
23
|
it "should get nexts two" do
|
20
24
|
files = [ "helper/gre.pcap", "helper/app.pcap" ]
|
21
25
|
offline = DIY::Offline.new(files)
|
22
|
-
offline.nexts.size.should == 1
|
23
|
-
offline.nexts.size.should == 2
|
24
|
-
offline.nexts.size.should == 2
|
26
|
+
offline.nexts[0].size.should == 1
|
27
|
+
offline.nexts[0].size.should == 2
|
28
|
+
offline.nexts[0].size.should == 2
|
25
29
|
offline.next_pcap
|
26
|
-
offline.nexts.size.should == 1
|
27
|
-
offline.nexts.size.should == 7
|
30
|
+
offline.nexts[0].size.should == 1
|
31
|
+
offline.nexts[0].size.should == 7
|
28
32
|
lambda { loop do offline.nexts end }.should raise_error(DIY::EOFError)
|
29
33
|
end
|
30
34
|
|
31
35
|
it "should get another two" do
|
32
36
|
files = [ "helper/http.pcap", "helper/gre.pcap" ]
|
33
37
|
offline = DIY::Offline.new(files)
|
34
|
-
offline.nexts.size.should == 1
|
35
|
-
offline.nexts.size.should == 1
|
36
|
-
offline.nexts.size.should == 1
|
38
|
+
offline.nexts[0].size.should == 1
|
39
|
+
offline.nexts[0].size.should == 1
|
40
|
+
offline.nexts[0].size.should == 1
|
37
41
|
#change to next
|
38
|
-
offline.nexts
|
39
|
-
|
40
|
-
|
42
|
+
a = offline.nexts
|
43
|
+
a[0].size.should == 1
|
44
|
+
a[1].should == :A
|
45
|
+
offline.nexts[0].size.should == 2
|
46
|
+
offline.nexts[0].size.should == 2
|
41
47
|
lambda { loop do offline.nexts end }.should raise_error(DIY::EOFError)
|
42
48
|
end
|
43
49
|
|
@@ -46,7 +52,7 @@ describe DIY::Offline do
|
|
46
52
|
600.times do
|
47
53
|
files << "helper/http.pcap"
|
48
54
|
end
|
49
|
-
puts "files size = #{files.size}"
|
55
|
+
#~ puts "files size = #{files.size}"
|
50
56
|
offline = DIY::Offline.new(files)
|
51
57
|
lambda {
|
52
58
|
loop do
|
data/spec/utils_spec.rb
CHANGED
@@ -5,6 +5,11 @@ describe DIY::Utils do
|
|
5
5
|
DIY::Utils.pp('a' * 100).should match(/\(100 sizes\)/)
|
6
6
|
end
|
7
7
|
|
8
|
+
it "#pp parse error" do
|
9
|
+
badtcp = File.open('helper/badtcp.dat', 'rb') { |io| io.read }
|
10
|
+
lambda { puts DIY::Utils.pp(badtcp) }.should_not raise_error
|
11
|
+
end
|
12
|
+
|
8
13
|
it "#pp false" do
|
9
14
|
DIY::Utils.pp('a' * 100, false).should_not match(/\(100 sizes\)/)
|
10
15
|
end
|
@@ -16,5 +21,17 @@ describe DIY::Utils do
|
|
16
21
|
it "#dst_mac" do
|
17
22
|
DIY::Utils.dst_mac( 'a' * 100 ).should == "a" * 6
|
18
23
|
end
|
24
|
+
|
25
|
+
it "#pp_mac" do
|
26
|
+
DIY::Utils.pp_mac( "\377" * 6 ).should == "ff:ff:ff:ff:ff:ff"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "#print_backtrace" do
|
30
|
+
begin
|
31
|
+
raise
|
32
|
+
rescue
|
33
|
+
lambda { DIY::Utils.print_backtrace($!) }.should_not raise_error
|
34
|
+
end
|
35
|
+
end
|
19
36
|
|
20
37
|
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
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
8
|
+
- 6
|
9
|
+
version: 0.3.6
|
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-10-
|
17
|
+
date: 2012-10-22 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
|
@@ -129,6 +128,7 @@ files:
|
|
129
128
|
- spec/controller_spec.rb
|
130
129
|
- spec/device_finder_spec.rb
|
131
130
|
- spec/helper/app.pcap
|
131
|
+
- spec/helper/badtcp.dat
|
132
132
|
- spec/helper/gre.pcap
|
133
133
|
- spec/helper/http.pcap
|
134
134
|
- spec/helper/long.dat
|
@@ -142,12 +142,14 @@ files:
|
|
142
142
|
- spec/helper/vlan.dat
|
143
143
|
- spec/live_spec.rb
|
144
144
|
- spec/logger_spec.rb
|
145
|
+
- spec/mac_learner_spec.rb
|
145
146
|
- spec/mu_parser_spec.rb
|
146
147
|
- spec/offline_spec.rb
|
147
148
|
- spec/packet_spec.rb
|
148
149
|
- spec/spec_helper.rb
|
149
150
|
- spec/utils_spec.rb
|
150
151
|
- spec/worker_spec.rb
|
152
|
+
has_rdoc: true
|
151
153
|
homepage: ""
|
152
154
|
licenses: []
|
153
155
|
|
@@ -161,7 +163,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
163
|
requirements:
|
162
164
|
- - ">="
|
163
165
|
- !ruby/object:Gem::Version
|
164
|
-
hash: 3
|
165
166
|
segments:
|
166
167
|
- 0
|
167
168
|
version: "0"
|
@@ -170,14 +171,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
171
|
requirements:
|
171
172
|
- - ">="
|
172
173
|
- !ruby/object:Gem::Version
|
173
|
-
hash: 3
|
174
174
|
segments:
|
175
175
|
- 0
|
176
176
|
version: "0"
|
177
177
|
requirements: []
|
178
178
|
|
179
179
|
rubyforge_project:
|
180
|
-
rubygems_version: 1.
|
180
|
+
rubygems_version: 1.3.7
|
181
181
|
signing_key:
|
182
182
|
specification_version: 3
|
183
183
|
summary: DIY pcap send and recv
|