packetfu 1.1.10 → 1.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/.gitignore +3 -0
- data/.travis.yml +8 -0
- data/CONTRIBUTING.md +47 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +1 -1
- data/README.rdoc +35 -30
- data/Rakefile +4 -4
- data/bench/octets.rb +9 -9
- data/examples/100kpackets.rb +12 -12
- data/examples/ackscan.rb +16 -16
- data/examples/arp.rb +35 -35
- data/examples/arphood.rb +36 -36
- data/examples/dissect_thinger.rb +6 -6
- data/examples/new-simple-stats.rb +23 -23
- data/examples/packetfu-shell.rb +25 -25
- data/examples/simple-sniffer.rb +9 -9
- data/examples/simple-stats.rb +23 -23
- data/examples/slammer.rb +3 -3
- data/gem-public_cert.pem +21 -0
- data/lib/packetfu.rb +149 -127
- data/lib/packetfu/capture.rb +169 -169
- data/lib/packetfu/config.rb +52 -52
- data/lib/packetfu/inject.rb +56 -56
- data/lib/packetfu/packet.rb +531 -528
- data/lib/packetfu/pcap.rb +579 -579
- data/lib/packetfu/protos/arp.rb +90 -90
- data/lib/packetfu/protos/arp/header.rb +158 -158
- data/lib/packetfu/protos/arp/mixin.rb +36 -36
- data/lib/packetfu/protos/eth.rb +44 -44
- data/lib/packetfu/protos/eth/header.rb +243 -243
- data/lib/packetfu/protos/eth/mixin.rb +3 -3
- data/lib/packetfu/protos/hsrp.rb +69 -69
- data/lib/packetfu/protos/hsrp/header.rb +107 -107
- data/lib/packetfu/protos/hsrp/mixin.rb +29 -29
- data/lib/packetfu/protos/icmp.rb +71 -71
- data/lib/packetfu/protos/icmp/header.rb +82 -82
- data/lib/packetfu/protos/icmp/mixin.rb +14 -14
- data/lib/packetfu/protos/invalid.rb +49 -49
- data/lib/packetfu/protos/ip.rb +69 -69
- data/lib/packetfu/protos/ip/header.rb +291 -291
- data/lib/packetfu/protos/ip/mixin.rb +40 -40
- data/lib/packetfu/protos/ipv6.rb +50 -50
- data/lib/packetfu/protos/ipv6/header.rb +188 -188
- data/lib/packetfu/protos/ipv6/mixin.rb +29 -29
- data/lib/packetfu/protos/tcp.rb +176 -176
- data/lib/packetfu/protos/tcp/ecn.rb +35 -35
- data/lib/packetfu/protos/tcp/flags.rb +74 -74
- data/lib/packetfu/protos/tcp/header.rb +268 -268
- data/lib/packetfu/protos/tcp/hlen.rb +32 -32
- data/lib/packetfu/protos/tcp/mixin.rb +46 -46
- data/lib/packetfu/protos/tcp/option.rb +321 -321
- data/lib/packetfu/protos/tcp/options.rb +95 -95
- data/lib/packetfu/protos/tcp/reserved.rb +35 -35
- data/lib/packetfu/protos/udp.rb +159 -123
- data/lib/packetfu/protos/udp/header.rb +91 -91
- data/lib/packetfu/protos/udp/mixin.rb +3 -3
- data/lib/packetfu/structfu.rb +280 -280
- data/lib/packetfu/utils.rb +292 -225
- data/lib/packetfu/version.rb +41 -41
- data/packetfu.gemspec +14 -3
- data/spec/arp_spec.rb +191 -0
- data/spec/eth_spec.rb +148 -0
- data/spec/icmp_spec.rb +97 -0
- data/spec/ip_spec.rb +78 -0
- data/spec/ipv6_spec.rb +81 -0
- data/spec/packet_spec.rb +61 -59
- data/spec/packet_subclasses_spec.rb +9 -10
- data/spec/packetfu_spec.rb +55 -62
- data/spec/sample3.pcap +0 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/structfu_spec.rb +270 -271
- data/spec/tcp_spec.rb +76 -77
- data/spec/udp_spec.rb +32 -0
- data/spec/utils_spec.rb +95 -0
- data/test/all_tests.rb +14 -17
- data/test/func_lldp.rb +3 -3
- data/test/ptest.rb +2 -2
- data/test/test_capture.rb +45 -45
- data/test/test_eth.rb +70 -68
- data/test/test_hsrp.rb +9 -9
- data/test/test_inject.rb +18 -18
- data/test/test_invalid.rb +16 -16
- data/test/test_octets.rb +23 -21
- data/test/test_packet.rb +156 -154
- data/test/test_pcap.rb +172 -170
- data/test/test_structfu.rb +99 -97
- data/test/test_tcp.rb +322 -320
- data/test/test_udp.rb +78 -76
- metadata +108 -44
- metadata.gz.sig +2 -0
- data/spec/ethpacket_spec.rb +0 -74
- data/test/test_arp.rb +0 -135
- data/test/test_icmp.rb +0 -62
- data/test/test_ip.rb +0 -50
- data/test/test_ip6.rb +0 -68
@@ -3,105 +3,105 @@ require 'packetfu/protos/tcp/option'
|
|
3
3
|
|
4
4
|
module PacketFu
|
5
5
|
|
6
|
-
|
6
|
+
class TcpOptions < Array
|
7
7
|
|
8
|
-
|
8
|
+
include StructFu
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
13
|
+
include StructFu
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
42
|
+
end
|
43
43
|
end
|
data/lib/packetfu/protos/udp.rb
CHANGED
@@ -5,138 +5,174 @@ require 'packetfu/protos/eth/mixin'
|
|
5
5
|
require 'packetfu/protos/ip/header'
|
6
6
|
require 'packetfu/protos/ip/mixin'
|
7
7
|
|
8
|
+
require 'packetfu/protos/ipv6/header'
|
9
|
+
require 'packetfu/protos/ipv6/mixin'
|
10
|
+
|
8
11
|
require 'packetfu/protos/udp/header'
|
9
12
|
require 'packetfu/protos/udp/mixin'
|
10
13
|
|
11
14
|
module PacketFu
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
16
|
+
# UDPPacket is used to construct UDP Packets. They contain an EthHeader, an IPHeader, and a UDPHeader.
|
17
|
+
#
|
18
|
+
# == Example
|
19
|
+
#
|
20
|
+
# udp_pkt = PacketFu::UDPPacket.new
|
21
|
+
# udp_pkt.udp_src=rand(0xffff-1024) + 1024
|
22
|
+
# udp_pkt.udp_dst=53
|
23
|
+
# udp_pkt.ip_saddr="1.2.3.4"
|
24
|
+
# udp_pkt.ip_daddr="10.20.30.40"
|
25
|
+
# udp_pkt.recalc
|
26
|
+
# udp_pkt.to_f('/tmp/udp.pcap')
|
27
|
+
#
|
28
|
+
# udp6_pkt = PacketFu::UDPPacket.new(:on_ipv6 => true)
|
29
|
+
# udp6_pkt.udp_src=rand(0xffff-1024) + 1024
|
30
|
+
# udp6_pkt.udp_dst=53
|
31
|
+
# udp6_pkt.ip6_saddr="4::1"
|
32
|
+
# udp6_pkt.ip6_daddr="12:3::4567"
|
33
|
+
# udp6_pkt.recalc
|
34
|
+
# udp6_pkt.to_f('/tmp/udp.pcap')
|
35
|
+
#
|
36
|
+
# == Parameters
|
37
|
+
#
|
38
|
+
# :eth
|
39
|
+
# A pre-generated EthHeader object.
|
40
|
+
# :ip
|
41
|
+
# A pre-generated IPHeader object.
|
42
|
+
# :flavor
|
43
|
+
# TODO: Sets the "flavor" of the UDP packet. UDP packets don't tend have a lot of
|
44
|
+
# flavor, but their underlying ip headers do.
|
45
|
+
# :config
|
46
|
+
# A hash of return address details, often the output of Utils.whoami?
|
47
|
+
class UDPPacket < Packet
|
39
48
|
include ::PacketFu::EthHeaderMixin
|
40
49
|
include ::PacketFu::IPHeaderMixin
|
50
|
+
include ::PacketFu::IPv6HeaderMixin
|
41
51
|
include ::PacketFu::UDPHeaderMixin
|
42
52
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
53
|
+
attr_accessor :eth_header, :ip_header, :ipv6_header, :udp_header
|
54
|
+
|
55
|
+
def self.can_parse?(str)
|
56
|
+
return false unless str.size >= 28
|
57
|
+
return false unless EthPacket.can_parse? str
|
58
|
+
return false unless IPPacket.can_parse? str
|
59
|
+
return false unless str[23,1] == "\x11"
|
60
|
+
return true
|
61
|
+
end
|
62
|
+
|
63
|
+
def read(str=nil, args={})
|
64
|
+
raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
|
65
|
+
@eth_header.read(str)
|
66
|
+
if args[:strip]
|
67
|
+
udp_body_len = self.ip_len - self.ip_hlen - 8
|
68
|
+
@udp_header.body.read(@udp_header.body.to_s[0,udp_body_len])
|
69
|
+
end
|
70
|
+
super(args)
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def initialize(args={})
|
75
|
+
if args[:on_ipv6] or args[:ipv6]
|
76
|
+
@eth_header = EthHeader.new(args.merge(:eth_proto => 0x86dd)).read(args[:eth])
|
77
|
+
@ipv6_header = IPv6Header.new(args).read(args[:ipv6])
|
78
|
+
@ipv6_header.ipv6_next=0x11
|
79
|
+
else
|
80
|
+
@eth_header = EthHeader.new(args).read(args[:eth])
|
81
|
+
@ip_header = IPHeader.new(args).read(args[:ip])
|
82
|
+
@ip_header.ip_proto=0x11
|
83
|
+
end
|
84
|
+
@udp_header = UDPHeader.new(args).read(args[:udp])
|
85
|
+
if args[:on_ipv6] or args[:ipv6]
|
86
|
+
@ipv6_header.body = @udp_header
|
87
|
+
@eth_header.body = @ipv6_header
|
88
|
+
@headers = [@eth_header, @ipv6_header, @udp_header]
|
89
|
+
else
|
90
|
+
@ip_header.body = @udp_header
|
91
|
+
@eth_header.body = @ip_header
|
92
|
+
@headers = [@eth_header, @ip_header, @udp_header]
|
93
|
+
end
|
94
|
+
super
|
95
|
+
udp_calc_sum
|
96
|
+
end
|
97
|
+
|
98
|
+
# udp_calc_sum() computes the UDP checksum, and is called upon intialization.
|
99
|
+
# It usually should be called just prior to dropping packets to a file or on the wire.
|
100
|
+
def udp_calc_sum
|
101
|
+
# This is /not/ delegated down to @udp_header since we need info
|
102
|
+
# from the IP header, too.
|
103
|
+
checksum = 0
|
104
|
+
if @ipv6_header
|
105
|
+
[ipv6_src, ipv6_dst].each do |iaddr|
|
106
|
+
8.times do |i|
|
107
|
+
checksum += (iaddr >> (i * 16)) & 0xffff
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
checksum += (ip_src.to_i >> 16)
|
112
|
+
checksum += (ip_src.to_i & 0xffff)
|
113
|
+
checksum += (ip_dst.to_i >> 16)
|
114
|
+
checksum += (ip_dst.to_i & 0xffff)
|
115
|
+
end
|
116
|
+
checksum += 0x11
|
117
|
+
checksum += udp_len.to_i
|
118
|
+
checksum += udp_src.to_i
|
119
|
+
checksum += udp_dst.to_i
|
120
|
+
checksum += udp_len.to_i
|
121
|
+
if udp_len.to_i >= 8
|
122
|
+
# For IP trailers. This isn't very reliable. :/
|
123
|
+
real_udp_payload = payload.to_s[0,(udp_len.to_i-8)]
|
124
|
+
else
|
125
|
+
# I'm not going to mess with this right now.
|
126
|
+
real_udp_payload = payload
|
127
|
+
end
|
128
|
+
chk_payload = (real_udp_payload.size % 2 == 0 ? real_udp_payload : real_udp_payload + "\x00")
|
129
|
+
chk_payload.unpack("n*").each {|x| checksum = checksum+x}
|
130
|
+
checksum = checksum % 0xffff
|
131
|
+
checksum = 0xffff - checksum
|
132
|
+
checksum == 0 ? 0xffff : checksum
|
133
|
+
@udp_header.udp_sum = checksum
|
134
|
+
end
|
135
|
+
|
136
|
+
# udp_recalc() recalculates various fields of the UDP packet. Valid arguments are:
|
137
|
+
#
|
138
|
+
# :all
|
139
|
+
# Recomputes all calculated fields.
|
140
|
+
# :udp_sum
|
141
|
+
# Recomputes the UDP checksum.
|
142
|
+
# :udp_len
|
143
|
+
# Recomputes the UDP length.
|
144
|
+
def udp_recalc(args=:all)
|
145
|
+
case args
|
146
|
+
when :udp_len
|
147
|
+
@udp_header.udp_recalc
|
148
|
+
when :udp_sum
|
149
|
+
udp_calc_sum
|
150
|
+
when :all
|
151
|
+
@udp_header.udp_recalc
|
152
|
+
udp_calc_sum
|
153
|
+
else
|
154
|
+
raise ArgumentError, "No such field `#{arg}'"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Peek provides summary data on packet contents.
|
159
|
+
def peek_format
|
160
|
+
peek_data = ["U "]
|
161
|
+
peek_data << "%-5d" % self.to_s.size
|
162
|
+
peek_data << "%-21s" % "#{self.ip_saddr}:#{self.udp_sport}"
|
163
|
+
peek_data << "->"
|
164
|
+
peek_data << "%21s" % "#{self.ip_daddr}:#{self.udp_dport}"
|
165
|
+
peek_data << "%23s" % "I:"
|
166
|
+
peek_data << "%04x" % self.ip_id
|
167
|
+
peek_data.join
|
168
|
+
end
|
169
|
+
|
170
|
+
# Is that packet an UDP on IPv6 packet ?
|
171
|
+
def ipv6?
|
172
|
+
@ipv6_header
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
140
176
|
|
141
177
|
end
|
142
178
|
|