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.
- 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/lib/packetfu.rb +127 -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 +528 -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 +116 -116
- 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 +226 -217
- data/lib/packetfu/version.rb +41 -41
- data/packetfu.gemspec +2 -1
- data/spec/ethpacket_spec.rb +48 -48
- data/spec/packet_spec.rb +57 -57
- data/spec/packet_subclasses_spec.rb +8 -8
- data/spec/packetfu_spec.rb +59 -59
- data/spec/structfu_spec.rb +268 -268
- data/spec/tcp_spec.rb +75 -75
- data/test/all_tests.rb +13 -13
- data/test/func_lldp.rb +3 -3
- data/test/ptest.rb +2 -2
- data/test/test_arp.rb +116 -116
- data/test/test_capture.rb +45 -45
- data/test/test_eth.rb +68 -68
- data/test/test_hsrp.rb +9 -9
- data/test/test_icmp.rb +52 -52
- data/test/test_inject.rb +18 -18
- data/test/test_invalid.rb +16 -16
- data/test/test_ip.rb +36 -36
- data/test/test_ip6.rb +48 -48
- data/test/test_octets.rb +21 -21
- data/test/test_packet.rb +154 -154
- data/test/test_pcap.rb +170 -170
- data/test/test_structfu.rb +97 -97
- data/test/test_tcp.rb +320 -320
- data/test/test_udp.rb +76 -76
- metadata +4 -3
@@ -1,84 +1,84 @@
|
|
1
1
|
# -*- coding: binary -*-
|
2
2
|
module PacketFu
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
# Implements flags for TCPHeader.
|
4
|
+
#
|
5
|
+
# ==== Header Definition
|
6
|
+
#
|
7
|
+
# Fixnum (1 bit) :urg
|
8
|
+
# Fixnum (1 bit) :ack
|
9
|
+
# Fixnum (1 bit) :psh
|
10
|
+
# Fixnum (1 bit) :rst
|
11
|
+
# Fixnum (1 bit) :syn
|
12
|
+
# Fixnum (1 bit) :fin
|
13
|
+
#
|
14
|
+
# Flags can typically be set by setting them either to 1 or 0, or to true or false.
|
15
|
+
class TcpFlags < Struct.new(:urg, :ack, :psh, :rst, :syn, :fin)
|
16
16
|
|
17
|
-
|
17
|
+
include StructFu
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
19
|
+
def initialize(args={})
|
20
|
+
# This technique attemts to ensure that flags are always 0 (off)
|
21
|
+
# or 1 (on). Statements like nil and false shouldn't be lurking in here.
|
22
|
+
if args.nil? || args.size.zero?
|
23
|
+
super( 0, 0, 0, 0, 0, 0)
|
24
|
+
else
|
25
|
+
super(
|
26
|
+
(args[:urg] ? 1 : 0),
|
27
|
+
(args[:ack] ? 1 : 0),
|
28
|
+
(args[:psh] ? 1 : 0),
|
29
|
+
(args[:rst] ? 1 : 0),
|
30
|
+
(args[:syn] ? 1 : 0),
|
31
|
+
(args[:fin] ? 1 : 0)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
# Returns the TcpFlags as an integer.
|
37
|
+
# Also not a great candidate for to_s due to the short bitspace.
|
38
|
+
def to_i
|
39
|
+
(urg.to_i << 5) + (ack.to_i << 4) + (psh.to_i << 3) +
|
40
|
+
(rst.to_i << 2) + (syn.to_i << 1) + fin.to_i
|
41
|
+
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
# Helper to determine if this flag is a 1 or a 0.
|
44
|
+
def zero_or_one(i=0)
|
45
|
+
if i == 0 || i == false || i == nil
|
46
|
+
0
|
47
|
+
else
|
48
|
+
1
|
49
|
+
end
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
# Setter for the Urgent flag.
|
53
|
+
def urg=(i); self[:urg] = zero_or_one(i); end
|
54
|
+
# Setter for the Acknowlege flag.
|
55
|
+
def ack=(i); self[:ack] = zero_or_one(i); end
|
56
|
+
# Setter for the Push flag.
|
57
|
+
def psh=(i); self[:psh] = zero_or_one(i); end
|
58
|
+
# Setter for the Reset flag.
|
59
|
+
def rst=(i); self[:rst] = zero_or_one(i); end
|
60
|
+
# Setter for the Synchronize flag.
|
61
|
+
def syn=(i); self[:syn] = zero_or_one(i); end
|
62
|
+
# Setter for the Finish flag.
|
63
|
+
def fin=(i); self[:fin] = zero_or_one(i); end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
65
|
+
# Reads a string to populate the object.
|
66
|
+
def read(str)
|
67
|
+
force_binary(str)
|
68
|
+
return self if str.nil?
|
69
|
+
if 1.respond_to? :ord
|
70
|
+
byte = str[0].ord
|
71
|
+
else
|
72
|
+
byte = str[0]
|
73
|
+
end
|
74
|
+
self[:urg] = byte & 0b00100000 == 0b00100000 ? 1 : 0
|
75
|
+
self[:ack] = byte & 0b00010000 == 0b00010000 ? 1 : 0
|
76
|
+
self[:psh] = byte & 0b00001000 == 0b00001000 ? 1 : 0
|
77
|
+
self[:rst] = byte & 0b00000100 == 0b00000100 ? 1 : 0
|
78
|
+
self[:syn] = byte & 0b00000010 == 0b00000010 ? 1 : 0
|
79
|
+
self[:fin] = byte & 0b00000001 == 0b00000001 ? 1 : 0
|
80
|
+
self
|
81
|
+
end
|
82
82
|
|
83
|
-
|
83
|
+
end
|
84
84
|
end
|
@@ -8,301 +8,301 @@ require 'packetfu/protos/tcp/options'
|
|
8
8
|
|
9
9
|
|
10
10
|
module PacketFu
|
11
|
-
|
12
|
-
|
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
|
-
|
39
|
-
|
11
|
+
# TCPHeader is a complete TCP struct, used in TCPPacket. Most IP traffic is TCP-based, by
|
12
|
+
# volume.
|
13
|
+
#
|
14
|
+
# For more on TCP packets, see http://www.networksorcery.com/enp/protocol/tcp.htm
|
15
|
+
#
|
16
|
+
# ==== Header Definition
|
17
|
+
#
|
18
|
+
# Int16 :tcp_src Default: random
|
19
|
+
# Int16 :tcp_dst
|
20
|
+
# Int32 :tcp_seq Default: random
|
21
|
+
# Int32 :tcp_ack
|
22
|
+
# TcpHlen :tcp_hlen Default: 5 # Must recalc as options are set.
|
23
|
+
# TcpReserved :tcp_reserved Default: 0
|
24
|
+
# TcpEcn :tcp_ecn
|
25
|
+
# TcpFlags :tcp_flags
|
26
|
+
# Int16 :tcp_win, Default: 0 # WinXP's default syn packet
|
27
|
+
# Int16 :tcp_sum, Default: calculated # Must set this upon generation.
|
28
|
+
# Int16 :tcp_urg
|
29
|
+
# TcpOptions :tcp_opts
|
30
|
+
# String :body
|
31
|
+
#
|
32
|
+
# See also TcpHlen, TcpReserved, TcpEcn, TcpFlags, TcpOpts
|
33
|
+
class TCPHeader < Struct.new(:tcp_src, :tcp_dst,
|
34
|
+
:tcp_seq,
|
35
|
+
:tcp_ack,
|
36
|
+
:tcp_hlen, :tcp_reserved, :tcp_ecn, :tcp_flags, :tcp_win,
|
37
|
+
:tcp_sum, :tcp_urg,
|
38
|
+
:tcp_opts, :body)
|
39
|
+
include StructFu
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
41
|
+
def initialize(args={})
|
42
|
+
@random_seq = rand(0xffffffff)
|
43
|
+
@random_src = rand_port
|
44
|
+
super(
|
45
|
+
Int16.new(args[:tcp_src] || tcp_calc_src),
|
46
|
+
Int16.new(args[:tcp_dst]),
|
47
|
+
Int32.new(args[:tcp_seq] || tcp_calc_seq),
|
48
|
+
Int32.new(args[:tcp_ack]),
|
49
|
+
TcpHlen.new(:hlen => (args[:tcp_hlen] || 5)),
|
50
|
+
TcpReserved.new(args[:tcp_reserved] || 0),
|
51
|
+
TcpEcn.new(args[:tcp_ecn]),
|
52
|
+
TcpFlags.new(args[:tcp_flags]),
|
53
|
+
Int16.new(args[:tcp_win] || 0x4000),
|
54
|
+
Int16.new(args[:tcp_sum] || 0),
|
55
|
+
Int16.new(args[:tcp_urg]),
|
56
|
+
TcpOptions.new.read(args[:tcp_opts]),
|
57
|
+
StructFu::String.new.read(args[:body])
|
58
|
+
)
|
59
|
+
end
|
60
60
|
|
61
|
-
|
61
|
+
attr_accessor :flavor
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
63
|
+
# Helper function to create the string for Hlen, Reserved, ECN, and Flags.
|
64
|
+
def bits_to_s
|
65
|
+
bytes = []
|
66
|
+
bytes[0] = (self[:tcp_hlen].to_i << 4) +
|
67
|
+
(self[:tcp_reserved].to_i << 1) +
|
68
|
+
self[:tcp_ecn].n.to_i
|
69
|
+
bytes[1] = (self[:tcp_ecn].c.to_i << 7) +
|
70
|
+
(self[:tcp_ecn].e.to_i << 6) +
|
71
|
+
self[:tcp_flags].to_i
|
72
|
+
bytes.pack("CC")
|
73
|
+
end
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
75
|
+
# Returns the object in string form.
|
76
|
+
def to_s
|
77
|
+
hdr = self.to_a.map do |x|
|
78
|
+
if x.kind_of? TcpHlen
|
79
|
+
bits_to_s
|
80
|
+
elsif x.kind_of? TcpReserved
|
81
|
+
next
|
82
|
+
elsif x.kind_of? TcpEcn
|
83
|
+
next
|
84
|
+
elsif x.kind_of? TcpFlags
|
85
|
+
next
|
86
|
+
else
|
87
|
+
x.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
hdr.flatten.join
|
91
|
+
end
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
93
|
+
# Reads a string to populate the object.
|
94
|
+
def read(str)
|
95
|
+
force_binary(str)
|
96
|
+
return self if str.nil?
|
97
|
+
self[:tcp_src].read(str[0,2])
|
98
|
+
self[:tcp_dst].read(str[2,2])
|
99
|
+
self[:tcp_seq].read(str[4,4])
|
100
|
+
self[:tcp_ack].read(str[8,4])
|
101
|
+
self[:tcp_hlen].read(str[12,1])
|
102
|
+
self[:tcp_reserved].read(str[12,1])
|
103
|
+
self[:tcp_ecn].read(str[12,2])
|
104
|
+
self[:tcp_flags].read(str[13,1])
|
105
|
+
self[:tcp_win].read(str[14,2])
|
106
|
+
self[:tcp_sum].read(str[16,2])
|
107
|
+
self[:tcp_urg].read(str[18,2])
|
108
|
+
self[:tcp_opts].read(str[20,((self[:tcp_hlen].to_i * 4) - 20)])
|
109
|
+
self[:body].read(str[(self[:tcp_hlen].to_i * 4),str.size])
|
110
|
+
self
|
111
|
+
end
|
112
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
|
-
|
140
|
-
|
113
|
+
# Setter for the TCP source port.
|
114
|
+
def tcp_src=(i); typecast i; end
|
115
|
+
# Getter for the TCP source port.
|
116
|
+
def tcp_src; self[:tcp_src].to_i; end
|
117
|
+
# Setter for the TCP destination port.
|
118
|
+
def tcp_dst=(i); typecast i; end
|
119
|
+
# Getter for the TCP destination port.
|
120
|
+
def tcp_dst; self[:tcp_dst].to_i; end
|
121
|
+
# Setter for the TCP sequence number.
|
122
|
+
def tcp_seq=(i); typecast i; end
|
123
|
+
# Getter for the TCP sequence number.
|
124
|
+
def tcp_seq; self[:tcp_seq].to_i; end
|
125
|
+
# Setter for the TCP ackowlegement number.
|
126
|
+
def tcp_ack=(i); typecast i; end
|
127
|
+
# Getter for the TCP ackowlegement number.
|
128
|
+
def tcp_ack; self[:tcp_ack].to_i; end
|
129
|
+
# Setter for the TCP window size number.
|
130
|
+
def tcp_win=(i); typecast i; end
|
131
|
+
# Getter for the TCP window size number.
|
132
|
+
def tcp_win; self[:tcp_win].to_i; end
|
133
|
+
# Setter for the TCP checksum.
|
134
|
+
def tcp_sum=(i); typecast i; end
|
135
|
+
# Getter for the TCP checksum.
|
136
|
+
def tcp_sum; self[:tcp_sum].to_i; end
|
137
|
+
# Setter for the TCP urgent field.
|
138
|
+
def tcp_urg=(i); typecast i; end
|
139
|
+
# Getter for the TCP urgent field.
|
140
|
+
def tcp_urg; self[:tcp_urg].to_i; end
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
142
|
+
# Getter for the TCP Header Length value.
|
143
|
+
def tcp_hlen; self[:tcp_hlen].to_i; end
|
144
|
+
# Setter for the TCP Header Length value. Can take
|
145
|
+
# either a string or an integer. Note that if it's
|
146
|
+
# a string, the top four bits are used.
|
147
|
+
def tcp_hlen=(i)
|
148
|
+
case i
|
149
|
+
when PacketFu::TcpHlen
|
150
|
+
self[:tcp_hlen] = i
|
151
|
+
when Numeric
|
152
|
+
self[:tcp_hlen] = TcpHlen.new(:hlen => i.to_i)
|
153
|
+
else
|
154
|
+
self[:tcp_hlen].read(i)
|
155
|
+
end
|
156
|
+
end
|
157
157
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
158
|
+
# Getter for the TCP Reserved field.
|
159
|
+
def tcp_reserved; self[:tcp_reserved].to_i; end
|
160
|
+
# Setter for the TCP Reserved field.
|
161
|
+
def tcp_reserved=(i)
|
162
|
+
case i
|
163
|
+
when PacketFu::TcpReserved
|
164
|
+
self[:tcp_reserved]=i
|
165
|
+
when Numeric
|
166
|
+
args = {}
|
167
|
+
args[:r1] = (i & 0b100) >> 2
|
168
|
+
args[:r2] = (i & 0b010) >> 1
|
169
|
+
args[:r3] = (i & 0b001)
|
170
|
+
self[:tcp_reserved] = TcpReserved.new(args)
|
171
|
+
else
|
172
|
+
self[:tcp_reserved].read(i)
|
173
|
+
end
|
174
|
+
end
|
175
175
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
176
|
+
# Getter for the ECN bits.
|
177
|
+
def tcp_ecn; self[:tcp_ecn].to_i; end
|
178
|
+
# Setter for the ECN bits.
|
179
|
+
def tcp_ecn=(i)
|
180
|
+
case i
|
181
|
+
when PacketFu::TcpEcn
|
182
|
+
self[:tcp_ecn]=i
|
183
|
+
when Numeric
|
184
|
+
args = {}
|
185
|
+
args[:n] = (i & 0b100) >> 2
|
186
|
+
args[:c] = (i & 0b010) >> 1
|
187
|
+
args[:e] = (i & 0b001)
|
188
|
+
self[:tcp_ecn] = TcpEcn.new(args)
|
189
|
+
else
|
190
|
+
self[:tcp_ecn].read(i)
|
191
|
+
end
|
192
|
+
end
|
193
193
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
194
|
+
# Getter for TCP Options.
|
195
|
+
def tcp_opts; self[:tcp_opts].to_s; end
|
196
|
+
# Setter for TCP Options.
|
197
|
+
def tcp_opts=(i)
|
198
|
+
case i
|
199
|
+
when PacketFu::TcpOptions
|
200
|
+
self[:tcp_opts]=i
|
201
|
+
else
|
202
|
+
self[:tcp_opts].read(i)
|
203
|
+
end
|
204
|
+
end
|
205
205
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
206
|
+
# Resets the sequence number to a new random number.
|
207
|
+
def tcp_calc_seq; @random_seq; end
|
208
|
+
# Resets the source port to a new random number.
|
209
|
+
def tcp_calc_src; @random_src; end
|
210
210
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
211
|
+
# Returns the actual length of the TCP options.
|
212
|
+
def tcp_opts_len
|
213
|
+
self[:tcp_opts].to_s.size
|
214
|
+
end
|
215
215
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
216
|
+
# Sets and returns the true length of the TCP Header.
|
217
|
+
# TODO: Think about making all the option stuff safer.
|
218
|
+
def tcp_calc_hlen
|
219
|
+
self[:tcp_hlen] = TcpHlen.new(:hlen => ((20 + tcp_opts_len) / 4))
|
220
|
+
end
|
221
221
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
222
|
+
# Generates a random high port. This is affected by packet flavor.
|
223
|
+
def rand_port
|
224
|
+
rand(0xffff - 1025) + 1025
|
225
|
+
end
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
227
|
+
# Gets a more readable option list.
|
228
|
+
def tcp_options
|
229
|
+
self[:tcp_opts].decode
|
230
|
+
end
|
231
231
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
232
|
+
# Gets a more readable flags list
|
233
|
+
def tcp_flags_dotmap
|
234
|
+
dotmap = tcp_flags.members.map do |flag|
|
235
|
+
status = self.tcp_flags.send flag
|
236
|
+
status == 0 ? "." : flag.to_s.upcase[0].chr
|
237
|
+
end
|
238
|
+
dotmap.join
|
239
|
+
end
|
240
240
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
241
|
+
# Sets a more readable option list.
|
242
|
+
def tcp_options=(arg)
|
243
|
+
self[:tcp_opts].encode arg
|
244
|
+
end
|
245
245
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
246
|
+
# Equivalent to tcp_src.
|
247
|
+
def tcp_sport
|
248
|
+
self.tcp_src.to_i
|
249
|
+
end
|
250
250
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
251
|
+
# Equivalent to tcp_src=.
|
252
|
+
def tcp_sport=(arg)
|
253
|
+
self.tcp_src=(arg)
|
254
|
+
end
|
255
255
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
256
|
+
# Equivalent to tcp_dst.
|
257
|
+
def tcp_dport
|
258
|
+
self.tcp_dst.to_i
|
259
|
+
end
|
260
|
+
|
261
|
+
# Equivalent to tcp_dst=.
|
262
|
+
def tcp_dport=(arg)
|
263
|
+
self.tcp_dst=(arg)
|
264
|
+
end
|
265
265
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
266
|
+
# Recalculates calculated fields for TCP (except checksum which is at the Packet level).
|
267
|
+
def tcp_recalc(arg=:all)
|
268
|
+
case arg
|
269
|
+
when :tcp_hlen
|
270
|
+
tcp_calc_hlen
|
271
|
+
when :tcp_src
|
272
|
+
@random_tcp_src = rand_port
|
273
|
+
when :tcp_sport
|
274
|
+
@random_tcp_src = rand_port
|
275
|
+
when :tcp_seq
|
276
|
+
@random_tcp_seq = rand(0xffffffff)
|
277
|
+
when :all
|
278
|
+
tcp_calc_hlen
|
279
|
+
@random_tcp_src = rand_port
|
280
|
+
@random_tcp_seq = rand(0xffffffff)
|
281
|
+
else
|
282
|
+
raise ArgumentError, "No such field `#{arg}'"
|
283
|
+
end
|
284
|
+
end
|
285
285
|
|
286
|
-
|
286
|
+
# Readability aliases
|
287
287
|
|
288
|
-
|
288
|
+
alias :tcp_flags_readable :tcp_flags_dotmap
|
289
289
|
|
290
|
-
|
291
|
-
|
292
|
-
|
290
|
+
def tcp_ack_readable
|
291
|
+
"0x%08x" % tcp_ack
|
292
|
+
end
|
293
293
|
|
294
|
-
|
295
|
-
|
296
|
-
|
294
|
+
def tcp_seq_readable
|
295
|
+
"0x%08x" % tcp_seq
|
296
|
+
end
|
297
297
|
|
298
|
-
|
299
|
-
|
300
|
-
|
298
|
+
def tcp_sum_readable
|
299
|
+
"0x%04x" % tcp_sum
|
300
|
+
end
|
301
301
|
|
302
|
-
|
303
|
-
|
304
|
-
|
302
|
+
def tcp_opts_readable
|
303
|
+
tcp_options
|
304
|
+
end
|
305
305
|
|
306
|
-
|
306
|
+
end
|
307
307
|
|
308
308
|
end
|