packetman 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d179b4712440f17879c705887caeec69fd857517
4
- data.tar.gz: 7879478eab7e6ecca5d75bff051a5dcad4006465
3
+ metadata.gz: d3819b6864ab2d131bcd29e65c79a02123a1d4b4
4
+ data.tar.gz: 7de18ca9f2f368755393dbc6c0d3b4edfb34a019
5
5
  SHA512:
6
- metadata.gz: 59f189ec8d961cc829938163d21daffea43b4ce14f5b0487d49339ad59abf6cbefabfbb5254e2b949132987ee06df4b584664d9e0d1f7973c33835c1328cd59a
7
- data.tar.gz: 4e6b9134085f93800d07dd8a5e218c48d1c25260832b837c4f2e4fc365545234589232e0af344b8e1687eb90f6aa93d91875a341cfcf1165c1bec3d2341fd3a5
6
+ metadata.gz: f70eb13025b20f23690c6d0b169bb165a7ea035597bd863a5bb1279711eb1f40f54fe393e0611715b980f460e5d899f2ddf92a8ce2806544d70f26d3cf0599e8
7
+ data.tar.gz: 3f2df4b4ee6be9f721195aa661b8ae91bf7aeccd77c8935fa6b51464c872e345206c103af7898342f102ddc55859ddb300642a5420b1e7831b24585f3b378dcb
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Advanced tcpdump and Wireshark capture generator.
4
4
 
5
- [![Code Climate](https://codeclimate.com/github/jescholl/packetman/badges/gpa.svg)](https://codeclimate.com/github/jescholl/packetman) [![Test Coverage](https://codeclimate.com/github/jescholl/packetman/badges/coverage.svg)](https://codeclimate.com/github/jescholl/packetman/coverage) [![Circle CI](https://circleci.com/gh/jescholl/packetman.svg?style=svg)](https://circleci.com/gh/jescholl/packetman)
5
+ [![Gem Version](https://badge.fury.io/rb/packetman.svg)](http://badge.fury.io/rb/packetman) [![Code Climate](https://codeclimate.com/github/jescholl/packetman/badges/gpa.svg)](https://codeclimate.com/github/jescholl/packetman) [![Test Coverage](https://codeclimate.com/github/jescholl/packetman/badges/coverage.svg)](https://codeclimate.com/github/jescholl/packetman/coverage) [![Circle CI](https://circleci.com/gh/jescholl/packetman.svg?style=svg)](https://circleci.com/gh/jescholl/packetman)
6
6
 
7
7
  Packetman is a packet capture filter generator modeled after [Wireshark's String-Matching Capture Filter Generator](https://www.wireshark.org/tools/string-cf.html) but with a lot more features allowing much finer control over the packets you see.
8
8
 
@@ -1,35 +1,29 @@
1
1
  ---
2
- transport:
3
- tcp:
4
- table:
5
- Source Port: 16
6
- Destination Port: 16
7
- Sequence Number: 32
8
- Acknowledgement Number: 32
9
- Data Offset: 4
10
- RESERVED: 3
11
- ECN: 3
12
- Control Bits: 6
13
- Window: 16
14
- Checksum: 16
15
- Urgent Pointer: 16
16
- Options and Padding: 32
17
- payload_query: '((tcp[12:1] & 0xf0) >> 2)'
18
- udp:
19
- table:
20
- Source Port: 16
21
- Destination Port: 16
22
- Length: 16
23
- Checksum: 16
24
- payload_query: 8
25
- icmp:
26
- table:
27
- Type: 8
28
- Code: 8
29
- Checksum: 16
30
- Type Specific Options: 32
31
- application:
32
- http:
33
- transport_protocol: tcp
34
- dns:
35
- transport_protocol: tcp
2
+ tcp:
3
+ table:
4
+ Source Port: 16
5
+ Destination Port: 16
6
+ Sequence Number: 32
7
+ Acknowledgement Number: 32
8
+ Data Offset: 4
9
+ RESERVED: 3
10
+ ECN: 3
11
+ Control Bits: 6
12
+ Window: 16
13
+ Checksum: 16
14
+ Urgent Pointer: 16
15
+ Options and Padding: 32
16
+ payload_query: '((tcp[12:1] & 0xf0) >> 2)'
17
+ udp:
18
+ table:
19
+ Source Port: 16
20
+ Destination Port: 16
21
+ Length: 16
22
+ Checksum: 16
23
+ payload_query: 8
24
+ icmp:
25
+ table:
26
+ Type: 8
27
+ Code: 8
28
+ Checksum: 16
29
+ Type Specific Options: 32
@@ -15,10 +15,5 @@ module Packetman
15
15
  def config!
16
16
  @config = Config.new
17
17
  end
18
-
19
- def user_input(prompt)
20
- puts prompt
21
- gets
22
- end
23
18
  end
24
19
  end
@@ -6,7 +6,7 @@ module Packetman
6
6
  @input = input
7
7
  @radix = radix
8
8
  end
9
-
9
+
10
10
  def desired_length
11
11
  ((@input.length + config.offset)/8.to_f).ceil*8 - config.offset
12
12
  end
@@ -15,7 +15,7 @@ module Packetman
15
15
  (radix.nil?) ? 8 : Math.log2(radix).to_i
16
16
  end
17
17
 
18
- def mask
18
+ def mask_bits
19
19
  shift(@input.scan(/./).map{ |c| mask_chr(c) }.join)
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ module Packetman
27
27
  input.ljust(desired_length, '0')
28
28
  end
29
29
 
30
- def search
30
+ def search_bits
31
31
  shift(@input.scan(/./).map{ |c| bin_chr(c) }.join)
32
32
  end
33
33
 
@@ -54,20 +54,18 @@ module Packetman
54
54
  end
55
55
 
56
56
  def mask_hex
57
- hex_encode(mask)
57
+ hex_encode(mask_bits)
58
58
  end
59
59
 
60
60
  def search_hex
61
- hex_encode(search)
61
+ hex_encode(search_bits)
62
62
  end
63
63
 
64
64
  def hex_encode(bin_str)
65
- bin_str.reverse.scan(/.{1,4}/).map{ |chunk| chunk.reverse.to_i(2).to_s(16) }.reverse.join.scan(/.{1,8}/).map{ |hex| hex.prepend('0x') }
65
+ bin_str.reverse.scan(/.{1,4}/).map{ |chunk| chunk.reverse.to_i(2).to_s(16) }.reverse.join.scan(/.{8}|.{4}|.{2}/).map{ |hex| hex.prepend('0x') }
66
66
  end
67
67
 
68
- def full_bit_length(num, radix=nil)
69
- return num.to_i(radix).to_s(radix).length * bit_density(radix) if radix
70
-
68
+ def bit_length(num)
71
69
  case num
72
70
  when /^0x/
73
71
  $'.length * bit_density(16)
@@ -78,20 +76,18 @@ module Packetman
78
76
  end
79
77
  end
80
78
 
81
- def start_byte(position)
82
- "#{config.payload_query} + #{(config.offset + position)/8}"
79
+ def start_byte(bit_position)
80
+ [config.payload_query, (config.offset + bit_position)/8].compact.join(' + ')
83
81
  end
84
82
 
85
- def to_s
86
- clauses = []
87
- position = 0
88
- search_hex.zip(mask_hex).each_with_index do |(hex_search, hex_mask),i|
89
- search_bit_length = full_bit_length(hex_search)
90
- clauses << "#{config.transport}[#{start_byte(position)}:#{search_bit_length/8}] & #{hex_mask} = #{hex_search}"
91
- position += search_bit_length
92
- end
83
+ def data_address(start_bit, bit_length)
84
+ "#{config.transport}[#{start_byte(start_bit)}:#{bit_length/8}]"
85
+ end
93
86
 
94
- clauses.join(' && ')
87
+ def to_s
88
+ search_hex.zip(mask_hex).map.with_index do |(search, mask),i|
89
+ "#{data_address(i*32, bit_length(search))} & #{mask} = #{search}"
90
+ end.join(' && ')
95
91
  end
96
92
  end
97
93
  end
@@ -2,16 +2,12 @@ require 'optparse'
2
2
 
3
3
  module Packetman
4
4
  class Config
5
- attr_accessor :transport, :application, :offset_units, :offset_type, :allow_wildcards, :radix
5
+ attr_accessor :transport, :application, :use_bytes, :allow_wildcards, :radix, :start_with_transport
6
6
  attr_writer :offset
7
7
 
8
8
  def initialize
9
9
  @transport = "tcp"
10
- @application = "http"
11
10
  @offset = 0
12
- @offset_units = "bits"
13
- @offset_type = "application"
14
- @allow_wildcards = true
15
11
  end
16
12
 
17
13
  def protocols
@@ -19,17 +15,11 @@ module Packetman
19
15
  end
20
16
 
21
17
  def payload_query
22
- case offset_type
23
- when "application"
24
- protocols['transport'][transport.to_s]['payload_query']
25
- else
26
- "0"
27
- end
18
+ protocols[transport]['payload_query'] unless start_with_transport
28
19
  end
29
20
 
30
21
  def offset
31
- case offset_units
32
- when "bytes"
22
+ if use_bytes
33
23
  @offset*8
34
24
  else
35
25
  @offset
@@ -39,14 +29,13 @@ module Packetman
39
29
  def parse_opts
40
30
  @opts ||= OptionParser.new do |opt|
41
31
  opt.banner = "Usage: #{File.basename($PROGRAM_NAME)} [OPTIONS] FILTER_STRING"
42
- opt.on("-t", "--transport [PROTO]", protocols['transport'].keys, "Transport Protocol (#{protocols['transport'].keys.join(',')})") {|v| self.transport = v }
43
- opt.on("-a", "--application [PROTO]", protocols['application'].keys, "Application protocol (#{protocols['application'].keys.join(',')})") { |v| self.application = v }
44
- #opt.on("-a", "--application [PROTO]", String, "Application Protocol (http|dns|icmp)") {|v| self.application = v }
32
+ opt.on("-p", "--protocol [PROTO]", protocols.keys, "Transport Protocol (#{protocols.keys.join(',')})") {|v| self.transport = v }
33
+ opt.on("-t", "--transport", "OFFSET starts at transport header instead of data payload") { |v| self.start_with_transport = v }
45
34
  opt.on("-r", "--radix [RADIX]", Integer, "Treat FILTER_STRING as RADIX instead of String") {|v| self.radix = v; }
46
35
  opt.on("-o", "--offset [OFFSET]", Integer, "Offset in bits") {|v| self.offset = v; }
47
- opt.on("-b", "--byte-offset", "Use 8-bit bytes instead of bits for offset") { |v| self.offset_units = "bytes" }
48
- opt.on("-O", "--offset-type [TYPE]", ["application", "transport"], "Begin offset at the application/transport header.") { |v| self.offset_type = v }
49
- opt.on("--[no-]wildcards", "Allow '?' wildcards") { |v| self.allow_wildcards = v }
36
+ opt.on("-b", "--byte-offset", "Use 8-bit bytes instead of bits for offset") { |v| self.use_bytes = v }
37
+ opt.on("-w", "--wildcards", "Allow '?' wildcards") { |v| self.allow_wildcards = v }
38
+ opt.on("-v", "--version", "Show version") { puts Packetman::VERSION; exit }
50
39
  end
51
40
 
52
41
  @opts.parse!
@@ -54,17 +43,6 @@ module Packetman
54
43
  raise "Invalid command line arguments" if ARGV.size != 1
55
44
 
56
45
  ARGV.pop
57
-
58
-
59
- # if transport !~ /tcp|udp/i ||
60
- # application !~ /http|dns|icmp/i
61
- # raise "invalid options"
62
- # end
63
- #
64
- # if offset_units == :bits
65
- # offset /= 8.to_f
66
- # offset_units = :octets
67
- # end
68
46
  end
69
47
 
70
48
  end
@@ -7,5 +7,9 @@ module Packetman
7
7
  def config
8
8
  Packetman.config
9
9
  end
10
+
11
+ def protocols
12
+ config.protocols
13
+ end
10
14
  end
11
15
  end
@@ -44,7 +44,7 @@ module Packetman
44
44
  def to_s
45
45
  output = horizontal_bar + header_row + horizontal_bar
46
46
 
47
- config.protocols['transport'][config.transport]['table'].each do |label, size|
47
+ protocols[config.transport]['table'].each do |label, size|
48
48
  output += sprintf "%s%.#{cell_size(size)}s", line_v, label.center(cell_size(size))
49
49
  if output.split("\n").last.length == (table_width - 1)
50
50
  output += line_v + "\n"
@@ -1,3 +1,3 @@
1
1
  module Packetman
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Scholl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-20 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,7 +110,6 @@ files:
110
110
  - lib/packetman/table.rb
111
111
  - lib/packetman/version.rb
112
112
  - packetman.gemspec
113
- - packetman_notes
114
113
  homepage: https://github.com/jescholl/packetman
115
114
  licenses:
116
115
  - MIT
@@ -131,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
130
  version: '0'
132
131
  requirements: []
133
132
  rubyforge_project:
134
- rubygems_version: 2.4.5
133
+ rubygems_version: 2.4.5.1
135
134
  signing_key:
136
135
  specification_version: 4
137
136
  summary: Advanced tcpdump and Wiresharp filter generator.
@@ -1,156 +0,0 @@
1
- 7a
2
- 1111010
3
-
4
- #NOTE: I think this is wrong
5
- # also, maybe I don't need to worry about the bits bing aligned on the byte, just on the bit, as long as it's what the user asked for
6
-
7
- hex and string need to be 0 padded on the left
8
- binary needs to fill to the right to hex encode, starting at the offset bit
9
-
10
- Packetman.compose3("0b1111", 3)
11
- 1111
12
- (fill right to ((4+3)/8.to_f).ceil*8 = 8 )
13
- 11110000
14
- (shift mask and search >> 3)
15
- 00011110
16
- 00011110
17
- (sample byte sequence)
18
- 00011111
19
-
20
- Packetman.compose3("0b1111010", 3)
21
- 1111010
22
- (fill right to ((7+3)/8.to_f).ceil*8 = 16)
23
- 11110100 00000000
24
- (shift mask and search >> 3)
25
- 00011111 11000000
26
- 00011110 10000000
27
- (sample byte sequence)
28
- 00011110 10101010
29
-
30
-
31
- Packetman.compose3("0b1111010????????", 3)
32
- 1111010? ???????
33
- (fill right to ((15+3)/8.to_f).ceil*8 = 24)
34
- 1111010? ???????0 00000000
35
- (shift mask and search >> 3)
36
- 00011111 11000000 00000000
37
- 00011110 10000000 00000000
38
- (sample byte sequence)
39
- 00011110 10101010 10101010
40
-
41
- Packetman.compose3("0x123",3)
42
- 100100011
43
- (left fill to 12 first, or manual right fill with 16-12)
44
- (fill right to ((3*4)+3)/8.to_f).ceil*8 = 16)
45
- 00010010 00110000
46
- (shift mask and search >> 3)
47
- 00000011 11111110
48
- 00000010 01000110
49
- (sample byte sequence)
50
- 00000010 01000111
51
-
52
-
53
-
54
-
55
- Packetman.compose3("0xa",3)
56
- "((tcp[0:1] & 0xa) >> 1) = 0xa"
57
- 1010
58
- (generate shifted mask)
59
- 00011110
60
- (generate shifted search)
61
- 00010100
62
- (sample byte sequence)
63
- 10010101
64
-
65
- 0b00011110 & 0b10010101 == 0x14
66
-
67
-
68
-
69
-
70
-
71
-
72
- Packetman.compose3("0b001010010", 3)
73
- "((tcp[0:2] & 0x1ff0) >> 4 = 0x52"
74
- 001010010
75
- (generate shifted mask)
76
- (turn preceding 0s to 1s)
77
- (left shift (((binlen)+3)/8.to_f).ceil*8 - binlen - 3)
78
- 1111111110000
79
- (generate shifted search - same as above)
80
- 0010100100000
81
- (sample byte sequence)
82
- 0010100101010
83
-
84
- 0b0010100101010 & 1111111110000 == 0b0010100100000
85
-
86
-
87
- Packetman.compose3("0b00??1010?111?00010101??10101010?????1010111110???111110101001111010101??????????10100101010100011???????", 5)
88
- 00??1010?111?00010101??10101010?????1010111110???111110101001111010101??????????10100101010100011???????
89
- (generate search str - replace ?s with 0s)
90
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000
91
- (generate shifted mask)
92
- (turn preceding 0s to 1s)
93
- (left shift (((binlen)+5)/8.to_f).ceil*8 - binlen - 5)
94
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000000
95
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000
96
- (generate shifted search - same as above)
97
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000000
98
- (sample byte sequence)
99
- 00011010011100001010111101010101100110101111100101111101010011110101010010101001101001010101000110110100101
100
-
101
- 00011010011100001010111101010101100110101111100101111101010011110101010010101001101001010101000110110100101 &
102
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000000 ==
103
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000000
104
-
105
-
106
- # NOTE
107
-
108
- instead of shifting the product of (mask & input), shift search
109
- this makes the form
110
- "tcp[0:1] & mask = shifted_search"
111
-
112
-
113
- Packetman.compose3("0xa",1)
114
- "((tcp[0:1] & 0x78) >> 3) = 0xa"
115
- 1010
116
- (generate shifted mask)
117
- (left shift (((hexlen*4)+1)/8.to_f).ceil*8 - hexlen*4 - 1)
118
- (use length of mask to determine how much data to take)
119
- 01111000
120
- (sample byte sequence)
121
- 11010101
122
-
123
- (0b01111000 & 0b11010101) >> 3 == 0xa
124
-
125
-
126
- Packetman.compose3("0x123", 3)
127
- "((tcp[0:2] & 0x1ffe) >> 1) = 0x123"
128
- 100100011
129
- (hex: left fill with 1s to hexlen*4)
130
- 111100100011
131
- (generate shifted mask)
132
- (left shift (((hexlen*4)+3)/8.to_f).ceil*8 - hexlen*4 - 3)
133
- (use length of mask to determine how much data to take)
134
- 0001111111111110
135
- (sample byte sequence)
136
- 1000001001000111
137
-
138
- (0b1000001001000111 & 0b0001111111111110) >> 1 == 0x123
139
-
140
- Packetman.compose3("abc", 3)
141
- "((tcp[0:4] & 0x1fffffe0 >> 5) = 0x616263"
142
- 11000010110001001100011
143
- (str: left fill with 1s to len*8)
144
- 111000010110001001100011
145
- (generate shifted mask)
146
- (left shift (((strlen*8)+3)/8.to_f).ceil*8 - strlen*8 - 3)
147
- (use length of mask to determine how much data to take)
148
- 00011111 11111111 11111111 11100000
149
- (sample byte sequence)
150
- 10101100 00101100 01001100 01110101
151
-
152
- (0b10101100001011000100110001110101 & 0b00011111111111111111111111100000) >> 5 == 0b11000010110001001100011
153
-
154
-
155
-
156
-