packetfu 1.1.8 → 1.1.9

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 (84) hide show
  1. data/README.rdoc +11 -12
  2. data/bench/octets.rb +9 -9
  3. data/examples/100kpackets.rb +13 -12
  4. data/examples/ackscan.rb +17 -16
  5. data/examples/arp.rb +36 -35
  6. data/examples/arphood.rb +37 -36
  7. data/examples/dissect_thinger.rb +7 -6
  8. data/examples/ethernet.rb +1 -0
  9. data/examples/examples.rb +1 -0
  10. data/examples/ifconfig.rb +1 -0
  11. data/examples/new-simple-stats.rb +24 -23
  12. data/examples/packetfu-shell.rb +26 -25
  13. data/examples/simple-sniffer.rb +10 -9
  14. data/examples/simple-stats.rb +24 -23
  15. data/examples/slammer.rb +4 -3
  16. data/lib/packetfu.rb +128 -127
  17. data/lib/packetfu/capture.rb +170 -169
  18. data/lib/packetfu/config.rb +53 -52
  19. data/lib/packetfu/inject.rb +57 -56
  20. data/lib/packetfu/packet.rb +529 -528
  21. data/lib/packetfu/pcap.rb +580 -579
  22. data/lib/packetfu/protos/arp.rb +91 -90
  23. data/lib/packetfu/protos/arp/header.rb +159 -158
  24. data/lib/packetfu/protos/arp/mixin.rb +37 -36
  25. data/lib/packetfu/protos/eth.rb +45 -44
  26. data/lib/packetfu/protos/eth/header.rb +244 -243
  27. data/lib/packetfu/protos/eth/mixin.rb +4 -3
  28. data/lib/packetfu/protos/hsrp.rb +70 -69
  29. data/lib/packetfu/protos/hsrp/header.rb +108 -107
  30. data/lib/packetfu/protos/hsrp/mixin.rb +30 -29
  31. data/lib/packetfu/protos/icmp.rb +72 -71
  32. data/lib/packetfu/protos/icmp/header.rb +83 -82
  33. data/lib/packetfu/protos/icmp/mixin.rb +15 -14
  34. data/lib/packetfu/protos/invalid.rb +50 -49
  35. data/lib/packetfu/protos/ip.rb +70 -69
  36. data/lib/packetfu/protos/ip/header.rb +292 -291
  37. data/lib/packetfu/protos/ip/mixin.rb +41 -40
  38. data/lib/packetfu/protos/ipv6.rb +51 -50
  39. data/lib/packetfu/protos/ipv6/header.rb +189 -188
  40. data/lib/packetfu/protos/ipv6/mixin.rb +30 -29
  41. data/lib/packetfu/protos/lldp.rb +3 -1
  42. data/lib/packetfu/protos/lldp/header.rb +1 -0
  43. data/lib/packetfu/protos/lldp/mixin.rb +1 -0
  44. data/lib/packetfu/protos/tcp.rb +177 -176
  45. data/lib/packetfu/protos/tcp/ecn.rb +36 -35
  46. data/lib/packetfu/protos/tcp/flags.rb +75 -74
  47. data/lib/packetfu/protos/tcp/header.rb +269 -268
  48. data/lib/packetfu/protos/tcp/hlen.rb +33 -32
  49. data/lib/packetfu/protos/tcp/mixin.rb +47 -46
  50. data/lib/packetfu/protos/tcp/option.rb +322 -321
  51. data/lib/packetfu/protos/tcp/options.rb +96 -95
  52. data/lib/packetfu/protos/tcp/reserved.rb +36 -35
  53. data/lib/packetfu/protos/udp.rb +117 -116
  54. data/lib/packetfu/protos/udp/header.rb +92 -91
  55. data/lib/packetfu/protos/udp/mixin.rb +4 -3
  56. data/lib/packetfu/structfu.rb +281 -280
  57. data/lib/packetfu/utils.rb +211 -208
  58. data/lib/packetfu/version.rb +42 -41
  59. data/packetfu.gemspec +1 -1
  60. data/spec/ethpacket_spec.rb +48 -48
  61. data/spec/packet_spec.rb +57 -57
  62. data/spec/packet_subclasses_spec.rb +8 -8
  63. data/spec/packetfu_spec.rb +59 -59
  64. data/spec/structfu_spec.rb +268 -268
  65. data/spec/tcp_spec.rb +75 -75
  66. data/test/all_tests.rb +13 -13
  67. data/test/func_lldp.rb +3 -3
  68. data/test/ptest.rb +2 -2
  69. data/test/test_arp.rb +116 -116
  70. data/test/test_capture.rb +45 -45
  71. data/test/test_eth.rb +68 -68
  72. data/test/test_hsrp.rb +9 -9
  73. data/test/test_icmp.rb +52 -52
  74. data/test/test_inject.rb +18 -18
  75. data/test/test_invalid.rb +16 -16
  76. data/test/test_ip.rb +36 -36
  77. data/test/test_ip6.rb +48 -48
  78. data/test/test_octets.rb +21 -21
  79. data/test/test_packet.rb +154 -154
  80. data/test/test_pcap.rb +170 -170
  81. data/test/test_structfu.rb +97 -97
  82. data/test/test_tcp.rb +320 -320
  83. data/test/test_udp.rb +76 -76
  84. metadata +2 -2
@@ -1,106 +1,107 @@
1
+ # -*- coding: binary -*-
1
2
  require 'packetfu/protos/tcp/option'
2
3
 
3
4
  module PacketFu
4
5
 
5
- class TcpOptions < Array
6
+ class TcpOptions < Array
6
7
 
7
- include StructFu
8
+ include StructFu
8
9
 
9
- # If args[:pad] is set, the options line is automatically padded out
10
- # with NOPs.
11
- def to_s(args={})
12
- opts = self.map {|x| x.to_s}.join
13
- if args[:pad]
14
- unless (opts.size % 4).zero?
15
- (4 - (opts.size % 4)).times { opts << "\x01" }
16
- end
17
- end
18
- opts
19
- end
10
+ # If args[:pad] is set, the options line is automatically padded out
11
+ # with NOPs.
12
+ def to_s(args={})
13
+ opts = self.map {|x| x.to_s}.join
14
+ if args[:pad]
15
+ unless (opts.size % 4).zero?
16
+ (4 - (opts.size % 4)).times { opts << "\x01" }
17
+ end
18
+ end
19
+ opts
20
+ end
20
21
 
21
- # Reads a string to populate the object.
22
- def read(str)
23
- self.clear
24
- PacketFu.force_binary(str)
25
- return self if(!str.respond_to? :to_s || str.nil?)
26
- i = 0
27
- while i < str.to_s.size
28
- this_opt = case str[i,1].unpack("C").first
29
- when 0; ::PacketFu::TcpOption::EOL.new
30
- when 1; ::PacketFu::TcpOption::NOP.new
31
- when 2; ::PacketFu::TcpOption::MSS.new
32
- when 3; ::PacketFu::TcpOption::WS.new
33
- when 4; ::PacketFu::TcpOption::SACKOK.new
34
- when 5; ::PacketFu::TcpOption::SACK.new
35
- when 6; ::PacketFu::TcpOption::ECHO.new
36
- when 7; ::PacketFu::TcpOption::ECHOREPLY.new
37
- when 8; ::PacketFu::TcpOption::TS.new
38
- else; ::PacketFu::TcpOption.new
39
- end
40
- this_opt.read str[i,str.size]
41
- unless this_opt.has_optlen?
42
- this_opt.value = nil
43
- this_opt.optlen = nil
44
- end
45
- self << this_opt
46
- i += this_opt.sz
47
- end
48
- self
49
- end
22
+ # Reads a string to populate the object.
23
+ def read(str)
24
+ self.clear
25
+ PacketFu.force_binary(str)
26
+ return self if(!str.respond_to? :to_s || str.nil?)
27
+ i = 0
28
+ while i < str.to_s.size
29
+ this_opt = case str[i,1].unpack("C").first
30
+ when 0; ::PacketFu::TcpOption::EOL.new
31
+ when 1; ::PacketFu::TcpOption::NOP.new
32
+ when 2; ::PacketFu::TcpOption::MSS.new
33
+ when 3; ::PacketFu::TcpOption::WS.new
34
+ when 4; ::PacketFu::TcpOption::SACKOK.new
35
+ when 5; ::PacketFu::TcpOption::SACK.new
36
+ when 6; ::PacketFu::TcpOption::ECHO.new
37
+ when 7; ::PacketFu::TcpOption::ECHOREPLY.new
38
+ when 8; ::PacketFu::TcpOption::TS.new
39
+ else; ::PacketFu::TcpOption.new
40
+ end
41
+ this_opt.read str[i,str.size]
42
+ unless this_opt.has_optlen?
43
+ this_opt.value = nil
44
+ this_opt.optlen = nil
45
+ end
46
+ self << this_opt
47
+ i += this_opt.sz
48
+ end
49
+ self
50
+ end
50
51
 
51
- # Decode parses the TcpOptions object's member options, and produces a
52
- # human-readable string by iterating over each element's decode() function.
53
- # If TcpOptions elements were not initially created as TcpOptions, an
54
- # attempt will be made to convert them.
55
- #
56
- # The output of decode is suitable as input for TcpOptions#encode.
57
- def decode
58
- decoded = self.map do |x|
59
- if x.kind_of? TcpOption
60
- x.decode
61
- else
62
- x = TcpOptions.new.read(x).decode
63
- end
64
- end
65
- decoded.join(",")
66
- end
52
+ # Decode parses the TcpOptions object's member options, and produces a
53
+ # human-readable string by iterating over each element's decode() function.
54
+ # If TcpOptions elements were not initially created as TcpOptions, an
55
+ # attempt will be made to convert them.
56
+ #
57
+ # The output of decode is suitable as input for TcpOptions#encode.
58
+ def decode
59
+ decoded = self.map do |x|
60
+ if x.kind_of? TcpOption
61
+ x.decode
62
+ else
63
+ x = TcpOptions.new.read(x).decode
64
+ end
65
+ end
66
+ decoded.join(",")
67
+ end
67
68
 
68
- # Encode takes a human-readable string and appends the corresponding
69
- # binary options to the TcpOptions object. To completely replace the contents
70
- # of the object, use TcpOptions#encode! instead.
71
- #
72
- # Options are comma-delimited, and are identical to the output of the
73
- # TcpOptions#decode function. Note that the syntax can be unforgiving, so
74
- # it may be easier to create the subclassed TcpOptions themselves directly,
75
- # but this method can be less typing if you know what you're doing.
76
- #
77
- # Note that by using TcpOptions#encode, strings supplied as values which
78
- # can be converted to numbers will be converted first.
79
- #
80
- # === Example
81
- #
82
- # t = TcpOptions.new
83
- # t.encode("MS:1460,WS:6")
84
- # t.to_s # => "\002\004\005\264\002\003\006"
85
- # t.encode("NOP")
86
- # t.to_s # => "\002\004\005\264\002\003\006\001"
87
- def encode(str)
88
- opts = str.split(/[\s]*,[\s]*/)
89
- opts.each do |o|
90
- kind,value = o.split(/[\s]*:[\s]*/)
91
- klass = TcpOption.const_get(kind.upcase)
92
- value = value.to_i if value =~ /^[0-9]+$/
93
- this_opt = klass.new
94
- this_opt.encode(value)
95
- self << this_opt
96
- end
97
- self
98
- end
69
+ # Encode takes a human-readable string and appends the corresponding
70
+ # binary options to the TcpOptions object. To completely replace the contents
71
+ # of the object, use TcpOptions#encode! instead.
72
+ #
73
+ # Options are comma-delimited, and are identical to the output of the
74
+ # TcpOptions#decode function. Note that the syntax can be unforgiving, so
75
+ # it may be easier to create the subclassed TcpOptions themselves directly,
76
+ # but this method can be less typing if you know what you're doing.
77
+ #
78
+ # Note that by using TcpOptions#encode, strings supplied as values which
79
+ # can be converted to numbers will be converted first.
80
+ #
81
+ # === Example
82
+ #
83
+ # t = TcpOptions.new
84
+ # t.encode("MS:1460,WS:6")
85
+ # t.to_s # => "\002\004\005\264\002\003\006"
86
+ # t.encode("NOP")
87
+ # t.to_s # => "\002\004\005\264\002\003\006\001"
88
+ def encode(str)
89
+ opts = str.split(/[\s]*,[\s]*/)
90
+ opts.each do |o|
91
+ kind,value = o.split(/[\s]*:[\s]*/)
92
+ klass = TcpOption.const_get(kind.upcase)
93
+ value = value.to_i if value =~ /^[0-9]+$/
94
+ this_opt = klass.new
95
+ this_opt.encode(value)
96
+ self << this_opt
97
+ end
98
+ self
99
+ end
99
100
 
100
- # Like TcpOption#encode, except the entire contents are replaced.
101
- def encode!(str)
102
- self.clear if self.size > 0
103
- encode(str)
104
- end
105
- end
101
+ # Like TcpOption#encode, except the entire contents are replaced.
102
+ def encode!(str)
103
+ self.clear if self.size > 0
104
+ encode(str)
105
+ end
106
+ end
106
107
  end
@@ -1,42 +1,43 @@
1
+ # -*- coding: binary -*-
1
2
  module PacketFu
2
- # Implements the Reserved bits for TCPHeader.
3
- #
4
- # ==== Header Definition
5
- #
6
- #
7
- # Fixnum (1 bit) :r1
8
- # Fixnum (1 bit) :r2
9
- # Fixnum (1 bit) :r3
10
- class TcpReserved < Struct.new(:r1, :r2, :r3)
3
+ # Implements the Reserved bits for TCPHeader.
4
+ #
5
+ # ==== Header Definition
6
+ #
7
+ #
8
+ # Fixnum (1 bit) :r1
9
+ # Fixnum (1 bit) :r2
10
+ # Fixnum (1 bit) :r3
11
+ class TcpReserved < Struct.new(:r1, :r2, :r3)
11
12
 
12
- include StructFu
13
+ include StructFu
13
14
 
14
- def initialize(args={})
15
- super(
16
- args[:r1] || 0,
17
- args[:r2] || 0,
18
- args[:r3] || 0) if args.kind_of? Hash
19
- end
15
+ def initialize(args={})
16
+ super(
17
+ args[:r1] || 0,
18
+ args[:r2] || 0,
19
+ args[:r3] || 0) if args.kind_of? Hash
20
+ end
20
21
 
21
- # Returns the Reserved field as an integer.
22
- def to_i
23
- (r1.to_i << 2) + (r2.to_i << 1) + r3.to_i
24
- end
22
+ # Returns the Reserved field as an integer.
23
+ def to_i
24
+ (r1.to_i << 2) + (r2.to_i << 1) + r3.to_i
25
+ end
25
26
 
26
- # Reads a string to populate the object.
27
- def read(str)
28
- force_binary(str)
29
- return self if str.nil? || str.size.zero?
30
- if 1.respond_to? :ord
31
- byte = str[0].ord
32
- else
33
- byte = str[0]
34
- end
35
- self[:r1] = byte & 0b00000100 == 0b00000100 ? 1 : 0
36
- self[:r2] = byte & 0b00000010 == 0b00000010 ? 1 : 0
37
- self[:r3] = byte & 0b00000001 == 0b00000001 ? 1 : 0
38
- self
39
- end
27
+ # Reads a string to populate the object.
28
+ def read(str)
29
+ force_binary(str)
30
+ return self if str.nil? || str.size.zero?
31
+ if 1.respond_to? :ord
32
+ byte = str[0].ord
33
+ else
34
+ byte = str[0]
35
+ end
36
+ self[:r1] = byte & 0b00000100 == 0b00000100 ? 1 : 0
37
+ self[:r2] = byte & 0b00000010 == 0b00000010 ? 1 : 0
38
+ self[:r3] = byte & 0b00000001 == 0b00000001 ? 1 : 0
39
+ self
40
+ end
40
41
 
41
- end
42
+ end
42
43
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: binary -*-
1
2
  require 'packetfu/protos/eth/header'
2
3
  require 'packetfu/protos/eth/mixin'
3
4
 
@@ -9,133 +10,133 @@ require 'packetfu/protos/udp/mixin'
9
10
 
10
11
  module PacketFu
11
12
 
12
- # UDPPacket is used to construct UDP Packets. They contain an EthHeader, an IPHeader, and a UDPHeader.
13
- #
14
- # == Example
15
- #
16
- # udp_pkt = PacketFu::UDPPacket.new
17
- # udp_pkt.udp_src=rand(0xffff-1024) + 1024
18
- # udp_pkt.udp_dst=53
19
- #
20
- # udp_pkt.ip_saddr="1.2.3.4"
21
- # udp_pkt.ip_daddr="10.20.30.40"
22
- #
23
- # udp_pkt.recalc
24
- # udp_pkt.to_f('/tmp/udp.pcap')
25
- #
26
- # == Parameters
27
- #
28
- # :eth
29
- # A pre-generated EthHeader object.
30
- # :ip
31
- # A pre-generated IPHeader object.
32
- # :flavor
33
- # TODO: Sets the "flavor" of the UDP packet. UDP packets don't tend have a lot of
34
- # flavor, but their underlying ip headers do.
35
- # :config
36
- # A hash of return address details, often the output of Utils.whoami?
37
- class UDPPacket < Packet
13
+ # UDPPacket is used to construct UDP Packets. They contain an EthHeader, an IPHeader, and a UDPHeader.
14
+ #
15
+ # == Example
16
+ #
17
+ # udp_pkt = PacketFu::UDPPacket.new
18
+ # udp_pkt.udp_src=rand(0xffff-1024) + 1024
19
+ # udp_pkt.udp_dst=53
20
+ #
21
+ # udp_pkt.ip_saddr="1.2.3.4"
22
+ # udp_pkt.ip_daddr="10.20.30.40"
23
+ #
24
+ # udp_pkt.recalc
25
+ # udp_pkt.to_f('/tmp/udp.pcap')
26
+ #
27
+ # == Parameters
28
+ #
29
+ # :eth
30
+ # A pre-generated EthHeader object.
31
+ # :ip
32
+ # A pre-generated IPHeader object.
33
+ # :flavor
34
+ # TODO: Sets the "flavor" of the UDP packet. UDP packets don't tend have a lot of
35
+ # flavor, but their underlying ip headers do.
36
+ # :config
37
+ # A hash of return address details, often the output of Utils.whoami?
38
+ class UDPPacket < Packet
38
39
  include ::PacketFu::EthHeaderMixin
39
40
  include ::PacketFu::IPHeaderMixin
40
41
  include ::PacketFu::UDPHeaderMixin
41
42
 
42
- attr_accessor :eth_header, :ip_header, :udp_header
43
+ attr_accessor :eth_header, :ip_header, :udp_header
43
44
 
44
- def self.can_parse?(str)
45
- return false unless str.size >= 28
46
- return false unless EthPacket.can_parse? str
47
- return false unless IPPacket.can_parse? str
48
- return false unless str[23,1] == "\x11"
49
- return true
50
- end
45
+ def self.can_parse?(str)
46
+ return false unless str.size >= 28
47
+ return false unless EthPacket.can_parse? str
48
+ return false unless IPPacket.can_parse? str
49
+ return false unless str[23,1] == "\x11"
50
+ return true
51
+ end
51
52
 
52
- def read(str=nil, args={})
53
- raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
54
- @eth_header.read(str)
55
- if args[:strip]
56
- udp_body_len = self.ip_len - self.ip_hlen - 8
57
- @udp_header.body.read(@udp_header.body.to_s[0,udp_body_len])
58
- end
59
- super(args)
60
- self
61
- end
53
+ def read(str=nil, args={})
54
+ raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
55
+ @eth_header.read(str)
56
+ if args[:strip]
57
+ udp_body_len = self.ip_len - self.ip_hlen - 8
58
+ @udp_header.body.read(@udp_header.body.to_s[0,udp_body_len])
59
+ end
60
+ super(args)
61
+ self
62
+ end
62
63
 
63
- def initialize(args={})
64
- @eth_header = EthHeader.new(args).read(args[:eth])
65
- @ip_header = IPHeader.new(args).read(args[:ip])
66
- @ip_header.ip_proto=0x11
67
- @udp_header = UDPHeader.new(args).read(args[:icmp])
68
- @ip_header.body = @udp_header
69
- @eth_header.body = @ip_header
70
- @headers = [@eth_header, @ip_header, @udp_header]
71
- super
72
- udp_calc_sum
73
- end
64
+ def initialize(args={})
65
+ @eth_header = EthHeader.new(args).read(args[:eth])
66
+ @ip_header = IPHeader.new(args).read(args[:ip])
67
+ @ip_header.ip_proto=0x11
68
+ @udp_header = UDPHeader.new(args).read(args[:icmp])
69
+ @ip_header.body = @udp_header
70
+ @eth_header.body = @ip_header
71
+ @headers = [@eth_header, @ip_header, @udp_header]
72
+ super
73
+ udp_calc_sum
74
+ end
74
75
 
75
- # udp_calc_sum() computes the UDP checksum, and is called upon intialization.
76
- # It usually should be called just prior to dropping packets to a file or on the wire.
77
- def udp_calc_sum
78
- # This is /not/ delegated down to @udp_header since we need info
79
- # from the IP header, too.
80
- checksum = (ip_src.to_i >> 16)
81
- checksum += (ip_src.to_i & 0xffff)
82
- checksum += (ip_dst.to_i >> 16)
83
- checksum += (ip_dst.to_i & 0xffff)
84
- checksum += 0x11
85
- checksum += udp_len.to_i
86
- checksum += udp_src.to_i
87
- checksum += udp_dst.to_i
88
- checksum += udp_len.to_i
89
- if udp_len.to_i >= 8
90
- # For IP trailers. This isn't very reliable. :/
91
- real_udp_payload = payload.to_s[0,(udp_len.to_i-8)]
92
- else
93
- # I'm not going to mess with this right now.
94
- real_udp_payload = payload
95
- end
96
- chk_payload = (real_udp_payload.size % 2 == 0 ? real_udp_payload : real_udp_payload + "\x00")
97
- chk_payload.unpack("n*").each {|x| checksum = checksum+x}
98
- checksum = checksum % 0xffff
99
- checksum = 0xffff - checksum
100
- checksum == 0 ? 0xffff : checksum
101
- @udp_header.udp_sum = checksum
102
- end
76
+ # udp_calc_sum() computes the UDP checksum, and is called upon intialization.
77
+ # It usually should be called just prior to dropping packets to a file or on the wire.
78
+ def udp_calc_sum
79
+ # This is /not/ delegated down to @udp_header since we need info
80
+ # from the IP header, too.
81
+ checksum = (ip_src.to_i >> 16)
82
+ checksum += (ip_src.to_i & 0xffff)
83
+ checksum += (ip_dst.to_i >> 16)
84
+ checksum += (ip_dst.to_i & 0xffff)
85
+ checksum += 0x11
86
+ checksum += udp_len.to_i
87
+ checksum += udp_src.to_i
88
+ checksum += udp_dst.to_i
89
+ checksum += udp_len.to_i
90
+ if udp_len.to_i >= 8
91
+ # For IP trailers. This isn't very reliable. :/
92
+ real_udp_payload = payload.to_s[0,(udp_len.to_i-8)]
93
+ else
94
+ # I'm not going to mess with this right now.
95
+ real_udp_payload = payload
96
+ end
97
+ chk_payload = (real_udp_payload.size % 2 == 0 ? real_udp_payload : real_udp_payload + "\x00")
98
+ chk_payload.unpack("n*").each {|x| checksum = checksum+x}
99
+ checksum = checksum % 0xffff
100
+ checksum = 0xffff - checksum
101
+ checksum == 0 ? 0xffff : checksum
102
+ @udp_header.udp_sum = checksum
103
+ end
103
104
 
104
- # udp_recalc() recalculates various fields of the UDP packet. Valid arguments are:
105
- #
106
- # :all
107
- # Recomputes all calculated fields.
108
- # :udp_sum
109
- # Recomputes the UDP checksum.
110
- # :udp_len
111
- # Recomputes the UDP length.
112
- def udp_recalc(args=:all)
113
- case args
114
- when :udp_len
115
- @udp_header.udp_recalc
116
- when :udp_sum
117
- udp_calc_sum
118
- when :all
119
- @udp_header.udp_recalc
120
- udp_calc_sum
121
- else
122
- raise ArgumentError, "No such field `#{arg}'"
123
- end
124
- end
105
+ # udp_recalc() recalculates various fields of the UDP packet. Valid arguments are:
106
+ #
107
+ # :all
108
+ # Recomputes all calculated fields.
109
+ # :udp_sum
110
+ # Recomputes the UDP checksum.
111
+ # :udp_len
112
+ # Recomputes the UDP length.
113
+ def udp_recalc(args=:all)
114
+ case args
115
+ when :udp_len
116
+ @udp_header.udp_recalc
117
+ when :udp_sum
118
+ udp_calc_sum
119
+ when :all
120
+ @udp_header.udp_recalc
121
+ udp_calc_sum
122
+ else
123
+ raise ArgumentError, "No such field `#{arg}'"
124
+ end
125
+ end
125
126
 
126
- # Peek provides summary data on packet contents.
127
- def peek_format
128
- peek_data = ["U "]
129
- peek_data << "%-5d" % self.to_s.size
130
- peek_data << "%-21s" % "#{self.ip_saddr}:#{self.udp_sport}"
131
- peek_data << "->"
132
- peek_data << "%21s" % "#{self.ip_daddr}:#{self.udp_dport}"
133
- peek_data << "%23s" % "I:"
134
- peek_data << "%04x" % self.ip_id
135
- peek_data.join
136
- end
127
+ # Peek provides summary data on packet contents.
128
+ def peek_format
129
+ peek_data = ["U "]
130
+ peek_data << "%-5d" % self.to_s.size
131
+ peek_data << "%-21s" % "#{self.ip_saddr}:#{self.udp_sport}"
132
+ peek_data << "->"
133
+ peek_data << "%21s" % "#{self.ip_daddr}:#{self.udp_dport}"
134
+ peek_data << "%23s" % "I:"
135
+ peek_data << "%04x" % self.ip_id
136
+ peek_data.join
137
+ end
137
138
 
138
- end
139
+ end
139
140
 
140
141
  end
141
142