packetfu 1.1.5 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.document +5 -2
  2. data/.gitignore +1 -0
  3. data/LICENSE.txt +1 -1
  4. data/bench/after-2012-07-28.txt +25 -0
  5. data/bench/before-2012-07-28.txt +25 -0
  6. data/bench/benchit.rb +68 -0
  7. data/bench/calc_delta.rb +17 -0
  8. data/bench/octets.rb +22 -0
  9. data/bench/octets_after.txt +8 -0
  10. data/bench/octets_after_refactor.txt +8 -0
  11. data/bench/octets_before.txt +8 -0
  12. data/lib/packetfu.rb +8 -3
  13. data/lib/packetfu/packet.rb +2 -2
  14. data/lib/packetfu/pcap.rb +20 -4
  15. data/lib/packetfu/protos/arp.rb +7 -160
  16. data/lib/packetfu/protos/arp/header.rb +160 -0
  17. data/lib/packetfu/protos/arp/mixin.rb +38 -0
  18. data/lib/packetfu/protos/eth.rb +5 -247
  19. data/lib/packetfu/protos/eth/header.rb +247 -0
  20. data/lib/packetfu/protos/eth/mixin.rb +20 -0
  21. data/lib/packetfu/protos/hsrp.rb +13 -123
  22. data/lib/packetfu/protos/hsrp/header.rb +120 -0
  23. data/lib/packetfu/protos/hsrp/mixin.rb +31 -0
  24. data/lib/packetfu/protos/icmp.rb +10 -97
  25. data/lib/packetfu/protos/icmp/header.rb +93 -0
  26. data/lib/packetfu/protos/icmp/mixin.rb +17 -0
  27. data/lib/packetfu/protos/ip.rb +7 -295
  28. data/lib/packetfu/protos/ip/header.rb +335 -0
  29. data/lib/packetfu/protos/ip/mixin.rb +43 -0
  30. data/lib/packetfu/protos/ipv6.rb +7 -191
  31. data/lib/packetfu/protos/ipv6/header.rb +190 -0
  32. data/lib/packetfu/protos/ipv6/mixin.rb +31 -0
  33. data/lib/packetfu/protos/tcp.rb +13 -939
  34. data/lib/packetfu/protos/tcp/ecn.rb +42 -0
  35. data/lib/packetfu/protos/tcp/flags.rb +83 -0
  36. data/lib/packetfu/protos/tcp/header.rb +307 -0
  37. data/lib/packetfu/protos/tcp/hlen.rb +40 -0
  38. data/lib/packetfu/protos/tcp/mixin.rb +48 -0
  39. data/lib/packetfu/protos/tcp/option.rb +323 -0
  40. data/lib/packetfu/protos/tcp/options.rb +106 -0
  41. data/lib/packetfu/protos/tcp/reserved.rb +42 -0
  42. data/lib/packetfu/protos/udp.rb +12 -110
  43. data/lib/packetfu/protos/udp/header.rb +107 -0
  44. data/lib/packetfu/protos/udp/mixin.rb +23 -0
  45. data/lib/packetfu/utils.rb +24 -24
  46. data/lib/packetfu/version.rb +1 -1
  47. data/packetfu.gemspec +2 -2
  48. data/test/test_ip.rb +0 -19
  49. data/test/test_octets.rb +18 -21
  50. data/test/test_tcp.rb +10 -0
  51. data/test/test_udp.rb +17 -0
  52. metadata +79 -50
@@ -0,0 +1,31 @@
1
+ module PacketFu
2
+ # This Mixin simplifies access to the HSRPHeaders. Mix this in with your
3
+ # packet interface, and it will add methods that essentially delegate to
4
+ # the 'hsrp_header' method (assuming that it is a HSRPHeader object)
5
+ module HSRPHeaderMixin
6
+ def hsrp_version=(v); self.hsrp_header.hsrp_version= v; end
7
+ def hsrp_version; self.hsrp_header.hsrp_version; end
8
+ def hsrp_opcode=(v); self.hsrp_header.hsrp_opcode= v; end
9
+ def hsrp_opcode; self.hsrp_header.hsrp_opcode; end
10
+ def hsrp_state=(v); self.hsrp_header.hsrp_state= v; end
11
+ def hsrp_state; self.hsrp_header.hsrp_state; end
12
+ def hsrp_hellotime=(v); self.hsrp_header.hsrp_hellotime= v; end
13
+ def hsrp_hellotime; self.hsrp_header.hsrp_hellotime; end
14
+ def hsrp_holdtime=(v); self.hsrp_header.hsrp_holdtime= v; end
15
+ def hsrp_holdtime; self.hsrp_header.hsrp_holdtime; end
16
+ def hsrp_priority=(v); self.hsrp_header.hsrp_priority= v; end
17
+ def hsrp_priority; self.hsrp_header.hsrp_priority; end
18
+ def hsrp_group=(v); self.hsrp_header.hsrp_group= v; end
19
+ def hsrp_group; self.hsrp_header.hsrp_group; end
20
+ def hsrp_reserved=(v); self.hsrp_header.hsrp_reserved= v; end
21
+ def hsrp_reserved; self.hsrp_header.hsrp_reserved; end
22
+ def hsrp_addr=(v); self.hsrp_header.hsrp_addr= v; end
23
+ def hsrp_addr; self.hsrp_header.hsrp_addr; end
24
+ def hsrp_vip_readable; self.hsrp_header.hsrp_vip_readable; end
25
+ def hsrp_password_readable; self.hsrp_header.hsrp_password_readable; end
26
+ def hsrp_password; self.hsrp_header.hsrp_password; end
27
+ def hsrp_password=(v); self.hsrp_header.hsrp_password= v; end
28
+ def hsrp_vip; self.hsrp_header.hsrp_vip; end
29
+ def hsrp_vip=(v); self.hsrp_header.hsrp_vip= v; end
30
+ end
31
+ end
@@ -1,97 +1,13 @@
1
- module PacketFu
1
+ require 'packetfu/protos/eth/header'
2
+ require 'packetfu/protos/eth/mixin'
2
3
 
3
- # ICMPHeader is a complete ICMP struct, used in ICMPPacket. ICMP is
4
- # typically used for network administration and connectivity testing.
5
- #
6
- # For more on ICMP packets, see
7
- # http://www.networksorcery.com/enp/protocol/icmp.htm
8
- #
9
- # ==== Header Definition
10
- #
11
- # Int8 :icmp_type # Type
12
- # Int8 :icmp_code # Code
13
- # Int16 :icmp_sum Default: calculated # Checksum
14
- # String :body
15
- class ICMPHeader < Struct.new(:icmp_type, :icmp_code, :icmp_sum, :body)
4
+ require 'packetfu/protos/ip/header'
5
+ require 'packetfu/protos/ip/mixin'
16
6
 
17
- include StructFu
18
-
19
- def initialize(args={})
20
- super(
21
- Int8.new(args[:icmp_type]),
22
- Int8.new(args[:icmp_code]),
23
- Int16.new(args[:icmp_sum] || icmp_calc_sum),
24
- StructFu::String.new.read(args[:body])
25
- )
26
- end
27
-
28
- # Returns the object in string form.
29
- def to_s
30
- self.to_a.map {|x| x.to_s}.join
31
- end
32
-
33
- # Reads a string to populate the object.
34
- def read(str)
35
- force_binary(str)
36
- return self if str.nil?
37
- self[:icmp_type].read(str[0,1])
38
- self[:icmp_code].read(str[1,1])
39
- self[:icmp_sum].read(str[2,2])
40
- self[:body].read(str[4,str.size])
41
- self
42
- end
43
-
44
- # Setter for the type.
45
- def icmp_type=(i); typecast i; end
46
- # Getter for the type.
47
- def icmp_type; self[:icmp_type].to_i; end
48
- # Setter for the code.
49
- def icmp_code=(i); typecast i; end
50
- # Getter for the code.
51
- def icmp_code; self[:icmp_code].to_i; end
52
- # Setter for the checksum. Note, this is calculated automatically with
53
- # icmp_calc_sum.
54
- def icmp_sum=(i); typecast i; end
55
- # Getter for the checksum.
56
- def icmp_sum; self[:icmp_sum].to_i; end
57
-
58
- # Calculates and sets the checksum for the object.
59
- def icmp_calc_sum
60
- checksum = (icmp_type.to_i << 8) + icmp_code.to_i
61
- chk_body = (body.to_s.size % 2 == 0 ? body.to_s : body.to_s + "\x00")
62
- if 1.respond_to? :ord
63
- chk_body.scan(/../).map { |x| (x[0].ord << 8) + x[1].ord }.each { |y| checksum += y }
64
- else
65
- chk_body.scan(/../).map { |x| (x[0] << 8) + x[1] }.each { |y| checksum += y }
66
- end
67
- checksum = checksum % 0xffff
68
- checksum = 0xffff - checksum
69
- checksum == 0 ? 0xffff : checksum
70
- end
71
-
72
- # Recalculates the calculatable fields for ICMP.
73
- def icmp_recalc(arg=:all)
74
- # How silly is this, you can't intern a symbol in ruby 1.8.7pl72?
75
- # I'm this close to monkey patching Symbol so you can force it...
76
- arg = arg.intern if arg.respond_to? :intern
77
- case arg
78
- when :icmp_sum
79
- self.icmp_sum=icmp_calc_sum
80
- when :all
81
- self.icmp_sum=icmp_calc_sum
82
- else
83
- raise ArgumentError, "No such field `#{arg}'"
84
- end
85
- end
86
-
87
- # Readability aliases
88
-
89
- def icmp_sum_readable
90
- "0x%04x" % icmp_sum
91
- end
92
-
93
- end
7
+ require 'packetfu/protos/icmp/header'
8
+ require 'packetfu/protos/icmp/mixin'
94
9
 
10
+ module PacketFu
95
11
  # ICMPPacket is used to construct ICMP Packets. They contain an EthHeader, an IPHeader, and a ICMPHeader.
96
12
  #
97
13
  # == Example
@@ -119,6 +35,9 @@ module PacketFu
119
35
  # :config
120
36
  # A hash of return address details, often the output of Utils.whoami?
121
37
  class ICMPPacket < Packet
38
+ include ::PacketFu::EthHeaderMixin
39
+ include ::PacketFu::IPHeaderMixin
40
+ include ::PacketFu::ICMPHeaderMixin
122
41
 
123
42
  attr_accessor :eth_header, :ip_header, :icmp_header
124
43
 
@@ -133,10 +52,6 @@ module PacketFu
133
52
  def read(str=nil, args={})
134
53
  raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
135
54
  @eth_header.read(str)
136
- @ip_header.read(str[14,str.size])
137
- @eth_header.body = @ip_header
138
- @icmp_header.read(str[14+(@ip_header.ip_hlen),str.size])
139
- @ip_header.body = @icmp_header
140
55
  super(args)
141
56
  self
142
57
  end
@@ -173,7 +88,5 @@ module PacketFu
173
88
  peek_data << "%04x" % self.ip_id
174
89
  peek_data.join
175
90
  end
176
-
177
91
  end
178
-
179
92
  end
@@ -0,0 +1,93 @@
1
+ module PacketFu
2
+ # ICMPHeader is a complete ICMP struct, used in ICMPPacket. ICMP is
3
+ # typically used for network administration and connectivity testing.
4
+ #
5
+ # For more on ICMP packets, see
6
+ # http://www.networksorcery.com/enp/protocol/icmp.htm
7
+ #
8
+ # ==== Header Definition
9
+ #
10
+ # Int8 :icmp_type # Type
11
+ # Int8 :icmp_code # Code
12
+ # Int16 :icmp_sum Default: calculated # Checksum
13
+ # String :body
14
+ class ICMPHeader < Struct.new(:icmp_type, :icmp_code, :icmp_sum, :body)
15
+
16
+ include StructFu
17
+
18
+ def initialize(args={})
19
+ super(
20
+ Int8.new(args[:icmp_type]),
21
+ Int8.new(args[:icmp_code]),
22
+ Int16.new(args[:icmp_sum] || icmp_calc_sum),
23
+ StructFu::String.new.read(args[:body])
24
+ )
25
+ end
26
+
27
+ # Returns the object in string form.
28
+ def to_s
29
+ self.to_a.map {|x| x.to_s}.join
30
+ end
31
+
32
+ # Reads a string to populate the object.
33
+ def read(str)
34
+ force_binary(str)
35
+ return self if str.nil?
36
+ self[:icmp_type].read(str[0,1])
37
+ self[:icmp_code].read(str[1,1])
38
+ self[:icmp_sum].read(str[2,2])
39
+ self[:body].read(str[4,str.size])
40
+ self
41
+ end
42
+
43
+ # Setter for the type.
44
+ def icmp_type=(i); typecast i; end
45
+ # Getter for the type.
46
+ def icmp_type; self[:icmp_type].to_i; end
47
+ # Setter for the code.
48
+ def icmp_code=(i); typecast i; end
49
+ # Getter for the code.
50
+ def icmp_code; self[:icmp_code].to_i; end
51
+ # Setter for the checksum. Note, this is calculated automatically with
52
+ # icmp_calc_sum.
53
+ def icmp_sum=(i); typecast i; end
54
+ # Getter for the checksum.
55
+ def icmp_sum; self[:icmp_sum].to_i; end
56
+
57
+ # Calculates and sets the checksum for the object.
58
+ def icmp_calc_sum
59
+ checksum = (icmp_type.to_i << 8) + icmp_code.to_i
60
+ chk_body = (body.to_s.size % 2 == 0 ? body.to_s : body.to_s + "\x00")
61
+ if 1.respond_to? :ord
62
+ chk_body.scan(/../).map { |x| (x[0].ord << 8) + x[1].ord }.each { |y| checksum += y }
63
+ else
64
+ chk_body.scan(/../).map { |x| (x[0] << 8) + x[1] }.each { |y| checksum += y }
65
+ end
66
+ checksum = checksum % 0xffff
67
+ checksum = 0xffff - checksum
68
+ checksum == 0 ? 0xffff : checksum
69
+ end
70
+
71
+ # Recalculates the calculatable fields for ICMP.
72
+ def icmp_recalc(arg=:all)
73
+ # How silly is this, you can't intern a symbol in ruby 1.8.7pl72?
74
+ # I'm this close to monkey patching Symbol so you can force it...
75
+ arg = arg.intern if arg.respond_to? :intern
76
+ case arg
77
+ when :icmp_sum
78
+ self.icmp_sum=icmp_calc_sum
79
+ when :all
80
+ self.icmp_sum=icmp_calc_sum
81
+ else
82
+ raise ArgumentError, "No such field `#{arg}'"
83
+ end
84
+ end
85
+
86
+ # Readability aliases
87
+
88
+ def icmp_sum_readable
89
+ "0x%04x" % icmp_sum
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,17 @@
1
+ module PacketFu
2
+ # This Mixin simplifies access to the ICMPHeaders. Mix this in with your
3
+ # packet interface, and it will add methods that essentially delegate to
4
+ # the 'icmp_header' method (assuming that it is a ICMPHeader object)
5
+ module ICMPHeaderMixin
6
+ def icmp_type=(v); self.icmp_header.icmp_type= v; end
7
+ def icmp_type; self.icmp_header.icmp_type; end
8
+ def icmp_code=(v); self.icmp_header.icmp_code= v; end
9
+ def icmp_code; self.icmp_header.icmp_code; end
10
+ def icmp_sum=(v); self.icmp_header.icmp_sum= v; end
11
+ def icmp_sum; self.icmp_header.icmp_sum; end
12
+ def icmp_calc_sum; self.icmp_header.icmp_calc_sum; end
13
+ def icmp_recalc(*v); self.icmp_header.icmp_recalc(*v); end
14
+ def icmp_sum_readable; self.icmp_header.icmp_sum_readable; end
15
+ end
16
+ end
17
+
@@ -1,298 +1,10 @@
1
- require 'ipaddr'
2
- module PacketFu
3
-
4
- # Octets implements the addressing scheme for IP.
5
- #
6
- # ==== Header Definition
7
- #
8
- # Int8 :o1
9
- # Int8 :o2
10
- # Int8 :o3
11
- # Int8 :o4
12
- class Octets < Struct.new(:o1, :o2, :o3, :o4)
13
- include StructFu
14
-
15
- def initialize(args={})
16
- super(
17
- Int8.new(args[:o1]),
18
- Int8.new(args[:o2]),
19
- Int8.new(args[:o3]),
20
- Int8.new(args[:o4]))
21
- end
22
-
23
- # Returns the object in string form.
24
- def to_s
25
- self.to_a.map {|x| x.to_s}.join
26
- end
27
-
28
- # Reads a string to populate the object.
29
- def read(str)
30
- force_binary(str)
31
- return self if str.nil?
32
- self[:o1].read str[0,1]
33
- self[:o2].read str[1,1]
34
- self[:o3].read str[2,1]
35
- self[:o4].read str[3,1]
36
- self
37
- end
38
-
39
- # Returns an address in dotted-quad format.
40
- def to_x
41
- ip_str = [o1, o2, o3, o4].map {|x| x.to_i.to_s}.join('.')
42
- IPAddr.new(ip_str).to_s
43
- end
44
-
45
- # Returns an address in numerical format.
46
- def to_i
47
- ip_str = [o1, o2, o3, o4].map {|x| x.to_i.to_s}.join('.')
48
- IPAddr.new(ip_str).to_i
49
- end
50
-
51
- # Set the IP Address by reading a dotted-quad address.
52
- def read_quad(str)
53
- read([IPAddr.new(str).to_i].pack("N"))
54
- end
1
+ require 'packetfu/protos/eth/header'
2
+ require 'packetfu/protos/eth/mixin'
55
3
 
56
- end
57
-
58
- # IPHeader is a complete IP struct, used in IPPacket. Most traffic on most networks today is IP-based.
59
- #
60
- # For more on IP packets, see http://www.networksorcery.com/enp/protocol/ip.htm
61
- #
62
- # ==== Header Definition
63
- #
64
- # Fixnum (4 bits) :ip_v, Default: 4
65
- # Fixnum (4 bits) :ip_hl, Default: 5
66
- # Int8 :ip_tos, Default: 0 # TODO: Break out the bits
67
- # Int16 :ip_len, Default: calculated
68
- # Int16 :ip_id, Default: calculated # IRL, hardly random.
69
- # Int16 :ip_frag, Default: 0 # TODO: Break out the bits
70
- # Int8 :ip_ttl, Default: 0xff # Changes per flavor
71
- # Int8 :ip_proto, Default: 0x01 # TCP: 0x06, UDP 0x11, ICMP 0x01
72
- # Int16 :ip_sum, Default: calculated
73
- # Octets :ip_src
74
- # Octets :ip_dst
75
- # String :body
76
- #
77
- # Note that IPPackets will always be somewhat incorrect upon initalization,
78
- # and want an IPHeader#recalc() to become correct before a
79
- # Packet#to_f or Packet#to_w.
80
- class IPHeader < Struct.new(:ip_v, :ip_hl, :ip_tos, :ip_len,
81
- :ip_id, :ip_frag, :ip_ttl, :ip_proto,
82
- :ip_sum, :ip_src, :ip_dst, :body)
83
- include StructFu
84
-
85
- def initialize(args={})
86
- @random_id = rand(0xffff)
87
- super(
88
- (args[:ip_v] || 4),
89
- (args[:ip_hl] || 5),
90
- Int8.new(args[:ip_tos]),
91
- Int16.new(args[:ip_len] || 20),
92
- Int16.new(args[:ip_id] || ip_calc_id),
93
- Int16.new(args[:ip_frag]),
94
- Int8.new(args[:ip_ttl] || 32),
95
- Int8.new(args[:ip_proto]),
96
- Int16.new(args[:ip_sum] || ip_calc_sum),
97
- Octets.new.read(args[:ip_src] || "\x00\x00\x00\x00"),
98
- Octets.new.read(args[:ip_dst] || "\x00\x00\x00\x00"),
99
- StructFu::String.new.read(args[:body])
100
- )
101
- end
4
+ require 'packetfu/protos/ip/header'
5
+ require 'packetfu/protos/ip/mixin'
102
6
 
103
- # Returns the object in string form.
104
- def to_s
105
- byte_v_hl = [(self.ip_v << 4) + self.ip_hl].pack("C")
106
- byte_v_hl + (self.to_a[2,10].map {|x| x.to_s}.join)
107
- end
108
-
109
- # Reads a string to populate the object.
110
- def read(str)
111
- force_binary(str)
112
- return self if str.nil?
113
- self[:ip_v] = str[0,1].unpack("C").first >> 4
114
- self[:ip_hl] = str[0,1].unpack("C").first.to_i & 0x0f
115
- self[:ip_tos].read(str[1,1])
116
- self[:ip_len].read(str[2,2])
117
- self[:ip_id].read(str[4,2])
118
- self[:ip_frag].read(str[6,2])
119
- self[:ip_ttl].read(str[8,1])
120
- self[:ip_proto].read(str[9,1])
121
- self[:ip_sum].read(str[10,2])
122
- self[:ip_src].read(str[12,4])
123
- self[:ip_dst].read(str[16,4])
124
- self[:body].read(str[20,str.size]) if str.size > 20
125
- self
126
- end
127
-
128
- # Setter for the version.
129
- def ip_v=(i); self[:ip_v] = i.to_i; end
130
- # Getter for the version.
131
- def ip_v; self[:ip_v].to_i; end
132
- # Setter for the header length (divide by 4)
133
- def ip_hl=(i); self[:ip_hl] = i.to_i; end
134
- # Getter for the header length (multiply by 4)
135
- def ip_hl; self[:ip_hl].to_i; end
136
- # Setter for the differentiated services
137
- def ip_tos=(i); typecast i; end
138
- # Getter for the differentiated services
139
- def ip_tos; self[:ip_tos].to_i; end
140
- # Setter for total length.
141
- def ip_len=(i); typecast i; end
142
- # Getter for total length.
143
- def ip_len; self[:ip_len].to_i; end
144
- # Setter for the identication number.
145
- def ip_id=(i); typecast i; end
146
- # Getter for the identication number.
147
- def ip_id; self[:ip_id].to_i; end
148
- # Setter for the fragmentation ID.
149
- def ip_frag=(i); typecast i; end
150
- # Getter for the fragmentation ID.
151
- def ip_frag; self[:ip_frag].to_i; end
152
- # Setter for the time to live.
153
- def ip_ttl=(i); typecast i; end
154
- # Getter for the time to live.
155
- def ip_ttl; self[:ip_ttl].to_i; end
156
- # Setter for the protocol number.
157
- def ip_proto=(i); typecast i; end
158
- # Getter for the protocol number.
159
- def ip_proto; self[:ip_proto].to_i; end
160
- # Setter for the checksum.
161
- def ip_sum=(i); typecast i; end
162
- # Getter for the checksum.
163
- def ip_sum; self[:ip_sum].to_i; end
164
- # Setter for the source IP address.
165
- def ip_src=(i)
166
- case i
167
- when Numeric
168
- self[:ip_src] = Octets.new.read([i].pack("N"))
169
- when Octets
170
- self[:ip_src] = i
171
- else
172
- typecast i
173
- end
174
- end
175
- # Getter for the source IP address.
176
- def ip_src; self[:ip_src].to_i; end
177
- # Setter for the destination IP address.
178
- def ip_dst=(i)
179
- case i
180
- when Numeric
181
- self[:ip_dst] = Octets.new.read([i].pack("N"))
182
- when Octets
183
- self[:ip_dst] = i
184
- else
185
- typecast i
186
- end
187
- end
188
- # Getter for the destination IP address.
189
- def ip_dst; self[:ip_dst].to_i; end
190
-
191
- # Calulcate the true length of the packet.
192
- def ip_calc_len
193
- (ip_hl * 4) + body.to_s.length
194
- end
195
-
196
- # Return the claimed header length
197
- def ip_hlen
198
- (ip_hl * 4)
199
- end
200
-
201
- # Calculate the true checksum of the packet.
202
- # (Yes, this is the long way to do it, but it's e-z-2-read for mathtards like me.)
203
- def ip_calc_sum
204
- checksum = (((self.ip_v << 4) + self.ip_hl) << 8) + self.ip_tos
205
- checksum += self.ip_len
206
- checksum += self.ip_id
207
- checksum += self.ip_frag
208
- checksum += (self.ip_ttl << 8) + self.ip_proto
209
- checksum += (self.ip_src >> 16)
210
- checksum += (self.ip_src & 0xffff)
211
- checksum += (self.ip_dst >> 16)
212
- checksum += (self.ip_dst & 0xffff)
213
- checksum = checksum % 0xffff
214
- checksum = 0xffff - checksum
215
- checksum == 0 ? 0xffff : checksum
216
- end
217
-
218
- # Retrieve the IP ID
219
- def ip_calc_id
220
- @random_id
221
- end
222
-
223
- # Sets a more readable IP address. If you wants to manipulate individual octets,
224
- # (eg, for host scanning in one network), it would be better use ip_src.o1 through
225
- # ip_src.o4 instead.
226
- def ip_saddr=(addr)
227
- self[:ip_src].read_quad(addr)
228
- end
229
-
230
- # Returns a more readable IP source address.
231
- def ip_saddr
232
- self[:ip_src].to_x
233
- end
234
-
235
- # Sets a more readable IP address.
236
- def ip_daddr=(addr)
237
- self[:ip_dst].read_quad(addr)
238
- end
239
-
240
- # Returns a more readable IP destination address.
241
- def ip_daddr
242
- self[:ip_dst].to_x
243
- end
244
-
245
- # Translate various formats of IPv4 Addresses to an array of digits.
246
- def self.octet_array(addr)
247
- if addr.class == String
248
- oa = addr.split('.').collect {|x| x.to_i}
249
- elsif addr.class == Fixnum
250
- oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.')
251
- elsif addr.class == Bignum
252
- oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.')
253
- elsif addr.class == Array
254
- oa = addr
255
- else
256
- raise ArgumentError, "IP Address should be a dotted quad string, an array of ints, or a bignum"
257
- end
258
- end
259
-
260
- # Recalculate the calculated IP fields. Valid arguments are:
261
- # :all
262
- # :ip_len
263
- # :ip_sum
264
- # :ip_id
265
- def ip_recalc(arg=:all)
266
- case arg
267
- when :ip_len
268
- self.ip_len=ip_calc_len
269
- when :ip_sum
270
- self.ip_sum=ip_calc_sum
271
- when :ip_id
272
- @random_id = rand(0xffff)
273
- when :all
274
- self.ip_id= ip_calc_id
275
- self.ip_len= ip_calc_len
276
- self.ip_sum= ip_calc_sum
277
- else
278
- raise ArgumentError, "No such field `#{arg}'"
279
- end
280
- end
281
-
282
- # Readability aliases
283
-
284
- alias :ip_src_readable :ip_saddr
285
- alias :ip_dst_readable :ip_daddr
286
-
287
- def ip_id_readable
288
- "0x%04x" % ip_id
289
- end
290
-
291
- def ip_sum_readable
292
- "0x%04x" % ip_sum
293
- end
294
-
295
- end
7
+ module PacketFu
296
8
 
297
9
  # IPPacket is used to construct IP packets. They contain an EthHeader, an IPHeader, and usually
298
10
  # a transport-layer protocol such as UDPHeader, TCPHeader, or ICMPHeader.
@@ -322,6 +34,8 @@ module PacketFu
322
34
  # :config
323
35
  # A hash of return address details, often the output of Utils.whoami?
324
36
  class IPPacket < Packet
37
+ include ::PacketFu::EthHeaderMixin
38
+ include ::PacketFu::IPHeaderMixin
325
39
 
326
40
  attr_accessor :eth_header, :ip_header
327
41
 
@@ -343,8 +57,6 @@ module PacketFu
343
57
  def read(str=nil, args={})
344
58
  raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
345
59
  @eth_header.read(str)
346
- @ip_header.read(str[14,str.size])
347
- @eth_header.body = @ip_header
348
60
  super(args)
349
61
  self
350
62
  end