net-dhcp 1.0.0

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/.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
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in net-dhcp.gemspec
4
+ gemspec
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
@@ -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
@@ -0,0 +1,2 @@
1
+ require 'net-dhcp/version'
2
+ require 'net/dhcp'
@@ -0,0 +1,5 @@
1
+ module Net
2
+ module Dhcp
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
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