net-dhcp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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