packetfu 1.1.9 → 1.1.10

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 (77) hide show
  1. data/bench/octets.rb +9 -9
  2. data/examples/100kpackets.rb +12 -12
  3. data/examples/ackscan.rb +16 -16
  4. data/examples/arp.rb +35 -35
  5. data/examples/arphood.rb +36 -36
  6. data/examples/dissect_thinger.rb +6 -6
  7. data/examples/new-simple-stats.rb +23 -23
  8. data/examples/packetfu-shell.rb +25 -25
  9. data/examples/simple-sniffer.rb +9 -9
  10. data/examples/simple-stats.rb +23 -23
  11. data/examples/slammer.rb +3 -3
  12. data/lib/packetfu.rb +127 -127
  13. data/lib/packetfu/capture.rb +169 -169
  14. data/lib/packetfu/config.rb +52 -52
  15. data/lib/packetfu/inject.rb +56 -56
  16. data/lib/packetfu/packet.rb +528 -528
  17. data/lib/packetfu/pcap.rb +579 -579
  18. data/lib/packetfu/protos/arp.rb +90 -90
  19. data/lib/packetfu/protos/arp/header.rb +158 -158
  20. data/lib/packetfu/protos/arp/mixin.rb +36 -36
  21. data/lib/packetfu/protos/eth.rb +44 -44
  22. data/lib/packetfu/protos/eth/header.rb +243 -243
  23. data/lib/packetfu/protos/eth/mixin.rb +3 -3
  24. data/lib/packetfu/protos/hsrp.rb +69 -69
  25. data/lib/packetfu/protos/hsrp/header.rb +107 -107
  26. data/lib/packetfu/protos/hsrp/mixin.rb +29 -29
  27. data/lib/packetfu/protos/icmp.rb +71 -71
  28. data/lib/packetfu/protos/icmp/header.rb +82 -82
  29. data/lib/packetfu/protos/icmp/mixin.rb +14 -14
  30. data/lib/packetfu/protos/invalid.rb +49 -49
  31. data/lib/packetfu/protos/ip.rb +69 -69
  32. data/lib/packetfu/protos/ip/header.rb +291 -291
  33. data/lib/packetfu/protos/ip/mixin.rb +40 -40
  34. data/lib/packetfu/protos/ipv6.rb +50 -50
  35. data/lib/packetfu/protos/ipv6/header.rb +188 -188
  36. data/lib/packetfu/protos/ipv6/mixin.rb +29 -29
  37. data/lib/packetfu/protos/tcp.rb +176 -176
  38. data/lib/packetfu/protos/tcp/ecn.rb +35 -35
  39. data/lib/packetfu/protos/tcp/flags.rb +74 -74
  40. data/lib/packetfu/protos/tcp/header.rb +268 -268
  41. data/lib/packetfu/protos/tcp/hlen.rb +32 -32
  42. data/lib/packetfu/protos/tcp/mixin.rb +46 -46
  43. data/lib/packetfu/protos/tcp/option.rb +321 -321
  44. data/lib/packetfu/protos/tcp/options.rb +95 -95
  45. data/lib/packetfu/protos/tcp/reserved.rb +35 -35
  46. data/lib/packetfu/protos/udp.rb +116 -116
  47. data/lib/packetfu/protos/udp/header.rb +91 -91
  48. data/lib/packetfu/protos/udp/mixin.rb +3 -3
  49. data/lib/packetfu/structfu.rb +280 -280
  50. data/lib/packetfu/utils.rb +226 -217
  51. data/lib/packetfu/version.rb +41 -41
  52. data/packetfu.gemspec +2 -1
  53. data/spec/ethpacket_spec.rb +48 -48
  54. data/spec/packet_spec.rb +57 -57
  55. data/spec/packet_subclasses_spec.rb +8 -8
  56. data/spec/packetfu_spec.rb +59 -59
  57. data/spec/structfu_spec.rb +268 -268
  58. data/spec/tcp_spec.rb +75 -75
  59. data/test/all_tests.rb +13 -13
  60. data/test/func_lldp.rb +3 -3
  61. data/test/ptest.rb +2 -2
  62. data/test/test_arp.rb +116 -116
  63. data/test/test_capture.rb +45 -45
  64. data/test/test_eth.rb +68 -68
  65. data/test/test_hsrp.rb +9 -9
  66. data/test/test_icmp.rb +52 -52
  67. data/test/test_inject.rb +18 -18
  68. data/test/test_invalid.rb +16 -16
  69. data/test/test_ip.rb +36 -36
  70. data/test/test_ip6.rb +48 -48
  71. data/test/test_octets.rb +21 -21
  72. data/test/test_packet.rb +154 -154
  73. data/test/test_pcap.rb +170 -170
  74. data/test/test_structfu.rb +97 -97
  75. data/test/test_tcp.rb +320 -320
  76. data/test/test_udp.rb +76 -76
  77. metadata +4 -3
@@ -3,105 +3,105 @@ require 'packetfu/protos/tcp/option'
3
3
 
4
4
  module PacketFu
5
5
 
6
- class TcpOptions < Array
6
+ class TcpOptions < Array
7
7
 
8
- include StructFu
8
+ include StructFu
9
9
 
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
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
21
21
 
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
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
51
51
 
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
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
68
68
 
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
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
100
100
 
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
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
107
107
  end
@@ -1,43 +1,43 @@
1
1
  # -*- coding: binary -*-
2
2
  module PacketFu
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)
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)
12
12
 
13
- include StructFu
13
+ include StructFu
14
14
 
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
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
21
21
 
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
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
26
26
 
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
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
41
41
 
42
- end
42
+ end
43
43
  end
@@ -10,133 +10,133 @@ require 'packetfu/protos/udp/mixin'
10
10
 
11
11
  module PacketFu
12
12
 
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
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
39
39
  include ::PacketFu::EthHeaderMixin
40
40
  include ::PacketFu::IPHeaderMixin
41
41
  include ::PacketFu::UDPHeaderMixin
42
42
 
43
- attr_accessor :eth_header, :ip_header, :udp_header
43
+ attr_accessor :eth_header, :ip_header, :udp_header
44
44
 
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
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
52
52
 
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
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
63
63
 
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
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
75
75
 
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
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
104
104
 
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
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
126
126
 
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
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
138
138
 
139
- end
139
+ end
140
140
 
141
141
  end
142
142