packet_via_dmem 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -2
- data/lib/packet_via_dmem.rb +8 -67
- data/lib/packet_via_dmem/cli.rb +14 -5
- data/lib/packet_via_dmem/packet.rb +54 -0
- data/lib/packet_via_dmem/packets.rb +33 -0
- data/lib/packet_via_dmem/received.rb +38 -0
- data/lib/packet_via_dmem/sent.rb +30 -0
- data/packet_via_dmem.gemspec +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef2cad0361ca93db4bedc5a4ba817c091bb7caae
|
4
|
+
data.tar.gz: 3a15a48484054db79bba1014ec008d5147e9427c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d54500d03397a67b058c9cf94cbf5b74efa81800a2a87eb2231691a223509a5584178470c603a972d49d4c630bf65818cc6f098ab3bc41d79060eca75778c66
|
7
|
+
data.tar.gz: a06ffee647a7f386a716c9bddf9bfa10dd796d691d7f02e1446d7bba2f5046f2bfcf6c921215eaf690de68a964ac78addddf9a54e7ba76217239ee599cc43d95
|
data/README.md
CHANGED
@@ -58,15 +58,22 @@ To capture say packets with IP address 10.11.12.13
|
|
58
58
|
% ./bin/packet-via-dmem --help
|
59
59
|
usage: ./bin/packet-via-dmem [options]
|
60
60
|
-d, --debug turn on debugging
|
61
|
+
--headers print headers to stderr
|
62
|
+
-o, --original print original frames
|
61
63
|
-r, --received pop BYTES from received frames, default 6
|
62
64
|
-s, --sent pop BYTES from senti frames, default is not to show sent frames
|
63
65
|
-h, --help
|
64
|
-
%
|
65
66
|
|
66
67
|
## Library
|
67
68
|
require 'packet_via_dmem'
|
68
69
|
dmem = PacketViaDMEM.new
|
69
|
-
|
70
|
+
packets = dmem.parse File.read(ARGF[0])
|
71
|
+
packets.each do |capture|
|
72
|
+
p capture.type
|
73
|
+
p capture.packet
|
74
|
+
p capture.header
|
75
|
+
p capture.original
|
76
|
+
end
|
70
77
|
|
71
78
|
|
72
79
|
## Header format
|
@@ -85,6 +92,12 @@ To capture say packets with IP address 10.11.12.13
|
|
85
92
|
|
86
93
|
* Sixth byte is perhaps source NPU? If it is zero, we get what seems to be trash (internal stuff)
|
87
94
|
|
95
|
+
* value of fift+sixth seems to sometime indicate special cases
|
96
|
+
* 0x1fff - Packet missing everything before IPv4 TTL, yet has some extra. I saw BGP from control-plane with this and also TCP/SMB2 with Seq1, it was transit, but perhaps it was via ARP resolve/punt and thus coming from control-plane?
|
97
|
+
* 0x2000 - BFD frames from control-plane, missing L2
|
98
|
+
* 0x4220 - Was traffic for AE/802.1AX, no L2 included, but something extra aadded
|
99
|
+
* 0x8000 - I need to pop 14 bytes extra
|
100
|
+
|
88
101
|
* 00 (22) (33) (44) \<src\> (66)
|
89
102
|
* 10 (22) (33) (44) \<si\> \<ze\> \<src\> (66)
|
90
103
|
|
data/lib/packet_via_dmem.rb
CHANGED
@@ -16,92 +16,31 @@ class PacketViaDMEM
|
|
16
16
|
class Error < StandardError; end
|
17
17
|
|
18
18
|
def initialize opts={}
|
19
|
-
@received
|
20
|
-
@sent
|
19
|
+
@received = opts.delete :received
|
20
|
+
@sent = opts.delete :sent
|
21
21
|
@received ||= HEADER_SIZE[:received]
|
22
|
-
@sc
|
22
|
+
@sc = StringScanner.new ''
|
23
23
|
end
|
24
24
|
|
25
25
|
def parse str
|
26
|
-
packets =
|
27
|
-
headers = []
|
26
|
+
packets = Packets.new
|
28
27
|
@sc.string = str
|
29
28
|
while @sc.scan_until PACKET
|
30
29
|
match = @sc.matched.split(/\s+/)
|
31
30
|
type = match.first.downcase.to_sym
|
32
|
-
next if type == :received and (not @received or @received < 1)
|
33
|
-
next if type == :sent and (not @sent or @sent < 1)
|
34
31
|
@sc.scan_until(/\n/) if type == :received
|
35
32
|
pkt = ''
|
36
33
|
while @sc.match?(/^0x/)
|
37
34
|
pkt << @sc.scan_until(/\n/).strip
|
38
35
|
end
|
39
36
|
pkt = parse_packet pkt
|
40
|
-
|
41
|
-
header = pkt[0..pop-1]
|
42
|
-
pkt = pkt[pop..-1]
|
43
|
-
if pkt
|
44
|
-
packets << '000000 ' + [push, pkt].flatten.join(' ')
|
45
|
-
headers << header.join(' ')
|
46
|
-
end
|
37
|
+
packets.add pkt, type
|
47
38
|
end
|
48
|
-
|
39
|
+
packets
|
49
40
|
end
|
50
41
|
|
51
42
|
private
|
52
43
|
|
53
|
-
def get_pop_push type, pkt
|
54
|
-
if type == :sent
|
55
|
-
get_pop_push_sent pkt
|
56
|
-
else
|
57
|
-
get_pop_push_received pkt
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def get_pop_push_sent pkt
|
62
|
-
pop, push = nil, []
|
63
|
-
case pkt.first.to_i(16)
|
64
|
-
when 0x00 # we're sending to fabric
|
65
|
-
# we may send MAC to fabric,byte 6, 7, 9, 11, 21?
|
66
|
-
if pkt[5].to_i(16) == 0xf0 # we don't send MAC to fabric
|
67
|
-
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_mpls]
|
68
|
-
pop = 24
|
69
|
-
else # we send MAC to fabric
|
70
|
-
pop = 33
|
71
|
-
end
|
72
|
-
when 0x08 then pop = 13
|
73
|
-
else pop = @sent
|
74
|
-
end
|
75
|
-
[pop, push]
|
76
|
-
end
|
77
|
-
|
78
|
-
def get_pop_push_received pkt
|
79
|
-
pop, push = 6, []
|
80
|
-
offset = 0
|
81
|
-
case pkt.first.to_i(16)
|
82
|
-
when 0x00 then offset = 0 #1,2,3,4,5,6
|
83
|
-
when 0x10 then offset = 2 #1,2,3,4,7,8,5,6
|
84
|
-
else pop = @received
|
85
|
-
end
|
86
|
-
pop += offset
|
87
|
-
case pkt[4+offset..5+offset].join.to_i(16)
|
88
|
-
when 0x8000 then pop+=14
|
89
|
-
when 0x4220 # ae/802.1AX is special, no L2 received, but something extra
|
90
|
-
pop+=18
|
91
|
-
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4]
|
92
|
-
when 0x2000 # these were BFD packets from control-plane
|
93
|
-
pop+=5
|
94
|
-
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4]
|
95
|
-
# some BGP packets like this
|
96
|
-
# also SMB2 TCP Seq1 (maybe post ARP from control-plane?)
|
97
|
-
# they are misssing all of ipv4 headers before TTL
|
98
|
-
when 0x1f00
|
99
|
-
pop+=7
|
100
|
-
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4] + FAKE[:ipv4]
|
101
|
-
end
|
102
|
-
[pop, push]
|
103
|
-
end
|
104
|
-
|
105
44
|
def parse_packet pkt
|
106
45
|
pkt = pkt.gsub(/0x/, '')
|
107
46
|
pkt = pkt.gsub(/\s+/, '')
|
@@ -109,3 +48,5 @@ class PacketViaDMEM
|
|
109
48
|
pkt
|
110
49
|
end
|
111
50
|
end
|
51
|
+
|
52
|
+
require_relative 'packet_via_dmem/packets'
|
data/lib/packet_via_dmem/cli.rb
CHANGED
@@ -20,17 +20,26 @@ class PacketViaDMEM
|
|
20
20
|
rescue
|
21
21
|
raise InvalidFile, "unable to read #{file}"
|
22
22
|
end
|
23
|
-
packets
|
24
|
-
|
25
|
-
|
23
|
+
packets = PacketViaDMEM.new(:received=>@opts[:received], :sent=>@opts[:sent]).parse file
|
24
|
+
count = 0
|
25
|
+
packets.each do |pkt|
|
26
|
+
next if pkt.type == :received and (not @opts[:received] or @opts[:received] < 1)
|
27
|
+
next if pkt.type == :sent and (not @opts[:sent] or @opts[:sent] < 1)
|
28
|
+
packet = @opts.original? ? pkt.pretty_original : pkt.pretty_packet
|
29
|
+
puts '### Packet %d ###' % [count+=1]
|
30
|
+
puts packet
|
31
|
+
$stderr.puts pkt.header.join(' ') if @opts.headers?
|
32
|
+
puts
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
private
|
29
37
|
|
30
38
|
def opts_parse
|
31
39
|
Slop.parse do |o|
|
32
|
-
o.bool '-d', '--debug',
|
33
|
-
o.bool
|
40
|
+
o.bool '-d', '--debug', 'turn on debugging'
|
41
|
+
o.bool '--headers', 'print headers to stderr'
|
42
|
+
o.bool '-o', '--original', 'print original frames'
|
34
43
|
o.int '-r', '--received', "pop BYTES from received frames, default #{PacketViaDMEM::HEADER_SIZE[:received]}", :default=>PacketViaDMEM::HEADER_SIZE[:received]
|
35
44
|
o.int '-s', '--sent', "pop BYTES from senti frames, default is not to show sent frames"
|
36
45
|
o.on '-h', '--help' do puts o; exit; end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class PacketViaDMEM
|
2
|
+
|
3
|
+
class Packet
|
4
|
+
class NoPayload < Error; end
|
5
|
+
attr_reader :type, :packet, :header, :original
|
6
|
+
|
7
|
+
def pop bytes
|
8
|
+
@original[bytes..-1]
|
9
|
+
end
|
10
|
+
|
11
|
+
def header_and_packet packet, pop_bytes, push_bytes
|
12
|
+
header = packet[0..pop_bytes-1]
|
13
|
+
payload = packet[pop_bytes..-1]
|
14
|
+
raise NoPayload, "no payload for #{packet}" unless payload
|
15
|
+
payload = push_bytes + payload
|
16
|
+
[header, payload]
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
pretty_packet
|
21
|
+
end
|
22
|
+
|
23
|
+
def pretty_packet
|
24
|
+
pretty @packet
|
25
|
+
end
|
26
|
+
|
27
|
+
def pretty_original
|
28
|
+
pretty @original
|
29
|
+
end
|
30
|
+
|
31
|
+
def pretty packet
|
32
|
+
offset = -16
|
33
|
+
out = ''
|
34
|
+
packet.each_slice(16) do |slice|
|
35
|
+
hex, str = [], []
|
36
|
+
slice.each_slice(8) do |subslice|
|
37
|
+
hex << subslice
|
38
|
+
str << subslice.inject(' ') do |r, s|
|
39
|
+
int = s.to_i(16)
|
40
|
+
r + ((int > 31 and int < 127) ? int.chr : '.')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
hex << [] if not hex[1]
|
44
|
+
hex.each do |h|
|
45
|
+
(8-h.size).times { h << ' ' }
|
46
|
+
end
|
47
|
+
out << "%04x %s %s %s \n" % [offset+=16, hex[0].join(' '), hex[1].to_a.join(' '), str.join(' ')]
|
48
|
+
end
|
49
|
+
out
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'packet'
|
2
|
+
require_relative 'received'
|
3
|
+
require_relative 'sent'
|
4
|
+
|
5
|
+
class PacketViaDMEM
|
6
|
+
class Packets
|
7
|
+
include Enumerable
|
8
|
+
class InvalidType < Error; end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@packets = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def add packet, type
|
15
|
+
packet = case type
|
16
|
+
when :received then Received.new packet
|
17
|
+
when :sent then Sent.new packet
|
18
|
+
else raise InvalidType, "#{type} not valid packet type"
|
19
|
+
end
|
20
|
+
@packets << packet
|
21
|
+
rescue Packet::NoPayload
|
22
|
+
end
|
23
|
+
|
24
|
+
def each &block
|
25
|
+
@packets.each { |packet| block.call packet }
|
26
|
+
end
|
27
|
+
|
28
|
+
def size
|
29
|
+
@packets.size
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class PacketViaDMEM
|
2
|
+
class Received < Packet
|
3
|
+
|
4
|
+
def initialize packet
|
5
|
+
@type = :received
|
6
|
+
@original = packet
|
7
|
+
@header, @packet = parse_packet packet
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def parse_packet pkt
|
13
|
+
pop, push = 6, []
|
14
|
+
offset = 0
|
15
|
+
case pkt.first.to_i(16)
|
16
|
+
when 0x00 then offset = 0 #1,2,3,4,5,6
|
17
|
+
when 0x10 then offset = 2 #1,2,3,4,7,8,5,6
|
18
|
+
end
|
19
|
+
pop += offset
|
20
|
+
case pkt[4+offset..5+offset].join.to_i(16)
|
21
|
+
when 0x8000 then pop+=14
|
22
|
+
when 0x4220 # ae/802.1AX is special, no L2 received, but something extra
|
23
|
+
pop+=18
|
24
|
+
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4]
|
25
|
+
when 0x2000 # these were BFD packets from control-plane
|
26
|
+
pop+=5
|
27
|
+
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4]
|
28
|
+
# some BGP packets like this
|
29
|
+
# also SMB2 TCP Seq1 (maybe post ARP from control-plane?)
|
30
|
+
# they are misssing all of ipv4 headers before TTL
|
31
|
+
when 0x1f00
|
32
|
+
pop+=7
|
33
|
+
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_ipv4] + FAKE[:ipv4]
|
34
|
+
end
|
35
|
+
header_and_packet pkt, pop, push
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class PacketViaDMEM
|
2
|
+
class Sent < Packet
|
3
|
+
|
4
|
+
def initialize packet
|
5
|
+
@type = :sent
|
6
|
+
@original = packet
|
7
|
+
@header, @packet = parse_packet packet
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def parse_packet pkt
|
13
|
+
pop, push = nil, []
|
14
|
+
case pkt.first.to_i(16)
|
15
|
+
when 0x00 # we're sending to fabric
|
16
|
+
# we may send MAC to fabric,byte 6, 7, 9, 11, 21?
|
17
|
+
if pkt[5].to_i(16) == 0xf0 # we don't send MAC to fabric
|
18
|
+
push = FAKE[:dmac] + FAKE[:smac] + FAKE[:etype_mpls]
|
19
|
+
pop = 24
|
20
|
+
else # we send MAC to fabric
|
21
|
+
pop = 33
|
22
|
+
end
|
23
|
+
when 0x08 then pop = 13
|
24
|
+
else pop = @sent
|
25
|
+
end
|
26
|
+
header_and_packet pkt, pop, push
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/packet_via_dmem.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packet_via_dmem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Saku Ytti
|
@@ -40,6 +40,10 @@ files:
|
|
40
40
|
- bin/packet-via-dmem
|
41
41
|
- lib/packet_via_dmem.rb
|
42
42
|
- lib/packet_via_dmem/cli.rb
|
43
|
+
- lib/packet_via_dmem/packet.rb
|
44
|
+
- lib/packet_via_dmem/packets.rb
|
45
|
+
- lib/packet_via_dmem/received.rb
|
46
|
+
- lib/packet_via_dmem/sent.rb
|
43
47
|
- packet_via_dmem.gemspec
|
44
48
|
homepage: http://github.com/ytti/packet_via_dmem
|
45
49
|
licenses:
|