DIY-pcap 0.4.1 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -4
- data/DIY-pcap.gemspec +17 -17
- data/Gemfile +3 -3
- data/Rakefile +1 -1
- data/lib/DIY-pcap.rb +2 -2
- data/lib/diy/command.rb +7 -1
- data/lib/diy/controller.rb +10 -15
- data/lib/diy/live.rb +9 -2
- data/lib/diy/parser/mu/pcap/ethernet.rb +148 -148
- data/lib/diy/parser/mu/pcap/header.rb +75 -75
- data/lib/diy/parser/mu/pcap/io_pair.rb +67 -67
- data/lib/diy/parser/mu/pcap/io_wrapper.rb +76 -76
- data/lib/diy/parser/mu/pcap/ip.rb +61 -61
- data/lib/diy/parser/mu/pcap/ipv4.rb +257 -257
- data/lib/diy/parser/mu/pcap/ipv6.rb +148 -148
- data/lib/diy/parser/mu/pcap/packet.rb +104 -104
- data/lib/diy/parser/mu/pcap/pkthdr.rb +155 -155
- data/lib/diy/parser/mu/pcap/reader.rb +61 -61
- data/lib/diy/parser/mu/pcap/reader/http_family.rb +170 -170
- data/lib/diy/parser/mu/pcap/sctp.rb +367 -367
- data/lib/diy/parser/mu/pcap/sctp/chunk.rb +123 -123
- data/lib/diy/parser/mu/pcap/sctp/chunk/data.rb +134 -134
- data/lib/diy/parser/mu/pcap/sctp/chunk/init.rb +100 -100
- data/lib/diy/parser/mu/pcap/sctp/chunk/init_ack.rb +68 -68
- data/lib/diy/parser/mu/pcap/sctp/parameter.rb +110 -110
- data/lib/diy/parser/mu/pcap/sctp/parameter/ip_address.rb +48 -48
- data/lib/diy/parser/mu/pcap/stream_packetizer.rb +72 -72
- data/lib/diy/parser/mu/pcap/tcp.rb +505 -505
- data/lib/diy/parser/mu/pcap/udp.rb +69 -69
- data/lib/diy/parser/mu/scenario/pcap.rb +172 -172
- data/lib/diy/parser/mu/scenario/pcap/fields.rb +50 -50
- data/lib/diy/parser/mu/scenario/pcap/rtp.rb +71 -71
- data/lib/diy/parser/pcap.rb +109 -109
- data/lib/diy/version.rb +1 -1
- metadata +7 -9
@@ -1,123 +1,123 @@
|
|
1
|
-
# http://www.mudynamics.com
|
2
|
-
# http://labs.mudynamics.com
|
3
|
-
# http://www.pcapr.net
|
4
|
-
|
5
|
-
module Mu
|
6
|
-
class Pcap
|
7
|
-
class SCTP
|
8
|
-
|
9
|
-
class Chunk < Packet
|
10
|
-
attr_accessor :type, :flags, :size
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
super
|
14
|
-
|
15
|
-
@type = 0
|
16
|
-
@flags = 0
|
17
|
-
@size = 0
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.from_bytes bytes
|
21
|
-
# Basic validation
|
22
|
-
Pcap.assert(bytes.length >= 4,
|
23
|
-
"Truncated chunk header: 4 > #{bytes.length}")
|
24
|
-
|
25
|
-
# Read chunk header
|
26
|
-
type, flags, size = bytes.unpack('CCn')
|
27
|
-
|
28
|
-
# Validate chunk size
|
29
|
-
Pcap.assert(bytes.length >= size,
|
30
|
-
"Truncated chunk: #{size} set, #{bytes.length} available")
|
31
|
-
|
32
|
-
# Create chunk based on type
|
33
|
-
case type
|
34
|
-
when CHUNK_DATA
|
35
|
-
chunk = Data.from_bytes(flags, size, bytes[4..-1])
|
36
|
-
when CHUNK_INIT
|
37
|
-
chunk = Init.from_bytes(flags, size, bytes[4..-1])
|
38
|
-
when CHUNK_INIT_ACK
|
39
|
-
chunk = InitAck.from_bytes(flags, size, bytes[4..-1])
|
40
|
-
when CHUNK_SACK
|
41
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
42
|
-
when CHUNK_HEARTBEAT
|
43
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
44
|
-
when CHUNK_HEARTBEAT_ACK
|
45
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
46
|
-
when CHUNK_ABORT
|
47
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
48
|
-
when CHUNK_SHUTDOWN
|
49
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
50
|
-
when CHUNK_SHUTDOWN_ACK
|
51
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
52
|
-
when CHUNK_ERROR
|
53
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
54
|
-
when CHUNK_COOKIE_ECHO
|
55
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
56
|
-
when CHUNK_COOKIE_ACK
|
57
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
58
|
-
when CHUNK_ECNE
|
59
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
60
|
-
when CHUNK_CWR
|
61
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
62
|
-
when CHUNK_SHUTDOWN_COMPLETE
|
63
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
64
|
-
when CHUNK_AUTH
|
65
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
66
|
-
when CHUNK_ASCONF_ACK
|
67
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
68
|
-
when CHUNK_PADDING
|
69
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
70
|
-
when CHUNK_FORWARD_TSN
|
71
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
72
|
-
when CHUNK_ASCONF
|
73
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
74
|
-
else
|
75
|
-
chunk = dummy_chunk(type, flags, size, bytes)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Return the result
|
79
|
-
return chunk
|
80
|
-
end
|
81
|
-
|
82
|
-
def write io, ip
|
83
|
-
header = [@type, @flags, @size].pack('CCn')
|
84
|
-
|
85
|
-
# Write Chunk header followed by the payload
|
86
|
-
io.write(header)
|
87
|
-
io.write(@payload_raw)
|
88
|
-
end
|
89
|
-
|
90
|
-
def padded_size
|
91
|
-
if 0 == @size % 4
|
92
|
-
return @size
|
93
|
-
else
|
94
|
-
return (@size + 4 - (@size % 4))
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def to_s
|
99
|
-
return "chunk(%d, %d, %d)" % [@type, @flags, @size]
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.dummy_chunk type, flags, size, bytes
|
103
|
-
# Create new dummy chunk
|
104
|
-
chunk = Chunk.new
|
105
|
-
chunk.type = type
|
106
|
-
chunk.flags = flags
|
107
|
-
chunk.size = size
|
108
|
-
|
109
|
-
# Save the payload
|
110
|
-
chunk.payload_raw = chunk.payload = bytes[4..chunk.padded_size]
|
111
|
-
|
112
|
-
# Return the result
|
113
|
-
return chunk
|
114
|
-
end
|
115
|
-
end # class Chunk
|
116
|
-
|
117
|
-
end # class SCTP
|
118
|
-
end # class Pcap
|
119
|
-
end # module Mu
|
120
|
-
|
121
|
-
require 'mu/pcap/sctp/chunk/data'
|
122
|
-
require 'mu/pcap/sctp/chunk/init'
|
123
|
-
require 'mu/pcap/sctp/chunk/init_ack'
|
1
|
+
# http://www.mudynamics.com
|
2
|
+
# http://labs.mudynamics.com
|
3
|
+
# http://www.pcapr.net
|
4
|
+
|
5
|
+
module Mu
|
6
|
+
class Pcap
|
7
|
+
class SCTP
|
8
|
+
|
9
|
+
class Chunk < Packet
|
10
|
+
attr_accessor :type, :flags, :size
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
super
|
14
|
+
|
15
|
+
@type = 0
|
16
|
+
@flags = 0
|
17
|
+
@size = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_bytes bytes
|
21
|
+
# Basic validation
|
22
|
+
Pcap.assert(bytes.length >= 4,
|
23
|
+
"Truncated chunk header: 4 > #{bytes.length}")
|
24
|
+
|
25
|
+
# Read chunk header
|
26
|
+
type, flags, size = bytes.unpack('CCn')
|
27
|
+
|
28
|
+
# Validate chunk size
|
29
|
+
Pcap.assert(bytes.length >= size,
|
30
|
+
"Truncated chunk: #{size} set, #{bytes.length} available")
|
31
|
+
|
32
|
+
# Create chunk based on type
|
33
|
+
case type
|
34
|
+
when CHUNK_DATA
|
35
|
+
chunk = Data.from_bytes(flags, size, bytes[4..-1])
|
36
|
+
when CHUNK_INIT
|
37
|
+
chunk = Init.from_bytes(flags, size, bytes[4..-1])
|
38
|
+
when CHUNK_INIT_ACK
|
39
|
+
chunk = InitAck.from_bytes(flags, size, bytes[4..-1])
|
40
|
+
when CHUNK_SACK
|
41
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
42
|
+
when CHUNK_HEARTBEAT
|
43
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
44
|
+
when CHUNK_HEARTBEAT_ACK
|
45
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
46
|
+
when CHUNK_ABORT
|
47
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
48
|
+
when CHUNK_SHUTDOWN
|
49
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
50
|
+
when CHUNK_SHUTDOWN_ACK
|
51
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
52
|
+
when CHUNK_ERROR
|
53
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
54
|
+
when CHUNK_COOKIE_ECHO
|
55
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
56
|
+
when CHUNK_COOKIE_ACK
|
57
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
58
|
+
when CHUNK_ECNE
|
59
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
60
|
+
when CHUNK_CWR
|
61
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
62
|
+
when CHUNK_SHUTDOWN_COMPLETE
|
63
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
64
|
+
when CHUNK_AUTH
|
65
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
66
|
+
when CHUNK_ASCONF_ACK
|
67
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
68
|
+
when CHUNK_PADDING
|
69
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
70
|
+
when CHUNK_FORWARD_TSN
|
71
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
72
|
+
when CHUNK_ASCONF
|
73
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
74
|
+
else
|
75
|
+
chunk = dummy_chunk(type, flags, size, bytes)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the result
|
79
|
+
return chunk
|
80
|
+
end
|
81
|
+
|
82
|
+
def write io, ip
|
83
|
+
header = [@type, @flags, @size].pack('CCn')
|
84
|
+
|
85
|
+
# Write Chunk header followed by the payload
|
86
|
+
io.write(header)
|
87
|
+
io.write(@payload_raw)
|
88
|
+
end
|
89
|
+
|
90
|
+
def padded_size
|
91
|
+
if 0 == @size % 4
|
92
|
+
return @size
|
93
|
+
else
|
94
|
+
return (@size + 4 - (@size % 4))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
return "chunk(%d, %d, %d)" % [@type, @flags, @size]
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.dummy_chunk type, flags, size, bytes
|
103
|
+
# Create new dummy chunk
|
104
|
+
chunk = Chunk.new
|
105
|
+
chunk.type = type
|
106
|
+
chunk.flags = flags
|
107
|
+
chunk.size = size
|
108
|
+
|
109
|
+
# Save the payload
|
110
|
+
chunk.payload_raw = chunk.payload = bytes[4..chunk.padded_size]
|
111
|
+
|
112
|
+
# Return the result
|
113
|
+
return chunk
|
114
|
+
end
|
115
|
+
end # class Chunk
|
116
|
+
|
117
|
+
end # class SCTP
|
118
|
+
end # class Pcap
|
119
|
+
end # module Mu
|
120
|
+
|
121
|
+
require 'mu/pcap/sctp/chunk/data'
|
122
|
+
require 'mu/pcap/sctp/chunk/init'
|
123
|
+
require 'mu/pcap/sctp/chunk/init_ack'
|
@@ -1,134 +1,134 @@
|
|
1
|
-
# http://www.mudynamics.com
|
2
|
-
# http://labs.mudynamics.com
|
3
|
-
# http://www.pcapr.net
|
4
|
-
|
5
|
-
module Mu
|
6
|
-
class Pcap
|
7
|
-
class SCTP
|
8
|
-
class Chunk
|
9
|
-
|
10
|
-
class Data < Chunk
|
11
|
-
FLAG_LAST_SEG = 0x01
|
12
|
-
FLAG_FIRST_SEG = 0x02
|
13
|
-
FLAG_UNORDERED = 0x04
|
14
|
-
|
15
|
-
attr_accessor :tsn, :sid, :ssn, :ppid
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
super
|
19
|
-
|
20
|
-
@type = CHUNK_DATA
|
21
|
-
@tsn = 0
|
22
|
-
@sid = 0
|
23
|
-
@ssn = 0
|
24
|
-
@ppid = 0
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.from_bytes flags, size, bytes
|
28
|
-
# Basic validation
|
29
|
-
Pcap.assert(bytes.length >= 12,
|
30
|
-
"Truncated data chunk header: 12 > #{bytes.length}")
|
31
|
-
|
32
|
-
# Read init chunk header
|
33
|
-
tsn, sid, ssn, ppid = bytes.unpack('NnnN')
|
34
|
-
|
35
|
-
# Create data chunk
|
36
|
-
data = Data.new
|
37
|
-
data.flags = flags
|
38
|
-
data.size = size
|
39
|
-
data.tsn = tsn
|
40
|
-
data.sid = sid
|
41
|
-
data.ssn = ssn
|
42
|
-
data.ppid = ppid
|
43
|
-
|
44
|
-
# Save the payload
|
45
|
-
data.payload_raw = data.payload = bytes[12..size - 5]
|
46
|
-
|
47
|
-
# Return the result
|
48
|
-
return data
|
49
|
-
end
|
50
|
-
|
51
|
-
def write io, ip
|
52
|
-
chunk_header = [@type, @flags, @size].pack('CCn')
|
53
|
-
data_header = [@tsn, @sid, @ssn, @ppid].pack('NnnN')
|
54
|
-
|
55
|
-
# Write Chunk header followed by the Data chunk header and payload
|
56
|
-
io.write(chunk_header)
|
57
|
-
io.write(data_header)
|
58
|
-
io.write(@payload_raw)
|
59
|
-
|
60
|
-
# Write padding, if necessary
|
61
|
-
if size < padded_size
|
62
|
-
(padded_size - size).times do
|
63
|
-
io.write("\x00")
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def ordered?
|
69
|
-
if 0 == @flags[2]
|
70
|
-
return true
|
71
|
-
else
|
72
|
-
return false
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def first_segment?
|
77
|
-
if 1 == @flags[1] and 0 == @flags[0]
|
78
|
-
return true
|
79
|
-
else
|
80
|
-
return false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def last_segment?
|
85
|
-
if 0 == @flags[1] and 1 == @flags[0]
|
86
|
-
return true
|
87
|
-
else
|
88
|
-
return false
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def complete_segment?
|
93
|
-
if 1 == @flags[1] and 1 == @flags[0]
|
94
|
-
return true
|
95
|
-
else
|
96
|
-
return false
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def to_s
|
101
|
-
flags_s = '['
|
102
|
-
|
103
|
-
if ordered?
|
104
|
-
flags_s += 'ordered, '
|
105
|
-
else
|
106
|
-
flags_s += 'unordered, '
|
107
|
-
end
|
108
|
-
|
109
|
-
if complete_segment?
|
110
|
-
flags_s += 'complete segment'
|
111
|
-
elsif first_segment?
|
112
|
-
flags_s += 'first segment'
|
113
|
-
elsif last_segment?
|
114
|
-
flags_s += 'last segment'
|
115
|
-
else
|
116
|
-
flags_s += 'middle segment'
|
117
|
-
end
|
118
|
-
|
119
|
-
flags_s += ']'
|
120
|
-
|
121
|
-
return "data(%s, %d, %d, %d, %d, %d, %s)" % [flags_s,
|
122
|
-
@size,
|
123
|
-
@tsn,
|
124
|
-
@sid,
|
125
|
-
@ssn,
|
126
|
-
@ppid,
|
127
|
-
@payload.inspect]
|
128
|
-
end
|
129
|
-
end # class Data
|
130
|
-
|
131
|
-
end # class Chunk
|
132
|
-
end # class SCTP
|
133
|
-
end # class Pcap
|
134
|
-
end # module Mu
|
1
|
+
# http://www.mudynamics.com
|
2
|
+
# http://labs.mudynamics.com
|
3
|
+
# http://www.pcapr.net
|
4
|
+
|
5
|
+
module Mu
|
6
|
+
class Pcap
|
7
|
+
class SCTP
|
8
|
+
class Chunk
|
9
|
+
|
10
|
+
class Data < Chunk
|
11
|
+
FLAG_LAST_SEG = 0x01
|
12
|
+
FLAG_FIRST_SEG = 0x02
|
13
|
+
FLAG_UNORDERED = 0x04
|
14
|
+
|
15
|
+
attr_accessor :tsn, :sid, :ssn, :ppid
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
super
|
19
|
+
|
20
|
+
@type = CHUNK_DATA
|
21
|
+
@tsn = 0
|
22
|
+
@sid = 0
|
23
|
+
@ssn = 0
|
24
|
+
@ppid = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.from_bytes flags, size, bytes
|
28
|
+
# Basic validation
|
29
|
+
Pcap.assert(bytes.length >= 12,
|
30
|
+
"Truncated data chunk header: 12 > #{bytes.length}")
|
31
|
+
|
32
|
+
# Read init chunk header
|
33
|
+
tsn, sid, ssn, ppid = bytes.unpack('NnnN')
|
34
|
+
|
35
|
+
# Create data chunk
|
36
|
+
data = Data.new
|
37
|
+
data.flags = flags
|
38
|
+
data.size = size
|
39
|
+
data.tsn = tsn
|
40
|
+
data.sid = sid
|
41
|
+
data.ssn = ssn
|
42
|
+
data.ppid = ppid
|
43
|
+
|
44
|
+
# Save the payload
|
45
|
+
data.payload_raw = data.payload = bytes[12..size - 5]
|
46
|
+
|
47
|
+
# Return the result
|
48
|
+
return data
|
49
|
+
end
|
50
|
+
|
51
|
+
def write io, ip
|
52
|
+
chunk_header = [@type, @flags, @size].pack('CCn')
|
53
|
+
data_header = [@tsn, @sid, @ssn, @ppid].pack('NnnN')
|
54
|
+
|
55
|
+
# Write Chunk header followed by the Data chunk header and payload
|
56
|
+
io.write(chunk_header)
|
57
|
+
io.write(data_header)
|
58
|
+
io.write(@payload_raw)
|
59
|
+
|
60
|
+
# Write padding, if necessary
|
61
|
+
if size < padded_size
|
62
|
+
(padded_size - size).times do
|
63
|
+
io.write("\x00")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ordered?
|
69
|
+
if 0 == @flags[2]
|
70
|
+
return true
|
71
|
+
else
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def first_segment?
|
77
|
+
if 1 == @flags[1] and 0 == @flags[0]
|
78
|
+
return true
|
79
|
+
else
|
80
|
+
return false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def last_segment?
|
85
|
+
if 0 == @flags[1] and 1 == @flags[0]
|
86
|
+
return true
|
87
|
+
else
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def complete_segment?
|
93
|
+
if 1 == @flags[1] and 1 == @flags[0]
|
94
|
+
return true
|
95
|
+
else
|
96
|
+
return false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_s
|
101
|
+
flags_s = '['
|
102
|
+
|
103
|
+
if ordered?
|
104
|
+
flags_s += 'ordered, '
|
105
|
+
else
|
106
|
+
flags_s += 'unordered, '
|
107
|
+
end
|
108
|
+
|
109
|
+
if complete_segment?
|
110
|
+
flags_s += 'complete segment'
|
111
|
+
elsif first_segment?
|
112
|
+
flags_s += 'first segment'
|
113
|
+
elsif last_segment?
|
114
|
+
flags_s += 'last segment'
|
115
|
+
else
|
116
|
+
flags_s += 'middle segment'
|
117
|
+
end
|
118
|
+
|
119
|
+
flags_s += ']'
|
120
|
+
|
121
|
+
return "data(%s, %d, %d, %d, %d, %d, %s)" % [flags_s,
|
122
|
+
@size,
|
123
|
+
@tsn,
|
124
|
+
@sid,
|
125
|
+
@ssn,
|
126
|
+
@ppid,
|
127
|
+
@payload.inspect]
|
128
|
+
end
|
129
|
+
end # class Data
|
130
|
+
|
131
|
+
end # class Chunk
|
132
|
+
end # class SCTP
|
133
|
+
end # class Pcap
|
134
|
+
end # module Mu
|