net-dhcp 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +11 -0
- data/.gitignore +40 -0
- data/Gemfile +4 -0
- data/LICENSE +12 -0
- data/README +14 -0
- data/README.etd.original +9 -0
- data/Rakefile +42 -0
- data/bin/net-dhcp +37 -0
- data/lib/net-dhcp.rb +2 -0
- data/lib/net-dhcp/version.rb +5 -0
- data/lib/net/dhcp.rb +48 -0
- data/lib/net/dhcp/constants.rb +182 -0
- data/lib/net/dhcp/core.rb +322 -0
- data/lib/net/dhcp/options.rb +621 -0
- data/lib/net/dhcp/oui.txt +68928 -0
- data/net-dhcp.gemspec +35 -0
- data/spec/net-dhcp_spec.rb +7 -0
- data/spec/spec_helper.rb +19 -0
- data/test/dhcp_test.rb +71 -0
- metadata +142 -0
data/.document
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# .document is used by rdoc and yard to know how to generate documentation
|
2
|
+
# for example, it can be used to control how rdoc gets built when you do `gem install foo`
|
3
|
+
|
4
|
+
README.rdoc
|
5
|
+
lib/**/*.rb
|
6
|
+
bin/*
|
7
|
+
|
8
|
+
# Files below this - are treated as 'extra files', and aren't parsed for ruby code
|
9
|
+
-
|
10
|
+
features/**/*.feature
|
11
|
+
LICENSE
|
data/.gitignore
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
*.gem
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
pkg/*
|
5
|
+
# rcov generated
|
6
|
+
coverage
|
7
|
+
|
8
|
+
# rdoc generated
|
9
|
+
rdoc
|
10
|
+
|
11
|
+
# yard generated
|
12
|
+
doc
|
13
|
+
.yardoc
|
14
|
+
|
15
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
16
|
+
#
|
17
|
+
# * Create a file at ~/.gitignore
|
18
|
+
# * Include files you want ignored
|
19
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
20
|
+
#
|
21
|
+
# After doing this, these files will be ignored in all your git projects,
|
22
|
+
# saving you from having to 'pollute' every project you touch with them
|
23
|
+
#
|
24
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
25
|
+
#
|
26
|
+
# For MacOS:
|
27
|
+
#
|
28
|
+
#.DS_Store
|
29
|
+
#
|
30
|
+
# For TextMate
|
31
|
+
#*.tmproj
|
32
|
+
#tmtags
|
33
|
+
#
|
34
|
+
# For emacs:
|
35
|
+
#*~
|
36
|
+
#\#*
|
37
|
+
#.\#*
|
38
|
+
#
|
39
|
+
# For vim:
|
40
|
+
#*.swp
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
This program is free software: you can redistribute it and/or modify
|
2
|
+
it under the terms of the GNU General Public License as published by
|
3
|
+
the Free Software Foundation, either version 3 of the License, or
|
4
|
+
(at your option) any later version.
|
5
|
+
|
6
|
+
This program is distributed in the hope that it will be useful,
|
7
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
8
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
9
|
+
GNU General Public License for more details.
|
10
|
+
|
11
|
+
You should have received a copy of the GNU General Public License
|
12
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/README
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Net::DHCP library for ruby, originally written by etd.
|
2
|
+
Fork to github by syonbori.
|
3
|
+
Additional fork and gemification by mjtko.
|
4
|
+
|
5
|
+
Here is original README:
|
6
|
+
The svn repository for Net::DHCP contains the project files to use with NetBeans IDE.
|
7
|
+
|
8
|
+
Use "rake" in the /lib folder to generate rdoc documentation.
|
9
|
+
|
10
|
+
Expect lots of changes in the near future both to the folder structure and the project architecture :)
|
11
|
+
|
12
|
+
Have fun,
|
13
|
+
|
14
|
+
etd
|
data/README.etd.original
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The svn repository for Net::DHCP contains the project files to use with NetBeans IDE.
|
2
|
+
|
3
|
+
Use "rake" in the /lib folder to generate rdoc documentation.
|
4
|
+
|
5
|
+
Expect lots of changes in the near future both to the folder structure and the project architecture :)
|
6
|
+
|
7
|
+
Have fun,
|
8
|
+
|
9
|
+
etd
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler'
|
5
|
+
rescue LoadError
|
6
|
+
$stderr.puts "You must install bundler - run `gem install bundler`"
|
7
|
+
end
|
8
|
+
|
9
|
+
begin
|
10
|
+
Bundler.setup
|
11
|
+
rescue Bundler::BundlerError => e
|
12
|
+
$stderr.puts e.message
|
13
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
14
|
+
exit e.status_code
|
15
|
+
end
|
16
|
+
require 'rake'
|
17
|
+
|
18
|
+
require 'bueller'
|
19
|
+
Bueller::Tasks.new
|
20
|
+
|
21
|
+
require 'rspec/core/rake_task'
|
22
|
+
RSpec::Core::RakeTask.new(:examples) do |examples|
|
23
|
+
examples.rspec_opts = '-Ispec'
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
27
|
+
spec.rspec_opts = '-Ispec'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
task :default => :examples
|
32
|
+
|
33
|
+
require 'rdoc/task'
|
34
|
+
Rake::RDocTask.new do |rdoc|
|
35
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
36
|
+
|
37
|
+
rdoc.main = 'README.rdoc'
|
38
|
+
rdoc.rdoc_dir = 'rdoc'
|
39
|
+
rdoc.title = "net-dhcp #{version}"
|
40
|
+
rdoc.rdoc_files.include('README*')
|
41
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
42
|
+
end
|
data/bin/net-dhcp
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# main.rb
|
2
|
+
# 4 de octubre de 2007
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'dhcp'
|
6
|
+
require 'socket'
|
7
|
+
require 'pcaplet'
|
8
|
+
|
9
|
+
server_thread = Thread.new do
|
10
|
+
s = "Packets received by the filter:\n"
|
11
|
+
s << '-'*s.size + "\n"
|
12
|
+
|
13
|
+
dhcpdump = Pcaplet.new('-s 4096')
|
14
|
+
|
15
|
+
DHCP_PACKET = Pcap::Filter.new('port 67 or port 68', dhcpdump.capture)
|
16
|
+
|
17
|
+
dhcpdump.add_filter(DHCP_PACKET)
|
18
|
+
dhcpdump.each_packet {|pkt|
|
19
|
+
msg = DHCP::Message.from_udp_payload(pkt.udp_data)
|
20
|
+
|
21
|
+
s << "#{pkt.src}:#{pkt.sport} > #{pkt.dst}:#{pkt.dport}\n"
|
22
|
+
s << msg.to_s
|
23
|
+
puts s if s
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
discover = DHCP::Discover.new
|
28
|
+
payload = discover.pack
|
29
|
+
|
30
|
+
|
31
|
+
sckt = UDPSocket.new
|
32
|
+
sckt.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST,true)
|
33
|
+
sckt.bind('', 68)
|
34
|
+
sckt.send(payload, 0, "<broadcast>", 67)
|
35
|
+
|
36
|
+
trap('INT') {server_thread.kill}
|
37
|
+
server_thread.join
|
data/lib/net-dhcp.rb
ADDED
data/lib/net/dhcp.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
=begin
|
2
|
+
**
|
3
|
+
** dhcp.rb
|
4
|
+
** 31/OCT/2007
|
5
|
+
** ETD-Software
|
6
|
+
** - Daniel Martin Gomez <etd[-at-]nomejortu.com>
|
7
|
+
**
|
8
|
+
** Desc:
|
9
|
+
** This package provides a set of classes to work with the DHCP protocol. They
|
10
|
+
** provide low level access to all the fields and internals of the protocol.
|
11
|
+
**
|
12
|
+
** See the provided rdoc comments for further information.
|
13
|
+
**
|
14
|
+
** More information in:
|
15
|
+
** - rfc2131: Dynamic Host Configuration Protocol
|
16
|
+
** - rfc2132: DHCP Options and BOOTP Vendor Extensions
|
17
|
+
** - rfc2563: DHCP Option to Disable Stateless Auto-Configuration in
|
18
|
+
** IPv4 Clients
|
19
|
+
** - rfc4578: DHCP Options for the Intel Preboot eXecution Environment (PXE)
|
20
|
+
** - rfc4702: The DHCP Client Fully Qualified Domain Name (FQDN) Option
|
21
|
+
**
|
22
|
+
** Version:
|
23
|
+
** v1.0 [31/October/2007]: first released
|
24
|
+
**
|
25
|
+
** License:
|
26
|
+
** This program is free software: you can redistribute it and/or modify
|
27
|
+
** it under the terms of the GNU General Public License as published by
|
28
|
+
** the Free Software Foundation, either version 3 of the License, or
|
29
|
+
** (at your option) any later version.
|
30
|
+
**
|
31
|
+
** This program is distributed in the hope that it will be useful,
|
32
|
+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
33
|
+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
34
|
+
** GNU General Public License for more details.
|
35
|
+
**
|
36
|
+
** You should have received a copy of the GNU General Public License
|
37
|
+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
38
|
+
**
|
39
|
+
=end
|
40
|
+
|
41
|
+
# constants defining the values in the different fields of the protocols
|
42
|
+
require 'net/dhcp/constants'
|
43
|
+
|
44
|
+
# DHCP options as defined in rfc2132 and rfc2563
|
45
|
+
require 'net/dhcp/options'
|
46
|
+
|
47
|
+
# DHCP messages as defined in rfc2131
|
48
|
+
require 'net/dhcp/core'
|
@@ -0,0 +1,182 @@
|
|
1
|
+
=begin
|
2
|
+
**
|
3
|
+
** constants.rb
|
4
|
+
** 04/OCT/2007
|
5
|
+
** ETD-Software
|
6
|
+
** - Daniel Martin Gomez <etd[-at-]nomejortu.com>
|
7
|
+
**
|
8
|
+
** Desc:
|
9
|
+
** This file provides a set of classes to work with the DHCP protocol. They
|
10
|
+
** provide low level access to all the fields and internals of the protocol.
|
11
|
+
**
|
12
|
+
** See the provided rdoc comments for further information.
|
13
|
+
**
|
14
|
+
** More information in:
|
15
|
+
** - rfc2131: Dynamic Host Configuration Protocol
|
16
|
+
** - rfc2132: DHCP Options and BOOTP Vendor Extensions
|
17
|
+
** - rfc2563: DHCP Option to Disable Stateless Auto-Configuration in
|
18
|
+
** IPv4 Clients
|
19
|
+
**
|
20
|
+
** Version:
|
21
|
+
** v1.0 [04/October/2007]: first released
|
22
|
+
**
|
23
|
+
** License:
|
24
|
+
** Please see dhcp.rb or LICENSE.txt for copyright and licensing information.
|
25
|
+
**
|
26
|
+
=end
|
27
|
+
|
28
|
+
# --------------------------------------------------------------- dhcp messages
|
29
|
+
|
30
|
+
# operations ('op' field)
|
31
|
+
$DHCP_OP_REQUEST= 0x01
|
32
|
+
$DHCP_OP_REPLY= 0x02
|
33
|
+
|
34
|
+
# message types
|
35
|
+
$DHCP_MSG_DISCOVER= 0x01
|
36
|
+
$DHCP_MSG_OFFER= 0x02
|
37
|
+
$DHCP_MSG_REQUEST= 0x03
|
38
|
+
$DHCP_MSG_DECLINE= 0x04
|
39
|
+
$DHCP_MSG_ACK= 0x05
|
40
|
+
$DHCP_MSG_NACK= 0x06
|
41
|
+
$DHCP_MSG_RELEASE= 0x07
|
42
|
+
$DHCP_MSG_INFORM= 0x08
|
43
|
+
$DHCP_MSG_NAMES = [
|
44
|
+
'DHCP Discover',
|
45
|
+
'DHCP Offer',
|
46
|
+
'DHCP Request',
|
47
|
+
'DHCP Decline',
|
48
|
+
'DHCP ACK',
|
49
|
+
'DHCP NAK',
|
50
|
+
'DHCP Release',
|
51
|
+
'DHCP Inform'
|
52
|
+
]
|
53
|
+
|
54
|
+
# ---------------------------------------------------------------- other fields
|
55
|
+
|
56
|
+
# hardware types. see "Number Hardware Type (hrd)" in rfc 1700.
|
57
|
+
$DHCP_HTYPE_ETHERNET = 0x01
|
58
|
+
$DHCP_HLEN_ETHERNET = 0x06
|
59
|
+
|
60
|
+
|
61
|
+
$DHCP_MAGIC= 0x63825363
|
62
|
+
$BOOTP_MIN_LEN= 0x12c
|
63
|
+
$DHCP_PAD= 0x00
|
64
|
+
|
65
|
+
# as defined in rfc2132
|
66
|
+
$DHCP_SUBNETMASK= 0x01
|
67
|
+
$DHCP_TIMEOFFSET= 0x02
|
68
|
+
$DHCP_ROUTER= 0x03
|
69
|
+
$DHCP_TIMESERVER= 0x04
|
70
|
+
$DHCP_NAMESERVER= 0x05
|
71
|
+
$DHCP_DNS= 0x06
|
72
|
+
$DHCP_LOGSERV= 0x07
|
73
|
+
#$DHCP_COOKIESERV= 0x08
|
74
|
+
$DHCP_QUOTESSERV= 0x08
|
75
|
+
$DHCP_LPRSERV= 0x09
|
76
|
+
$DHCP_IMPSERV= 0x0a
|
77
|
+
$DHCP_RESSERV= 0x0b
|
78
|
+
$DHCP_HOSTNAME= 0x0c
|
79
|
+
$DHCP_BOOTFILESIZE= 0x0d
|
80
|
+
$DHCP_DUMPFILE= 0x0e
|
81
|
+
$DHCP_DOMAINNAME= 0x0f
|
82
|
+
$DHCP_SWAPSERV= 0x10
|
83
|
+
$DHCP_ROOTPATH= 0x11
|
84
|
+
$DHCP_EXTENPATH= 0x12
|
85
|
+
$DHCP_IPFORWARD= 0x13
|
86
|
+
$DHCP_SRCROUTE= 0x14
|
87
|
+
$DHCP_POLICYFILTER= 0x15
|
88
|
+
$DHCP_MAXASMSIZE= 0x16
|
89
|
+
$DHCP_IPTTL= 0x17
|
90
|
+
$DHCP_MTUTIMEOUT= 0x18
|
91
|
+
$DHCP_MTUTABLE= 0x19
|
92
|
+
$DHCP_MTUSIZE= 0x1a
|
93
|
+
$DHCP_LOCALSUBNETS= 0x1b
|
94
|
+
$DHCP_BROADCASTADDR= 0x1c
|
95
|
+
$DHCP_DOMASKDISCOV= 0x1d
|
96
|
+
$DHCP_MASKSUPPLY= 0x1e
|
97
|
+
$DHCP_DOROUTEDISC= 0x1f
|
98
|
+
$DHCP_ROUTERSOLICIT= 0x20
|
99
|
+
$DHCP_STATICROUTE= 0x21
|
100
|
+
$DHCP_TRAILERENCAP= 0x22
|
101
|
+
$DHCP_ARPTIMEOUT= 0x23
|
102
|
+
$DHCP_ETHERENCAP= 0x24
|
103
|
+
$DHCP_TCPTTL= 0x25
|
104
|
+
$DHCP_TCPKEEPALIVE= 0x26
|
105
|
+
$DHCP_TCPALIVEGARBAGE=0x27
|
106
|
+
$DHCP_NISDOMAIN= 0x28
|
107
|
+
$DHCP_NISSERVERS= 0x29
|
108
|
+
$DHCP_NISTIMESERV= 0x2a
|
109
|
+
$DHCP_VENDSPECIFIC= 0x2b
|
110
|
+
$DHCP_NBNS= 0x2c
|
111
|
+
$DHCP_NBDD= 0x2d
|
112
|
+
$DHCP_NBTCPIP= 0x2e
|
113
|
+
$DHCP_NBTCPSCOPE= 0x2f
|
114
|
+
$DHCP_XFONT= 0x30
|
115
|
+
$DHCP_XDISPLAYMGR= 0x31
|
116
|
+
$DHCP_DISCOVERADDR= 0x32
|
117
|
+
$DHCP_LEASETIME= 0x33
|
118
|
+
$DHCP_OPTIONOVERLOAD= 0x34
|
119
|
+
$DHCP_MESSAGETYPE= 0x35
|
120
|
+
$DHCP_SERVIDENT= 0x36
|
121
|
+
$DHCP_PARAMREQUEST= 0x37
|
122
|
+
$DHCP_MESSAGE= 0x38
|
123
|
+
$DHCP_MAXMSGSIZE= 0x39
|
124
|
+
$DHCP_RENEWTIME= 0x3a
|
125
|
+
$DHCP_REBINDTIME= 0x3b
|
126
|
+
$DHCP_CLASSSID= 0x3c
|
127
|
+
$DHCP_CLIENTID= 0x3d
|
128
|
+
$DHCP_NISPLUSDOMAIN= 0x40
|
129
|
+
$DHCP_NISPLUSSERVERS= 0x41
|
130
|
+
$DHCP_TFTPSERVER= 0x42
|
131
|
+
$DHCP_BOOTFILENAME= 0x43
|
132
|
+
$DHCP_MOBILEIPAGENT= 0x44
|
133
|
+
$DHCP_SMTPSERVER= 0x45
|
134
|
+
$DHCP_POP3SERVER= 0x46
|
135
|
+
$DHCP_NNTPSERVER= 0x47
|
136
|
+
$DHCP_WWWSERVER= 0x48
|
137
|
+
$DHCP_FINGERSERVER= 0x49
|
138
|
+
$DHCP_IRCSERVER= 0x4a
|
139
|
+
$DHCP_STSERVER= 0x4b
|
140
|
+
$DHCP_STDASERVER= 0x4c
|
141
|
+
$DHCP_USERCLASS= 0x4d
|
142
|
+
$DHCP_PRIVATE= 0xaf
|
143
|
+
$DHCP_END= 0xff
|
144
|
+
# / as defined in rfc2132
|
145
|
+
|
146
|
+
# see http://www.bind9.net/bootp-dhcp-parameters
|
147
|
+
|
148
|
+
$DHCP_CLIENTFQDN= 0x51 #rfc4702
|
149
|
+
|
150
|
+
|
151
|
+
$DHCP_CLIENTARCH= 0x5d #rfc4578
|
152
|
+
$DHCP_CLIENTARCH_I386= 0x0000
|
153
|
+
$DHCP_CLIENTARCH_PC98= 0x0001
|
154
|
+
$DHCP_CLIENTARCH_ITANIUM= 0x0002
|
155
|
+
$DHCP_CLIENTARCH_ALPHA= 0x0003
|
156
|
+
$DHCP_CLIENTARCH_X86= 0x0004
|
157
|
+
$DHCP_CLIENTARCH_ILC= 0x0005
|
158
|
+
$DHCP_CLIENTARCH_IA32= 0x0006
|
159
|
+
$DHCP_CLIENTARCH_BC= 0x0007
|
160
|
+
$DHCP_CLIENTARCH_XSCALE= 0x0008
|
161
|
+
$DHCP_CLIENTARCH_X8664= 0x0009
|
162
|
+
$DHCP_CLIENTARCH_NAMES = [
|
163
|
+
'Intel x86PC',
|
164
|
+
'NEC/PC98',
|
165
|
+
'EFI Itanium',
|
166
|
+
'DEC Alpha',
|
167
|
+
'Arc x86',
|
168
|
+
'Intel Lean Client',
|
169
|
+
'EFI IA32',
|
170
|
+
'EFI BC',
|
171
|
+
'EFI Xscale',
|
172
|
+
'EFI x86-64',
|
173
|
+
]
|
174
|
+
|
175
|
+
$DHCP_CLIENTNDI= 0x5e #rfc4578
|
176
|
+
#$DHCP_LDAP= 0x5f
|
177
|
+
$DHCP_UUIDGUID= 0x61 #rfc4578
|
178
|
+
|
179
|
+
$DHCP_AUTOCONF= 0x74 #rfc2563
|
180
|
+
$DHCP_AUTOCONF_NO= 0x00 #rfc2563
|
181
|
+
$DHCP_AUTOCONF_YES= 0x01 #rfc2563
|
182
|
+
|
@@ -0,0 +1,322 @@
|
|
1
|
+
=begin
|
2
|
+
**
|
3
|
+
** core.rb
|
4
|
+
** 02/OCT/2007
|
5
|
+
** ETD-Software
|
6
|
+
** - Daniel Martin Gomez <etd[-at-]nomejortu.com>
|
7
|
+
**
|
8
|
+
** Desc:
|
9
|
+
** This file provides a set of classes to work with the DHCP protocol. They
|
10
|
+
** provide low level access to all the fields and internals of the protocol.
|
11
|
+
**
|
12
|
+
** See the provided rdoc comments for further information.
|
13
|
+
**
|
14
|
+
** Version:
|
15
|
+
** v1.0 [02/October/2007]: first released
|
16
|
+
** v1.1 [31/October/2007]: file moved under /dhcp/ directory and renamed to
|
17
|
+
** core.rb. Now it only contains core classes to
|
18
|
+
** encapsulate DHCP messages
|
19
|
+
**
|
20
|
+
** License:
|
21
|
+
** Please see dhcp.rb or LICENSE.txt for copyright and licensing information.
|
22
|
+
**
|
23
|
+
=end
|
24
|
+
|
25
|
+
module DHCP
|
26
|
+
# -------------------------------------------------------------- dhcp messages
|
27
|
+
class Message
|
28
|
+
attr_accessor :op, :htype, :hlen, :hops
|
29
|
+
attr_accessor :xid
|
30
|
+
attr_accessor :secs, :flags
|
31
|
+
attr_accessor :ciaddr, :yiaddr, :siaddr, :giaddr, :chaddr
|
32
|
+
attr_accessor :options
|
33
|
+
|
34
|
+
alias == eql?
|
35
|
+
|
36
|
+
def Message.from_udp_payload(data)
|
37
|
+
values = data.unpack('C4Nn2N4C16C192NC*')
|
38
|
+
|
39
|
+
params = {
|
40
|
+
:op => values.shift,
|
41
|
+
:htype => values.shift,
|
42
|
+
:hlen => values.shift,
|
43
|
+
:hops => values.shift,
|
44
|
+
|
45
|
+
:xid => values.shift,
|
46
|
+
:secs => values.shift,
|
47
|
+
:flags => values.shift,
|
48
|
+
:ciaddr => values.shift,
|
49
|
+
:yiaddr => values.shift,
|
50
|
+
:siaddr => values.shift,
|
51
|
+
:giaddr => values.shift,
|
52
|
+
:chaddr => values.slice!(0..15)
|
53
|
+
}
|
54
|
+
|
55
|
+
# sname and file
|
56
|
+
not_used = values.slice!(0..191)
|
57
|
+
|
58
|
+
return nil unless ($DHCP_MAGIC == values.shift)
|
59
|
+
|
60
|
+
#default message class
|
61
|
+
msg_class = Message
|
62
|
+
#default option class
|
63
|
+
opt_class = Option
|
64
|
+
|
65
|
+
params[:options] = []
|
66
|
+
|
67
|
+
next_opt = values.shift
|
68
|
+
while(next_opt != $DHCP_END)
|
69
|
+
p = {
|
70
|
+
:type => next_opt,
|
71
|
+
:len => values.shift
|
72
|
+
}
|
73
|
+
p[:payload] = values.slice!(0..p[:len]-1)
|
74
|
+
|
75
|
+
# check what is the type of dhcp option
|
76
|
+
opt_class = $DHCP_MSG_OPTIONS[p[:type]]
|
77
|
+
if(opt_class.nil?)
|
78
|
+
puts '-------------------- please further investigate!!'
|
79
|
+
puts p[:type]
|
80
|
+
puts '-------------------- /'
|
81
|
+
opt_class == Option
|
82
|
+
end
|
83
|
+
if (opt_class == MessageTypeOption)
|
84
|
+
msg_class = $DHCP_MSG_CLASSES[p[:payload].first]
|
85
|
+
end
|
86
|
+
params[:options] << opt_class.new(p)
|
87
|
+
next_opt = values.shift
|
88
|
+
end
|
89
|
+
|
90
|
+
if(msg_class.nil?)
|
91
|
+
puts '-------------------- please further investigate!!'
|
92
|
+
p params[:options]
|
93
|
+
puts '-------------------- /'
|
94
|
+
opt_class == Option
|
95
|
+
end
|
96
|
+
msg_class.new(params)
|
97
|
+
end
|
98
|
+
|
99
|
+
def initialize(params = {})
|
100
|
+
|
101
|
+
# message operation and options. We need at least an operation and a
|
102
|
+
# MessageTypeOption to create a DHCP message!!
|
103
|
+
if (([:op, :options] & params.keys).size != 2)
|
104
|
+
raise ArgumentError('you need to specify at least values for :op and :options')
|
105
|
+
end
|
106
|
+
|
107
|
+
self.op = params[:op]
|
108
|
+
|
109
|
+
self.options = params[:options]
|
110
|
+
found = false
|
111
|
+
self.options.each do |opt|
|
112
|
+
next unless opt.class == MessageTypeOption
|
113
|
+
found = true
|
114
|
+
end
|
115
|
+
raise ArgumentError(':options must include a MessageTypeOption') unless found
|
116
|
+
|
117
|
+
#hardware type and length of the hardware address
|
118
|
+
self.htype = params.fetch(:htype, $DHCP_HTYPE_ETHERNET)
|
119
|
+
self.hlen = params.fetch(:hlen, $DHCP_HLEN_ETHERNET)
|
120
|
+
|
121
|
+
# client sets to zero. relay agents may modify
|
122
|
+
self.hops = params.fetch(:hops, 0x00)
|
123
|
+
|
124
|
+
# initialize a random transaction ID
|
125
|
+
self.xid = params.fetch(:xid, rand(2**32))
|
126
|
+
|
127
|
+
# seconds elapsed, flags
|
128
|
+
self.secs = params.fetch(:secs, 0x0000)
|
129
|
+
self.flags = params.fetch(:flags, 0x0000)
|
130
|
+
|
131
|
+
# client, you, next server and relay agent addresses
|
132
|
+
self.ciaddr = params.fetch(:ciaddr, 0x00000000)
|
133
|
+
self.yiaddr = params.fetch(:yiaddr, 0x00000000)
|
134
|
+
self.siaddr = params.fetch(:siaddr, 0x00000000)
|
135
|
+
self.giaddr = params.fetch(:giaddr, 0x00000000)
|
136
|
+
|
137
|
+
if (params.key?(:chaddr))
|
138
|
+
self.chaddr = params[:chaddr]
|
139
|
+
raise 'chaddr field should be of 16 bytes' unless self.chaddr.size == 16
|
140
|
+
else
|
141
|
+
mac = `/sbin/ifconfig | grep HWaddr | cut -c39- | head -1`.chomp.strip.gsub(/:/,'')
|
142
|
+
self.chaddr = [mac].pack('H*').unpack('CCCCCC')
|
143
|
+
self.chaddr += [0x00]*(16-self.chaddr.size)
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
def pack()
|
150
|
+
out = [
|
151
|
+
self.op, self.htype, self.hlen, self.hops,
|
152
|
+
self.xid,
|
153
|
+
self.secs, self.flags,
|
154
|
+
self.ciaddr,
|
155
|
+
self.yiaddr,
|
156
|
+
self.siaddr,
|
157
|
+
self.giaddr
|
158
|
+
].pack('C4Nn2N4')
|
159
|
+
|
160
|
+
out << self.chaddr.pack('C*')
|
161
|
+
|
162
|
+
|
163
|
+
# sname and file
|
164
|
+
out << ([0x00]*192).pack('C192')
|
165
|
+
|
166
|
+
out << [$DHCP_MAGIC].pack('N')
|
167
|
+
self.options.each do |option|
|
168
|
+
out << option.pack
|
169
|
+
end
|
170
|
+
out << [$DHCP_END].pack('C')
|
171
|
+
|
172
|
+
# add padding up to 300 bytes
|
173
|
+
if out.size < 300
|
174
|
+
out << ([$DHCP_PAD]*(300-out.size)).pack('C*')
|
175
|
+
end
|
176
|
+
return out
|
177
|
+
end
|
178
|
+
|
179
|
+
def eql?(obj)
|
180
|
+
# objects must be of the same class
|
181
|
+
return false unless (self.class == obj.class)
|
182
|
+
|
183
|
+
vars1 = self.instance_variables
|
184
|
+
|
185
|
+
# first make sure that the :options var is equal
|
186
|
+
opt1 = self.instance_variable_get('@options')
|
187
|
+
opt2 = obj.instance_variable_get('@options')
|
188
|
+
|
189
|
+
return false unless opt1.eql?(opt2)
|
190
|
+
vars1.delete('@options')
|
191
|
+
|
192
|
+
# check all the other instance vairables
|
193
|
+
vars1.each do |var|
|
194
|
+
return false unless (self.instance_variable_get(var) == obj.instance_variable_get(var))
|
195
|
+
end
|
196
|
+
|
197
|
+
return true
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
def to_s
|
203
|
+
out = "DHCP Message\r\n"
|
204
|
+
out << "\tFIELDS:\r\n"
|
205
|
+
out << "\t\tTransaction ID = #{self.xid}\r\n"
|
206
|
+
out << "\t\tClient IP address = #{[self.ciaddr].pack('N').unpack('C4').join('.')}\r\n"
|
207
|
+
out << "\t\tYour IP address = #{[self.yiaddr].pack('N').unpack('C4').join('.')}\r\n"
|
208
|
+
out << "\t\tNext server IP address = #{[self.siaddr].pack('N').unpack('C4').join('.')}\r\n"
|
209
|
+
out << "\t\tRelay agent IP address = #{[self.giaddr].pack('N').unpack('C4').join('.')}\r\n"
|
210
|
+
out << "\t\tHardware address = #{self.chaddr.slice(0..(self.hlen-1)).collect do |b| b.to_s(16).upcase.rjust(2,'0') end.join(':')}\r\n"
|
211
|
+
out << "\tOPT:\r\n"
|
212
|
+
self.options.each do |opt|
|
213
|
+
out << "\t\t #{opt.to_s}\r\n"
|
214
|
+
end
|
215
|
+
return out
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Client broadcast to locate available servers.
|
220
|
+
class Discover < Message
|
221
|
+
def initialize(params={})
|
222
|
+
params[:op] = $DHCP_OP_REQUEST
|
223
|
+
# if an :options field is provided, we use it, otherwise, a default is set
|
224
|
+
params[:options] = params.fetch(:options, [MessageTypeOption.new, ParameterRequestListOption.new])
|
225
|
+
super(params)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Server to client in response to DHCPDISCOVER with offer of configuration
|
230
|
+
# parameters.
|
231
|
+
#
|
232
|
+
# By default an ACK message will contain a Server Identifier (0.0.0.0) and
|
233
|
+
# a Domain Name ('nomejortu.com') option.
|
234
|
+
class Offer < Message
|
235
|
+
def initialize(params={})
|
236
|
+
params[:op] = $DHCP_OP_REPLY
|
237
|
+
params[:options] = params.fetch(:options, [
|
238
|
+
MessageTypeOption.new({:payload=>$DHCP_MSG_OFFER}),
|
239
|
+
ServerIdentifierOption.new,
|
240
|
+
DomainNameOption.new
|
241
|
+
])
|
242
|
+
super(params)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Client message to servers either (a) requesting offered parameters from one
|
247
|
+
# server and implicitly declining offers from all others, (b) confirming
|
248
|
+
# correctness of previously allocated address after, e.g., system reboot, or
|
249
|
+
# (c) extending the lease on a particular network address.
|
250
|
+
class Request < Message
|
251
|
+
def initialize(params={})
|
252
|
+
params[:op] = $DHCP_OP_REQUEST
|
253
|
+
params[:options] = params.fetch(:options, [MessageTypeOption.new({:payload=>$DHCP_MSG_REQUEST}), ParameterRequestListOption.new])
|
254
|
+
super(params)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
#
|
259
|
+
# DHCPDECLINE - Client to server indicating network address is already
|
260
|
+
# in use.
|
261
|
+
|
262
|
+
# Server to client with configuration parameters, including committed network
|
263
|
+
# address.
|
264
|
+
#
|
265
|
+
# By default an ACK message will contain a Server Identifier (0.0.0.0) and
|
266
|
+
# a Domain Name ('nomejortu.com') option.
|
267
|
+
class ACK < Message
|
268
|
+
def initialize(params={})
|
269
|
+
params[:op] = $DHCP_OP_REPLY
|
270
|
+
params[:options] = params.fetch(:options, [
|
271
|
+
MessageTypeOption.new({:payload=>$DHCP_MSG_ACK}),
|
272
|
+
ServerIdentifierOption.new,
|
273
|
+
DomainNameOption.new
|
274
|
+
])
|
275
|
+
super(params)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# DHCPNAK - Server to client indicating client's notion of network
|
280
|
+
# address is incorrect (e.g., client has moved to new
|
281
|
+
# subnet) or client's lease as expired
|
282
|
+
|
283
|
+
# Client to server relinquishing network address and cancelling remaining
|
284
|
+
# lease.
|
285
|
+
#
|
286
|
+
# By default an ACK message will contain a Server Identifier (0.0.0.0)
|
287
|
+
class Release < Message
|
288
|
+
def initialize(params={})
|
289
|
+
params[:op] = $DHCP_OP_REQUEST
|
290
|
+
params[:options] = params.fetch(:options, [
|
291
|
+
MessageTypeOption.new({:payload=>$DHCP_MSG_RELEASE}),
|
292
|
+
ServerIdentifierOption.new
|
293
|
+
])
|
294
|
+
super(params)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Client to server, asking only for local configuration parameters; client
|
299
|
+
# already has externally configured network address.
|
300
|
+
class Inform < Message
|
301
|
+
def initialize(params={})
|
302
|
+
params[:op] = $DHCP_OP_REQUEST
|
303
|
+
params[:options] = params.fetch(:options, [MessageTypeOption.new({:payload=>$DHCP_MSG_INFORM}), ParameterRequestListOption.new])
|
304
|
+
super(params)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# ------------------------------------ map from values of fields to class names
|
309
|
+
|
310
|
+
$DHCP_MSG_CLASSES = {
|
311
|
+
$DHCP_MSG_DISCOVER => Discover,
|
312
|
+
$DHCP_MSG_OFFER => Offer,
|
313
|
+
$DHCP_MSG_REQUEST => Request,
|
314
|
+
# $DHCP_MSG_DECLINE= 0x04
|
315
|
+
$DHCP_MSG_ACK => ACK,
|
316
|
+
# $DHCP_MSG_NACK= 0x06
|
317
|
+
$DHCP_MSG_RELEASE => Release,
|
318
|
+
$DHCP_MSG_INFORM => Inform
|
319
|
+
}
|
320
|
+
|
321
|
+
|
322
|
+
end
|