DIY-pcap 0.3.5 → 0.3.6
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/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
|