packetfu 1.1.11 → 1.1.12.pre

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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +2 -0
  4. data/.travis.yml +2 -3
  5. data/README.md +127 -0
  6. data/examples/100kpackets.rb +11 -10
  7. data/examples/ackscan.rb +4 -1
  8. data/examples/arp.rb +4 -5
  9. data/examples/arphood.rb +5 -4
  10. data/examples/dissect_thinger.rb +10 -7
  11. data/examples/ethernet.rb +8 -3
  12. data/examples/ids.rb +22 -4
  13. data/examples/idsv2.rb +25 -6
  14. data/examples/ifconfig.rb +6 -3
  15. data/examples/new-simple-stats.rb +5 -6
  16. data/examples/packetfu-shell.rb +11 -48
  17. data/examples/pcap2pcapng.rb +32 -0
  18. data/examples/simple-sniffer.rb +9 -4
  19. data/examples/simple-stats.rb +7 -8
  20. data/examples/slammer.rb +2 -2
  21. data/examples/uniqpcap.rb +17 -7
  22. data/lib/packetfu.rb +10 -175
  23. data/lib/packetfu/capture.rb +2 -2
  24. data/lib/packetfu/common.rb +142 -0
  25. data/lib/packetfu/config.rb +8 -8
  26. data/lib/packetfu/inject.rb +3 -3
  27. data/lib/packetfu/packet.rb +22 -18
  28. data/lib/packetfu/pcap.rb +2 -1
  29. data/lib/packetfu/pcapng.rb +37 -0
  30. data/lib/packetfu/pcapng/block.rb +25 -0
  31. data/lib/packetfu/pcapng/epb.rb +112 -0
  32. data/lib/packetfu/pcapng/file.rb +316 -0
  33. data/lib/packetfu/pcapng/idb.rb +125 -0
  34. data/lib/packetfu/pcapng/shb.rb +146 -0
  35. data/lib/packetfu/pcapng/spb.rb +83 -0
  36. data/lib/packetfu/pcapng/unknown_block.rb +60 -0
  37. data/lib/packetfu/protos.rb +3 -0
  38. data/lib/packetfu/protos/arp.rb +10 -10
  39. data/lib/packetfu/protos/icmpv6.rb +131 -0
  40. data/lib/packetfu/protos/icmpv6/header.rb +69 -0
  41. data/lib/packetfu/protos/icmpv6/mixin.rb +14 -0
  42. data/lib/packetfu/protos/ip.rb +4 -5
  43. data/lib/packetfu/protos/ipv6/header.rb +2 -0
  44. data/lib/packetfu/protos/udp.rb +24 -12
  45. data/lib/packetfu/structfu.rb +27 -0
  46. data/lib/packetfu/utils.rb +55 -9
  47. data/lib/packetfu/version.rb +1 -1
  48. data/packetfu.gemspec +13 -7
  49. data/spec/arp_spec.rb +11 -5
  50. data/spec/eth_spec.rb +20 -11
  51. data/spec/fake_packets.rb +28 -0
  52. data/spec/hsrp_spec.rb +15 -0
  53. data/spec/icmp_spec.rb +12 -5
  54. data/spec/icmpv6_spec.rb +98 -0
  55. data/spec/invalid_spec.rb +28 -0
  56. data/spec/ip_spec.rb +10 -5
  57. data/spec/ipv4_icmp.pcap +0 -0
  58. data/spec/ipv4_udp.pcap +0 -0
  59. data/spec/ipv6_icmp.pcap +0 -0
  60. data/spec/ipv6_spec.rb +4 -0
  61. data/spec/ipv6_udp.pcap +0 -0
  62. data/spec/lldp_spec.rb +36 -0
  63. data/spec/octets_spec.rb +43 -0
  64. data/spec/packet_spec.rb +24 -0
  65. data/spec/packetfu_spec.rb +6 -1
  66. data/spec/pcap_spec.rb +286 -0
  67. data/spec/pcapng/epb_spec.rb +81 -0
  68. data/spec/pcapng/file_spec.rb +295 -0
  69. data/spec/pcapng/file_spec_helper.rb +45 -0
  70. data/spec/pcapng/idb_spec.rb +53 -0
  71. data/spec/pcapng/shb_spec.rb +42 -0
  72. data/spec/pcapng/spb_spec.rb +43 -0
  73. data/spec/pcapng/unknown_block_spec.rb +36 -0
  74. data/spec/spec_helper.rb +3 -31
  75. data/spec/tcp_spec.rb +4 -1
  76. data/spec/udp_spec.rb +149 -1
  77. data/spec/utils_spec.rb +98 -15
  78. data/test/pcapng-test/output_be/advanced/test100.pcapng +0 -0
  79. data/test/pcapng-test/output_be/advanced/test100.txt +11 -0
  80. data/test/pcapng-test/output_be/advanced/test101.pcapng +0 -0
  81. data/test/pcapng-test/output_be/advanced/test101.txt +11 -0
  82. data/test/pcapng-test/output_be/advanced/test102.pcapng +0 -0
  83. data/test/pcapng-test/output_be/advanced/test102.txt +14 -0
  84. data/test/pcapng-test/output_be/basic/test001.pcapng +0 -0
  85. data/test/pcapng-test/output_be/basic/test001.txt +9 -0
  86. data/test/pcapng-test/output_be/basic/test002.pcapng +0 -0
  87. data/test/pcapng-test/output_be/basic/test002.txt +7 -0
  88. data/test/pcapng-test/output_be/basic/test003.pcapng +0 -0
  89. data/test/pcapng-test/output_be/basic/test003.txt +8 -0
  90. data/test/pcapng-test/output_be/basic/test004.pcapng +0 -0
  91. data/test/pcapng-test/output_be/basic/test004.txt +9 -0
  92. data/test/pcapng-test/output_be/basic/test005.pcapng +0 -0
  93. data/test/pcapng-test/output_be/basic/test005.txt +9 -0
  94. data/test/pcapng-test/output_be/basic/test006.pcapng +0 -0
  95. data/test/pcapng-test/output_be/basic/test006.txt +9 -0
  96. data/test/pcapng-test/output_be/basic/test007.pcapng +0 -0
  97. data/test/pcapng-test/output_be/basic/test007.txt +9 -0
  98. data/test/pcapng-test/output_be/basic/test008.pcapng +0 -0
  99. data/test/pcapng-test/output_be/basic/test008.txt +9 -0
  100. data/test/pcapng-test/output_be/basic/test009.pcapng +0 -0
  101. data/test/pcapng-test/output_be/basic/test009.txt +9 -0
  102. data/test/pcapng-test/output_be/basic/test010.pcapng +0 -0
  103. data/test/pcapng-test/output_be/basic/test010.txt +9 -0
  104. data/test/pcapng-test/output_be/basic/test011.pcapng +0 -0
  105. data/test/pcapng-test/output_be/basic/test011.txt +10 -0
  106. data/test/pcapng-test/output_be/basic/test012.pcapng +0 -0
  107. data/test/pcapng-test/output_be/basic/test012.txt +10 -0
  108. data/test/pcapng-test/output_be/basic/test013.pcapng +0 -0
  109. data/test/pcapng-test/output_be/basic/test013.txt +9 -0
  110. data/test/pcapng-test/output_be/basic/test014.pcapng +0 -0
  111. data/test/pcapng-test/output_be/basic/test014.txt +9 -0
  112. data/test/pcapng-test/output_be/basic/test015.pcapng +0 -0
  113. data/test/pcapng-test/output_be/basic/test015.txt +9 -0
  114. data/test/pcapng-test/output_be/basic/test016.pcapng +0 -0
  115. data/test/pcapng-test/output_be/basic/test016.txt +11 -0
  116. data/test/pcapng-test/output_be/basic/test017.pcapng +0 -0
  117. data/test/pcapng-test/output_be/basic/test017.txt +9 -0
  118. data/test/pcapng-test/output_be/basic/test018.pcapng +0 -0
  119. data/test/pcapng-test/output_be/basic/test018.txt +12 -0
  120. data/test/pcapng-test/output_be/difficult/test200.pcapng +0 -0
  121. data/test/pcapng-test/output_be/difficult/test200.txt +8 -0
  122. data/test/pcapng-test/output_be/difficult/test201.pcapng +0 -0
  123. data/test/pcapng-test/output_be/difficult/test201.txt +11 -0
  124. data/test/pcapng-test/output_be/difficult/test202.pcapng +0 -0
  125. data/test/pcapng-test/output_be/difficult/test202.txt +14 -0
  126. data/test/pcapng-test/output_le/advanced/test100.pcapng +0 -0
  127. data/test/pcapng-test/output_le/advanced/test100.txt +11 -0
  128. data/test/pcapng-test/output_le/advanced/test101.pcapng +0 -0
  129. data/test/pcapng-test/output_le/advanced/test101.txt +11 -0
  130. data/test/pcapng-test/output_le/advanced/test102.pcapng +0 -0
  131. data/test/pcapng-test/output_le/advanced/test102.txt +14 -0
  132. data/test/pcapng-test/output_le/basic/test001.pcapng +0 -0
  133. data/test/pcapng-test/output_le/basic/test001.txt +9 -0
  134. data/test/pcapng-test/output_le/basic/test002.pcapng +0 -0
  135. data/test/pcapng-test/output_le/basic/test002.txt +7 -0
  136. data/test/pcapng-test/output_le/basic/test003.pcapng +0 -0
  137. data/test/pcapng-test/output_le/basic/test003.txt +8 -0
  138. data/test/pcapng-test/output_le/basic/test004.pcapng +0 -0
  139. data/test/pcapng-test/output_le/basic/test004.txt +9 -0
  140. data/test/pcapng-test/output_le/basic/test005.pcapng +0 -0
  141. data/test/pcapng-test/output_le/basic/test005.txt +9 -0
  142. data/test/pcapng-test/output_le/basic/test006.pcapng +0 -0
  143. data/test/pcapng-test/output_le/basic/test006.txt +9 -0
  144. data/test/pcapng-test/output_le/basic/test007.pcapng +0 -0
  145. data/test/pcapng-test/output_le/basic/test007.txt +9 -0
  146. data/test/pcapng-test/output_le/basic/test008.pcapng +0 -0
  147. data/test/pcapng-test/output_le/basic/test008.txt +9 -0
  148. data/test/pcapng-test/output_le/basic/test009.pcapng +0 -0
  149. data/test/pcapng-test/output_le/basic/test009.txt +9 -0
  150. data/test/pcapng-test/output_le/basic/test010.pcapng +0 -0
  151. data/test/pcapng-test/output_le/basic/test010.txt +9 -0
  152. data/test/pcapng-test/output_le/basic/test011.pcapng +0 -0
  153. data/test/pcapng-test/output_le/basic/test011.txt +10 -0
  154. data/test/pcapng-test/output_le/basic/test012.pcapng +0 -0
  155. data/test/pcapng-test/output_le/basic/test012.txt +10 -0
  156. data/test/pcapng-test/output_le/basic/test013.pcapng +0 -0
  157. data/test/pcapng-test/output_le/basic/test013.txt +9 -0
  158. data/test/pcapng-test/output_le/basic/test014.pcapng +0 -0
  159. data/test/pcapng-test/output_le/basic/test014.txt +9 -0
  160. data/test/pcapng-test/output_le/basic/test015.pcapng +0 -0
  161. data/test/pcapng-test/output_le/basic/test015.txt +9 -0
  162. data/test/pcapng-test/output_le/basic/test016.pcapng +0 -0
  163. data/test/pcapng-test/output_le/basic/test016.txt +11 -0
  164. data/test/pcapng-test/output_le/basic/test017.pcapng +0 -0
  165. data/test/pcapng-test/output_le/basic/test017.txt +9 -0
  166. data/test/pcapng-test/output_le/basic/test018.pcapng +0 -0
  167. data/test/pcapng-test/output_le/basic/test018.txt +12 -0
  168. data/test/pcapng-test/output_le/difficult/test200.pcapng +0 -0
  169. data/test/pcapng-test/output_le/difficult/test200.txt +8 -0
  170. data/test/pcapng-test/output_le/difficult/test201.pcapng +0 -0
  171. data/test/pcapng-test/output_le/difficult/test201.txt +11 -0
  172. data/test/pcapng-test/output_le/difficult/test202.pcapng +0 -0
  173. data/test/pcapng-test/output_le/difficult/test202.txt +14 -0
  174. data/test/sample-ipv6.pcapng +0 -0
  175. data/test/sample-spb.pcapng +0 -0
  176. data/test/sample.pcapng +0 -0
  177. data/test/sample2.pcapng +0 -0
  178. metadata +190 -68
  179. checksums.yaml.gz.sig +0 -0
  180. data.tar.gz.sig +0 -2
  181. data/INSTALL.rdoc +0 -40
  182. data/README.rdoc +0 -64
  183. data/examples/examples.rb +0 -4
  184. data/setup.rb +0 -1586
  185. data/test/func_lldp.rb +0 -25
  186. data/test/ptest.rb +0 -16
  187. data/test/test_eth.rb +0 -93
  188. data/test/test_hsrp.rb +0 -20
  189. data/test/test_invalid.rb +0 -28
  190. data/test/test_octets.rb +0 -36
  191. data/test/test_pcap.rb +0 -211
  192. data/test/test_udp.rb +0 -100
  193. metadata.gz.sig +0 -2
@@ -0,0 +1,125 @@
1
+ require 'stringio'
2
+
3
+ module PacketFu
4
+ module PcapNG
5
+
6
+ # Pcapng::IDB represents a Interface Description Block (IDB) of a pcapng file.
7
+ #
8
+ # == Pcapng::IDB Definition
9
+ # Int32 :type Default: 0x00000001
10
+ # Int32 :block_len
11
+ # Int16 :link_type Default: 1
12
+ # Int16 :reserved Default: 0
13
+ # Int64 :snaplen Default: 0 (no limit)
14
+ # String :options
15
+ # Int32 :block_len2
16
+ class IDB < Struct.new(:type, :block_len, :link_type, :reserved,
17
+ :snaplen, :options, :block_len2)
18
+ include StructFu
19
+ include Block
20
+ attr_accessor :endian
21
+ attr_accessor :section
22
+ attr_accessor :packets
23
+
24
+ MIN_SIZE = 5*4
25
+
26
+ # Option code for if_tsresol option
27
+ OPTION_IF_TSRESOL = 9
28
+
29
+ def initialize(args={})
30
+ @endian = set_endianness(args[:endian] || :little)
31
+ @packets = []
32
+ @options_decoded = false
33
+ init_fields(args)
34
+ super(args[:type], args[:block_len], args[:link_type], args[:reserved],
35
+ args[:snaplen], args[:options], args[:block_len2])
36
+ end
37
+
38
+ # Used by #initialize to set the initial fields
39
+ def init_fields(args={})
40
+ args[:type] = @int32.new(args[:type] || PcapNG::IDB_TYPE.to_i)
41
+ args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
42
+ args[:link_type] = @int16.new(args[:link_type] || 1)
43
+ args[:reserved] = @int16.new(args[:reserved] || 0)
44
+ args[:snaplen] = @int32.new(args[:snaplen] || 0)
45
+ args[:options] = StructFu::String.new(args[:options] || '')
46
+ args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
47
+ args
48
+ end
49
+
50
+ def has_options?
51
+ self[:options].size > 0
52
+ end
53
+
54
+ # Reads a String or a IO to populate the object
55
+ def read(str_or_io)
56
+ if str_or_io.respond_to? :read
57
+ io = str_or_io
58
+ else
59
+ io = StringIO.new(force_binary(str_or_io.to_s))
60
+ end
61
+ return self if io.eof?
62
+
63
+ self[:type].read io.read(4)
64
+ self[:block_len].read io.read(4)
65
+ self[:link_type].read io.read(2)
66
+ self[:reserved].read io.read(2)
67
+ self[:snaplen].read io.read(4)
68
+ self[:options].read io.read(self[:block_len].to_i - MIN_SIZE)
69
+ self[:block_len2].read io.read(4)
70
+
71
+ unless self[:block_len].to_i == self[:block_len2].to_i
72
+ raise InvalidFileError, 'Incoherency in Interface Description Block'
73
+ end
74
+
75
+ self
76
+ end
77
+
78
+ # Add a xPB to this section
79
+ def <<(xpb)
80
+ @packets << xpb
81
+ end
82
+
83
+ # Give timestamp resolution for this interface
84
+ def ts_resol(force=false)
85
+ if @options_decoded and not force
86
+ @ts_resol
87
+ else
88
+ packstr = (@endian == :little) ? 'v' : 'n'
89
+ idx = 0
90
+ options = self[:options]
91
+ opt_code = opt_len = 0
92
+
93
+ while idx < options.length do
94
+ opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
95
+ if opt_code == OPTION_IF_TSRESOL and opt_len == 1
96
+ tsresol = options[idx+4, 1].unpack('C').first
97
+ if tsresol & 0x80 == 0
98
+ @ts_resol = 10 ** -tsresol
99
+ else
100
+ @ts_resol = 2 ** -(tsresol & 0x7f)
101
+ end
102
+
103
+ @options_decoded = true
104
+ return @ts_resol
105
+ else
106
+ idx += 4 + opt_len
107
+ end
108
+ end
109
+
110
+ @options_decoded = true
111
+ @ts_resol = 1E-6 # default value
112
+ end
113
+ end
114
+
115
+ # Return the object as a String
116
+ def to_s
117
+ pad_field :options
118
+ recalc_block_len
119
+ to_a.map(&:to_s).join + @packets.map(&:to_s).join
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,146 @@
1
+ require 'stringio'
2
+
3
+ module PacketFu
4
+ module PcapNG
5
+
6
+ # PcapngSHB represents a Section Header Block (SHB) of a pcapng file.
7
+ #
8
+ # == PcapngSHB Definition
9
+ # Int32 :type Default: 0x0A0D0D0A
10
+ # Int32 :block_len
11
+ # Int32 :magic Default: 0x1A2B3C4D # :big is 0x4D3C2C1A
12
+ # Int16 :ver_major Default: 1
13
+ # Int16 :ver_minor Default: 0
14
+ # Int64 :section_len
15
+ # String :options Default: ''
16
+ # Int32 :block_len2
17
+ class SHB < Struct.new(:type, :block_len, :magic, :ver_major, :ver_minor,
18
+ :section_len, :options, :block_len2)
19
+ include StructFu
20
+ include Block
21
+ attr_accessor :endian
22
+ attr_reader :interfaces
23
+ # Get unsupported blocks given in pcapng file as raw data
24
+ attr_reader :unknown_blocks
25
+
26
+ MAGIC_INT32 = 0x1A2B3C4D
27
+ MAGIC_LITTLE = [MAGIC_INT32].pack('V')
28
+ MAGIC_BIG = [MAGIC_INT32].pack('N')
29
+
30
+ MIN_SIZE = 7*4
31
+ SECTION_LEN_UNDEFINED = 0xffffffff_ffffffff
32
+
33
+ def initialize(args={})
34
+ @endian = set_endianness(args[:endian] || :little)
35
+ @interfaces = []
36
+ @unknown_blocks = []
37
+ init_fields(args)
38
+ super(args[:type], args[:block_len], args[:magic], args[:ver_major],
39
+ args[:ver_minor], args[:section_len], args[:options], args[:block_len2])
40
+ end
41
+
42
+ # Used by #initialize to set the initial fields
43
+ def init_fields(args={})
44
+ args[:type] = @int32.new(args[:type] || PcapNG::SHB_TYPE.to_i)
45
+ args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
46
+ args[:magic] = @int32.new(args[:magic] || MAGIC_INT32)
47
+ args[:ver_major] = @int16.new(args[:ver_major] || 1)
48
+ args[:ver_minor] = @int16.new(args[:ver_minor] || 0)
49
+ args[:section_len] = @int64.new(args[:section_len] || SECTION_LEN_UNDEFINED)
50
+ args[:options] = StructFu::String.new(args[:options] || '')
51
+ args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
52
+ args
53
+ end
54
+
55
+ def has_options?
56
+ self[:options].size > 0
57
+ end
58
+
59
+ # Reads a String or a IO to populate the object
60
+ def read(str_or_io)
61
+ if str_or_io.respond_to? :read
62
+ io = str_or_io
63
+ else
64
+ io = StringIO.new(force_binary(str_or_io.to_s))
65
+ end
66
+ return self if io.eof?
67
+
68
+ type_str = io.read(4)
69
+ unless type_str == PcapNG::SHB_TYPE.to_s
70
+ type = type_str.unpack('H*').join
71
+ raise InvalidFileError, "Incorrect type (#{type})for Section Header Block"
72
+ end
73
+
74
+ block_len_str = io.read(4)
75
+
76
+ magic_str = io.read(4)
77
+ case @endian
78
+ when :little
79
+ case magic_str
80
+ when MAGIC_LITTLE
81
+ when MAGIC_BIG
82
+ force_endianness :big
83
+ else
84
+ raise InvalidFileError, 'Incorrect magic for Section Header Block'
85
+ end
86
+ when :big
87
+ case magic_str
88
+ when MAGIC_BIG
89
+ when MAGIC_LITTLE
90
+ force_endianness :little
91
+ else
92
+ raise InvalidFileError, 'Incorrect magic for Section Header Block'
93
+ end
94
+ end
95
+
96
+ self[:type].read type_str
97
+ self[:block_len].read block_len_str
98
+ self[:magic].read magic_str
99
+ self[:ver_major].read io.read(2)
100
+ self[:ver_minor].read io.read(2)
101
+ self[:section_len].read io.read(8)
102
+ self[:options].read io.read(self[:block_len].to_i - MIN_SIZE)
103
+ self[:block_len2].read io.read(4)
104
+
105
+ unless self[:block_len].to_i == self[:block_len2].to_i
106
+ raise InvalidFileError, 'Incoherency in Section Header Block'
107
+ end
108
+
109
+ self
110
+ end
111
+
112
+ # Add a IDB to this section
113
+ def <<(idb)
114
+ @interfaces << idb
115
+ end
116
+
117
+ # Return the object as a String
118
+ def to_s
119
+ body = @interfaces.map(&:to_s).join
120
+ unless self[:section_len].to_i == SECTION_LEN_UNDEFINED
121
+ self.section_len.value = body.size
122
+ end
123
+ pad_field :options
124
+ recalc_block_len
125
+ to_a.map(&:to_s).join + body
126
+ end
127
+
128
+
129
+ private
130
+
131
+ def force_endianness(endian)
132
+ set_endianness endian
133
+ @endian = endian
134
+ self[:type] = @int32.new(self[:type].to_i)
135
+ self[:block_len] = @int32.new(self[:block_len].to_i)
136
+ self[:magic] = @int32.new(self[:magic].to_i)
137
+ self[:ver_major] = @int16.new(self[:ver_major].to_i)
138
+ self[:ver_minor] = @int16.new(self[:ver_minor].to_i)
139
+ self[:section_len] = @int64.new(self[:section_len].to_i)
140
+ self[:block_len2] = @int32.new(self[:block_len2].to_i)
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+ end
@@ -0,0 +1,83 @@
1
+ require 'stringio'
2
+
3
+ module PacketFu
4
+ module PcapNG
5
+
6
+ # Pcapng::SPB represents a Section Simple Packet Block (SPB) of a pcapng file.
7
+ #
8
+ # == Pcapng::SPB Definition
9
+ # Int32 :type Default: 0x00000003
10
+ # Int32 :block_len
11
+ # Int32 :orig_len
12
+ # String :data
13
+ # Int32 :block_len2
14
+ class SPB < Struct.new(:type, :block_len, :orig_len, :data, :block_len2)
15
+ include StructFu
16
+ include Block
17
+ attr_accessor :endian
18
+ attr_accessor :interface
19
+
20
+ MIN_SIZE = 4*4
21
+
22
+ def initialize(args={})
23
+ @endian = set_endianness(args[:endian] || :little)
24
+ init_fields(args)
25
+ super(args[:type], args[:block_len], args[:orig_len], args[:data],
26
+ args[:block_len2])
27
+ end
28
+
29
+ # Used by #initialize to set the initial fields
30
+ def init_fields(args={})
31
+ args[:type] = @int32.new(args[:type] || PcapNG::SPB_TYPE.to_i)
32
+ args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
33
+ args[:orig_len] = @int32.new(args[:orig_len] || 0)
34
+ args[:data] = StructFu::String.new(args[:data] || '')
35
+ args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
36
+ args
37
+ end
38
+
39
+ def has_options?
40
+ false
41
+ end
42
+
43
+ def read(str_or_io)
44
+ if str_or_io.respond_to? :read
45
+ io = str_or_io
46
+ else
47
+ io = StringIO.new(force_binary(str_or_io.to_s))
48
+ end
49
+ return self if io.eof?
50
+
51
+ self[:type].read io.read(4)
52
+ self[:block_len].read io.read(4)
53
+ self[:orig_len].read io.read(4)
54
+ # Take care of IDB snaplen
55
+ # CAUTION: snaplen == 0 -> no capture limit
56
+ if interface and interface.snaplen.to_i > 0
57
+ data_len = [self[:orig_len].to_i, interface.snaplen.to_i].min
58
+ else
59
+ data_len = self[:orig_len].to_i
60
+ end
61
+ data_pad_len = (4 - (data_len % 4)) % 4
62
+ self[:data].read io.read(data_len)
63
+ io.read data_pad_len
64
+ self[:block_len2].read io.read(4)
65
+
66
+ unless self[:block_len].to_i == self[:block_len2].to_i
67
+ raise InvalidFileError, 'Incoherency in Simple Packet Block'
68
+ end
69
+
70
+ self
71
+ end
72
+
73
+ # Return the object as a String
74
+ def to_s
75
+ pad_field :data
76
+ recalc_block_len
77
+ to_a.map(&:to_s).join
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,60 @@
1
+ require 'stringio'
2
+
3
+ module PacketFu
4
+ module PcapNG
5
+
6
+ # Pcapng::UnknownBlock is used to handle unsupported blocks of a pcapng file.
7
+ class UnknownBlock < Struct.new(:type, :block_len, :body, :block_len2)
8
+ include StructFu
9
+ include Block
10
+ attr_accessor :endian
11
+ attr_accessor :section
12
+
13
+ MIN_SIZE = 12
14
+
15
+ def initialize(args={})
16
+ @endian = set_endianness(args[:endian] || :little)
17
+ init_fields(args)
18
+ super(args[:type], args[:block_len], args[:body], args[:block_len2])
19
+ end
20
+
21
+ # Used by #initialize to set the initial fields
22
+ def init_fields(args={})
23
+ args[:type] = @int32.new(args[:type] || 0)
24
+ args[:block_len] = @int32.new(args[:block_len] || MIN_SIZE)
25
+ args[:body] = StructFu::String.new(args[:body] || '')
26
+ args[:block_len2] = @int32.new(args[:block_len2] || MIN_SIZE)
27
+ args
28
+ end
29
+
30
+ def read(str_or_io)
31
+ if str_or_io.respond_to? :read
32
+ io = str_or_io
33
+ else
34
+ io = StringIO.new(force_binary(str_or_io.to_s))
35
+ end
36
+ return self if io.eof?
37
+
38
+ self[:type].read io.read(4)
39
+ self[:block_len].read io.read(4)
40
+ self[:body].read io.read(self[:block_len].to_i - MIN_SIZE)
41
+ self[:block_len2].read io.read(4)
42
+
43
+ unless self[:block_len].to_i == self[:block_len2].to_i
44
+ raise InvalidFileError, 'Incoherency in Header Block'
45
+ end
46
+
47
+ self
48
+ end
49
+
50
+ # Return the object as a String
51
+ def to_s
52
+ pad_field :body
53
+ recalc_block_len
54
+ to_a.map(&:to_s).join
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ # Picks up all the protocols defined in the protos subdirectory
2
+ path = File.expand_path("lib/packetfu/protos/*.rb")
3
+ Dir.glob(path).each {|file| require file}
@@ -1,7 +1,7 @@
1
1
  # -*- coding: binary -*-
2
+ require 'packetfu/common'
2
3
  require 'packetfu/protos/eth/header'
3
4
  require 'packetfu/protos/eth/mixin'
4
-
5
5
  require 'packetfu/protos/arp/header'
6
6
  require 'packetfu/protos/arp/mixin'
7
7
 
@@ -16,7 +16,7 @@ module PacketFu
16
16
  # arp_pkt.arp_saddr_ip="10.10.10.17" # Your IP address
17
17
  # arp_pkt.arp_daddr_ip="10.10.10.1" # Target IP address
18
18
  # arp_pkt.arp_opcode=1 # Request
19
- #
19
+ #
20
20
  # arp_pkt.to_w('eth0') # Inject on the wire. (requires root)
21
21
  # arp_pkt.to_f('/tmp/arp.pcap') # Write to a file.
22
22
  #
@@ -24,7 +24,7 @@ module PacketFu
24
24
  #
25
25
  # :flavor
26
26
  # Sets the "flavor" of the ARP packet. Choices are currently:
27
- # :windows, :linux, :hp_deskjet
27
+ # :windows, :linux, :hp_deskjet
28
28
  # :eth
29
29
  # A pre-generated EthHeader object. If not specified, a new one will be created.
30
30
  # :arp
@@ -53,23 +53,23 @@ module PacketFu
53
53
 
54
54
  def initialize(args={})
55
55
  @eth_header = EthHeader.new(args).read(args[:eth])
56
- @arp_header = ARPHeader.new(args).read(args[:arp])
56
+ @arp_header = ARPHeader.new(args).read(args[:arp])
57
57
  @eth_header.eth_proto = "\x08\x06"
58
58
  @eth_header.body=@arp_header
59
59
 
60
60
  # Please send more flavors to todb+packetfu@planb-security.net.
61
61
  # Most of these initial fingerprints come from one (1) sample.
62
62
  case (args[:flavor].nil?) ? :nil : args[:flavor].to_s.downcase.intern
63
- when :windows; @arp_header.body = "\x00" * 64 # 64 bytes of padding
64
- when :linux; @arp_header.body = "\x00" * 4 + # 32 bytes of padding
63
+ when :windows; @arp_header.body = "\x00" * 64 # 64 bytes of padding
64
+ when :linux; @arp_header.body = "\x00" * 4 + # 32 bytes of padding
65
65
  "\x00\x07\x5c\x14" + "\x00" * 4 +
66
66
  "\x00\x0f\x83\x34" + "\x00\x0f\x83\x74" +
67
- "\x01\x11\x83\x78" + "\x00\x00\x00\x0c" +
67
+ "\x01\x11\x83\x78" + "\x00\x00\x00\x0c" +
68
68
  "\x00\x00\x00\x00"
69
69
  when :hp_deskjet; # Pads up to 60 bytes.
70
- @arp_header.body = "\xe0\x90\x0d\x6c" +
71
- "\xff\xff\xee\xee" + "\x00" * 4 +
72
- "\xe0\x8f\xfa\x18\x00\x20"
70
+ @arp_header.body = "\xe0\x90\x0d\x6c" +
71
+ "\xff\xff\xee\xee" + "\x00" * 4 +
72
+ "\xe0\x8f\xfa\x18\x00\x20"
73
73
  else; @arp_header.body = "\x00" * 18 # Pads up to 60 bytes.
74
74
  end
75
75