dhcpsapi 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/lib/dhcpsapi/class.rb +3 -77
- data/lib/dhcpsapi/client.rb +7 -130
- data/lib/dhcpsapi/common.rb +1 -8
- data/lib/dhcpsapi/data_structures.rb +654 -0
- data/lib/dhcpsapi/misc.rb +6 -18
- data/lib/dhcpsapi/option.rb +26 -112
- data/lib/dhcpsapi/option_value.rb +13 -183
- data/lib/dhcpsapi/reservation.rb +3 -63
- data/lib/dhcpsapi/server.rb +30 -1
- data/lib/dhcpsapi/subnet.rb +6 -80
- data/lib/dhcpsapi/version.rb +1 -1
- data/lib/dhcpsapi/win2008/class.rb +38 -0
- data/lib/dhcpsapi/win2008/client.rb +41 -0
- data/lib/dhcpsapi/win2008/free_memory.rb +14 -0
- data/lib/dhcpsapi/win2008/option.rb +57 -0
- data/lib/dhcpsapi/win2008/option_value.rb +61 -0
- data/lib/dhcpsapi/win2008/subnet.rb +46 -0
- data/lib/dhcpsapi/win2008/subnet_element.rb +26 -0
- data/lib/dhcpsapi/win2012/client.rb +21 -0
- data/lib/dhcpsapi/win2012/misc.rb +19 -0
- data/lib/dhcpsapi/win2012/reservation.rb +20 -0
- data/lib/dhcpsapi.rb +4 -6
- metadata +27 -21
- data/lib/dhcpsapi/common_data_structs.rb +0 -267
- data/lib/dhcpsapi/ffi.rb +0 -6
- data/lib/dhcpsapi/subnet_element.rb +0 -45
- data/lib/dhcpsapi_for_testing/server.rb +0 -9
- data/lib/dhcpsapi_for_testing.rb +0 -3
@@ -0,0 +1,654 @@
|
|
1
|
+
module DhcpsApi
|
2
|
+
#
|
3
|
+
# Data Streuctures available in Windows2008 and earlier versions of Windows
|
4
|
+
#
|
5
|
+
|
6
|
+
=begin
|
7
|
+
typedef struct _DHCP_IP_ARRAY {
|
8
|
+
DWORD NumElements;
|
9
|
+
LPDHCP_IP_ADDRESS Elements;
|
10
|
+
} DHCP_IP_ARRAY, *LPDHCP_IP_ARRAY;
|
11
|
+
=end
|
12
|
+
class DHCP_IP_ARRAY < DHCPS_Struct
|
13
|
+
layout :num_elements, :uint32,
|
14
|
+
:elements, :pointer
|
15
|
+
end
|
16
|
+
|
17
|
+
=begin
|
18
|
+
typedef struct _DHCP_HOST_INFO {
|
19
|
+
DHCP_IP_ADDRESS IpAddress;
|
20
|
+
LPWSTR NetBiosName;
|
21
|
+
LPWSTR HostName;
|
22
|
+
} DHCP_HOST_INFO, *LPDHCP_HOST_INFO;
|
23
|
+
=end
|
24
|
+
class DHCP_HOST_INFO < DHCPS_Struct
|
25
|
+
layout :ip_address, :uint32,
|
26
|
+
:net_bios_name, :pointer,
|
27
|
+
:host_name, :pointer
|
28
|
+
|
29
|
+
ruby_struct_attr :uint32_to_ip, :ip_address
|
30
|
+
ruby_struct_attr :to_string, :net_bios_name, :host_name
|
31
|
+
end
|
32
|
+
|
33
|
+
=begin
|
34
|
+
typedef struct _DHCP_BINARY_DATA {
|
35
|
+
DWORD DataLength;
|
36
|
+
BYTE *Data;
|
37
|
+
} DHCP_BINARY_DATA, *LPDHCP_BINARY_DATA, DHCP_CLIENT_UID;
|
38
|
+
=end
|
39
|
+
class DHCP_CLIENT_UID < DHCPS_Struct
|
40
|
+
layout :data_length, :uint32,
|
41
|
+
:data, :pointer
|
42
|
+
|
43
|
+
def self.from_mac_address(mac_address)
|
44
|
+
to_return = new
|
45
|
+
mac_as_uint8s = to_return.mac_address_to_array_of_uint8(mac_address)
|
46
|
+
to_return[:data_length] = mac_as_uint8s.size
|
47
|
+
to_return[:data] = FFI::MemoryPointer.new(:uint8, mac_as_uint8s.size)
|
48
|
+
to_return[:data].write_array_of_uint8(mac_as_uint8s)
|
49
|
+
to_return
|
50
|
+
end
|
51
|
+
|
52
|
+
def intialize_with_mac_address(mac_address)
|
53
|
+
mac_as_uint8s = mac_address_to_array_of_uint8(mac_address)
|
54
|
+
self[:data_length] = mac_as_uint8s.size
|
55
|
+
self[:data] = FFI::MemoryPointer.new(:uint8, mac_as_uint8s.size)
|
56
|
+
self[:data].write_array_of_uint8(mac_as_uint8s)
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize_with_subnet_and_mac_addresses(subnet_address, mac_address)
|
61
|
+
mac_as_uint8s = mac_address_to_array_of_uint8(mac_address)
|
62
|
+
subnet_as_uint8s = subnet_address.split('.').reverse.map {|octet| octet.to_i}
|
63
|
+
self[:data_length] = 11
|
64
|
+
self[:data] = FFI::MemoryPointer.new(:uint8, 11)
|
65
|
+
self[:data].write_array_of_uint8(subnet_as_uint8s + [0x1] + mac_as_uint8s)
|
66
|
+
end
|
67
|
+
|
68
|
+
def data_as_ruby_struct_attr
|
69
|
+
self[:data].read_array_of_type(:uint8, :read_uint8, self[:data_length]).map {|w| "%02X" % w}.join(":")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class DHCP_BINARY_DATA < DHCPS_Struct
|
74
|
+
layout :data_length, :uint32,
|
75
|
+
:data, :pointer
|
76
|
+
|
77
|
+
def self.from_data(data)
|
78
|
+
to_return = new
|
79
|
+
to_return[:data_length] = data.size
|
80
|
+
to_return[:data] = FFI::MemoryPointer.new(:uint8, data.size)
|
81
|
+
to_return[:data].write_array_of_uint8(data)
|
82
|
+
to_return
|
83
|
+
end
|
84
|
+
|
85
|
+
def data_as_ruby_struct_attr
|
86
|
+
self[:data].read_array_of_type(:uint8, :read_uint8, self[:data_length])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
=begin
|
91
|
+
typedef struct _DATE_TIME {
|
92
|
+
DWORD dwLowDateTime;
|
93
|
+
DWORD dwHighDateTime;
|
94
|
+
} DATE_TIME, *LPDATE_TIME;
|
95
|
+
=end
|
96
|
+
class DATE_TIME < DHCPS_Struct
|
97
|
+
layout :dw_low_date_time, :uint32,
|
98
|
+
:dw_high_date_time, :uint32
|
99
|
+
|
100
|
+
def as_ruby_struct
|
101
|
+
tmp = self[:dw_high_date_time]
|
102
|
+
tmp = (tmp << 32) + self[:dw_low_date_time]
|
103
|
+
tmp == 0 ? nil : Time.at(tmp/10000000 - 11644473600)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class DWORD_DWORD < DHCPS_Struct
|
108
|
+
layout :dword1, :uint32,
|
109
|
+
:dword2, :uint32
|
110
|
+
|
111
|
+
def self.from_int(an_int)
|
112
|
+
to_return = new
|
113
|
+
to_return[:dword1] = ((an_int >> 32) & 0xffffffff)
|
114
|
+
to_return[:dword2] = (an_int & 0xffffffff)
|
115
|
+
to_return
|
116
|
+
end
|
117
|
+
|
118
|
+
def as_ruby_struct
|
119
|
+
(self[:dword1] << 32) | self[:dword2]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
=begin
|
124
|
+
typedef struct _DHCP_OPTION_DATA_ELEMENT {
|
125
|
+
DHCP_OPTION_DATA_TYPE OptionType;
|
126
|
+
union {
|
127
|
+
BYTE ByteOption;
|
128
|
+
WORD WordOption;
|
129
|
+
DWORD DWordOption;
|
130
|
+
DWORD_DWORD DWordDWordOption;
|
131
|
+
DHCP_IP_ADDRESS IpAddressOption;
|
132
|
+
LPWSTR StringDataOption;
|
133
|
+
DHCP_BINARY_DATA BinaryDataOption;
|
134
|
+
DHCP_BINARY_DATA EncapsulatedDataOption;
|
135
|
+
LPWSTR Ipv6AddressDataOption;
|
136
|
+
} Element;
|
137
|
+
} DHCP_OPTION_DATA_ELEMENT, *LPDHCP_OPTION_DATA_ELEMENT;
|
138
|
+
=end
|
139
|
+
class DHCP_OPTION_DATA_ELEMENT_UNION < FFI::Union
|
140
|
+
layout :byte_option, :uint8,
|
141
|
+
:word_opition, :uint16,
|
142
|
+
:dword_option, :uint32,
|
143
|
+
:dword_dword_option, DWORD_DWORD,
|
144
|
+
:ip_address_option, :uint32,
|
145
|
+
:string_data_option, :pointer,
|
146
|
+
:binary_data_option, DHCP_BINARY_DATA, # expects an array of uint8s
|
147
|
+
:encapsulated_data_option, DHCP_BINARY_DATA,
|
148
|
+
:ipv6_address_data_option, :pointer
|
149
|
+
end
|
150
|
+
|
151
|
+
class DHCP_OPTION_DATA_ELEMENT < DHCPS_Struct
|
152
|
+
layout :option_type, :uint32, # see DHCP_OPTION_DATA_TYPE
|
153
|
+
:element, DHCP_OPTION_DATA_ELEMENT_UNION
|
154
|
+
|
155
|
+
def element_as_ruby_struct_attr
|
156
|
+
case self[:option_type]
|
157
|
+
when DHCP_OPTION_DATA_TYPE::DhcpByteOption
|
158
|
+
self[:element][:byte_option]
|
159
|
+
when DHCP_OPTION_DATA_TYPE::DhcpWordOption
|
160
|
+
self[:element][:word_opition]
|
161
|
+
when DHCP_OPTION_DATA_TYPE::DhcpDWordOption
|
162
|
+
self[:element][:dword_option]
|
163
|
+
when DHCP_OPTION_DATA_TYPE::DhcpDWordDWordOption
|
164
|
+
self[:element][:dword_dword_option].as_ruby_struct
|
165
|
+
when DHCP_OPTION_DATA_TYPE::DhcpIpAddressOption
|
166
|
+
uint32_to_ip(self[:element][:ip_address_option])
|
167
|
+
when DHCP_OPTION_DATA_TYPE::DhcpStringDataOption
|
168
|
+
to_string(self[:element][:string_data_option])
|
169
|
+
when DHCP_OPTION_DATA_TYPE::DhcpBinaryDataOption
|
170
|
+
self[:element][:binary_data_option].as_ruby_struct
|
171
|
+
when DHCP_OPTION_DATA_TYPE::DhcpEncapsulatedDataOption
|
172
|
+
self[:element][:encapsulated_data_option].as_ruby_struct
|
173
|
+
when DHCP_OPTION_DATA_TYPE::DhcpIpv6AddressOption
|
174
|
+
to_string(self[:element][:ipv6_address_data_option])
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def initialize_from_data(type, data)
|
179
|
+
self[:option_type] = type
|
180
|
+
case type
|
181
|
+
when DHCP_OPTION_DATA_TYPE::DhcpByteOption
|
182
|
+
self[:element][:byte_option] = data.nil? ? 0 : data & 0xff
|
183
|
+
when DHCP_OPTION_DATA_TYPE::DhcpWordOption
|
184
|
+
self[:element][:word_opition] = data.nil? ? 0 : data & 0xffff
|
185
|
+
when DHCP_OPTION_DATA_TYPE::DhcpDWordOption
|
186
|
+
self[:element][:dword_option] = data.nil? ? 0 : data & 0xffffffff
|
187
|
+
when DHCP_OPTION_DATA_TYPE::DhcpDWordDWordOption
|
188
|
+
self[:element][:dword_dword_option] = DWORD_DWORD.from_int(data.nil? ? 0 : data)
|
189
|
+
when DHCP_OPTION_DATA_TYPE::DhcpIpAddressOption
|
190
|
+
self[:element][:ip_address_option] = data.nil? ? 0 : ip_to_uint32(data)
|
191
|
+
when DHCP_OPTION_DATA_TYPE::DhcpStringDataOption
|
192
|
+
self[:element][:string_data_option] = FFI::MemoryPointer.from_string(to_wchar_string(data.nil? ? '' : data))
|
193
|
+
when DHCP_OPTION_DATA_TYPE::DhcpBinaryDataOption
|
194
|
+
self[:element][:binary_data_option] = DHCP_BINARY_DATA.from_data(data.nil? ? [0] : data)
|
195
|
+
when DHCP_OPTION_DATA_TYPE::DhcpEncapsulatedDataOption
|
196
|
+
self[:element][:encapsulated_data_option] = DHCP_BINARY_DATA.from_data(data.nil? ? [0] : data)
|
197
|
+
when DHCP_OPTION_DATA_TYPE::DhcpIpv6AddressOption
|
198
|
+
self[:element][:ipv6_address_data_option] = FFI::MemoryPointer.from_string(to_wchar_string(data.nil? ? '' : data))
|
199
|
+
else
|
200
|
+
raise DhcpError, "Unknown dhcp option data type: #{type}"
|
201
|
+
end
|
202
|
+
|
203
|
+
self
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.initialize_from_data(type, data)
|
207
|
+
DHCP_OPTION_DATA_ELEMENT.new.initialize_from_data(type, data)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
=begin
|
212
|
+
typedef struct _DHCP_OPTION_DATA {
|
213
|
+
DWORD NumElements;
|
214
|
+
LPDHCP_OPTION_DATA_ELEMENT Elements;
|
215
|
+
} DHCP_OPTION_DATA, *LPDHCP_OPTION_DATA;
|
216
|
+
=end
|
217
|
+
class DHCP_OPTION_DATA < DHCPS_Struct
|
218
|
+
layout :num_elements, :uint32,
|
219
|
+
:elements, :pointer
|
220
|
+
|
221
|
+
def self.from_array(type, array_of_data)
|
222
|
+
to_return = new
|
223
|
+
to_return.from_array(type, array_of_data)
|
224
|
+
to_return
|
225
|
+
end
|
226
|
+
|
227
|
+
def from_array(type, array_of_data)
|
228
|
+
if array_of_data.size == 0
|
229
|
+
self[:num_elements] = 1
|
230
|
+
self[:elements] = FFI::MemoryPointer.new(DHCP_OPTION_DATA_ELEMENT, 1)
|
231
|
+
DHCP_OPTION_DATA_ELEMENT.new(self[:elements]).initialize_from_data(type, nil)
|
232
|
+
return self
|
233
|
+
end
|
234
|
+
|
235
|
+
self[:num_elements] = array_of_data.size
|
236
|
+
self[:elements] = FFI::MemoryPointer.new(DHCP_OPTION_DATA_ELEMENT, array_of_data.size)
|
237
|
+
0.upto(array_of_data.size-1) do |i|
|
238
|
+
element = DHCP_OPTION_DATA_ELEMENT.new(self[:elements] + DHCP_OPTION_DATA_ELEMENT.size*i)
|
239
|
+
element.initialize_from_data(type, array_of_data[i])
|
240
|
+
end
|
241
|
+
|
242
|
+
self
|
243
|
+
end
|
244
|
+
|
245
|
+
def as_ruby_struct
|
246
|
+
0.upto(self[:num_elements]-1).inject([]) do |all, offset|
|
247
|
+
all << DHCP_OPTION_DATA_ELEMENT.new(self[:elements] + DHCP_OPTION_DATA_ELEMENT.size*offset).as_ruby_struct
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# DHCP_CLASS_INFO data structure describes an option class.
|
254
|
+
#
|
255
|
+
# Available fields:
|
256
|
+
# :class_name [String],
|
257
|
+
# :class_comment [String],
|
258
|
+
# :is_vendor [Boolean],
|
259
|
+
# :flags [Fixnum],
|
260
|
+
# :class_data [String]
|
261
|
+
#
|
262
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd897569(v=vs.85).aspx
|
263
|
+
#
|
264
|
+
class DHCP_CLASS_INFO < DHCPS_Struct
|
265
|
+
layout :class_name, :pointer,
|
266
|
+
:class_comment, :pointer,
|
267
|
+
:class_data_length, :uint32,
|
268
|
+
:is_vendor, :bool,
|
269
|
+
:flags, :uint32,
|
270
|
+
:class_data, :pointer
|
271
|
+
|
272
|
+
ruby_struct_attr :to_string, :class_name, :class_comment, :policy_name
|
273
|
+
ruby_struct_attr :class_data_as_string, :class_data
|
274
|
+
|
275
|
+
private
|
276
|
+
def class_data_as_string(unused)
|
277
|
+
self[:class_data].read_array_of_type(:uint8, :read_uint8, self[:class_data_length])
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
#
|
282
|
+
# DHCP_CLASS_INFO data structure describes an array of option classes.
|
283
|
+
#
|
284
|
+
# Available fields:
|
285
|
+
# :num_elements [Fixnum],
|
286
|
+
# :classes [Array<Hash>]
|
287
|
+
#
|
288
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd897570(v=vs.85).aspx
|
289
|
+
#
|
290
|
+
class DHCP_CLASS_INFO_ARRAY < DHCPS_Struct
|
291
|
+
layout :num_elements, :uint32,
|
292
|
+
:classes, :pointer
|
293
|
+
end
|
294
|
+
|
295
|
+
=begin
|
296
|
+
typedef struct _DHCP_CLIENT_INFO_V4 {
|
297
|
+
DHCP_IP_ADDRESS ClientIpAddress;
|
298
|
+
DHCP_IP_MASK SubnetMask;
|
299
|
+
DHCP_CLIENT_UID ClientHardwareAddress;
|
300
|
+
LPWSTR ClientName;
|
301
|
+
LPWSTR ClientComment;
|
302
|
+
DATE_TIME ClientLeaseExpires;
|
303
|
+
DHCP_HOST_INFO OwnerHost;
|
304
|
+
BYTE bClientType;
|
305
|
+
} DHCP_CLIENT_INFO_V4, *LPDHCP_CLIENT_INFO_V4;
|
306
|
+
=end
|
307
|
+
class DHCP_CLIENT_INFO_V4 < DHCPS_Struct
|
308
|
+
layout :client_ip_address, :uint32,
|
309
|
+
:subnet_mask, :uint32,
|
310
|
+
:client_hardware_address, DHCP_CLIENT_UID,
|
311
|
+
:client_name, :pointer,
|
312
|
+
:client_comment, :pointer,
|
313
|
+
:client_lease_expires, DATE_TIME,
|
314
|
+
:owner_host, DHCP_HOST_INFO,
|
315
|
+
:client_type, :uint8 # see ClientType
|
316
|
+
|
317
|
+
ruby_struct_attr :uint32_to_ip, :client_ip_address, :subnet_mask
|
318
|
+
ruby_struct_attr :dhcp_client_uid_to_mac, :client_hardware_address
|
319
|
+
ruby_struct_attr :to_string, :client_name, :client_comment
|
320
|
+
end
|
321
|
+
|
322
|
+
=begin
|
323
|
+
typedef struct _DHCP_CLIENT_SEARCH_INFO {
|
324
|
+
DHCP_SEARCH_INFO_TYPE SearchType;
|
325
|
+
union {
|
326
|
+
DHCP_IP_ADDRESS ClientIpAddress;
|
327
|
+
DHCP_CLIENT_UID ClientHardwareAddress;
|
328
|
+
LPWSTR ClientName;
|
329
|
+
} SearchInfo;
|
330
|
+
} DHCP_SEARCH_INFO, *LPDHCP_SEARCH_INFO;
|
331
|
+
=end
|
332
|
+
class SEARCH_INFO_UNION < FFI::Union
|
333
|
+
layout :client_ip_address, :uint32,
|
334
|
+
:client_hardware_address, DHCP_CLIENT_UID,
|
335
|
+
:client_name, :pointer
|
336
|
+
end
|
337
|
+
class DHCP_SEARCH_INFO < DHCPS_Struct
|
338
|
+
layout :search_type, :uint32, # see DHCP_SEARCH_INFO_TYPE
|
339
|
+
:search_info, SEARCH_INFO_UNION
|
340
|
+
end
|
341
|
+
|
342
|
+
=begin
|
343
|
+
typedef struct _DHCP_OPTION {
|
344
|
+
DHCP_OPTION_ID OptionID;
|
345
|
+
LPWSTR OptionName;
|
346
|
+
LPWSTR OptionComment;
|
347
|
+
DHCP_OPTION_DATA DefaultValue;
|
348
|
+
DHCP_OPTION_TYPE OptionType;
|
349
|
+
} DHCP_OPTION, *LPDHCP_OPTION;
|
350
|
+
=end
|
351
|
+
class DHCP_OPTION < DHCPS_Struct
|
352
|
+
layout :option_id, :uint32,
|
353
|
+
:option_name, :pointer,
|
354
|
+
:option_comment, :pointer,
|
355
|
+
:default_value, DHCP_OPTION_DATA,
|
356
|
+
:option_type, :uint32 # see DHCP_OPTION_TYPE
|
357
|
+
|
358
|
+
ruby_struct_attr :to_string, :option_name, :option_comment
|
359
|
+
end
|
360
|
+
|
361
|
+
=begin
|
362
|
+
typedef struct _DHCP_OPTION_ARRAY {
|
363
|
+
DWORD NumElements;
|
364
|
+
LPDHCP_OPTION Options;
|
365
|
+
} DHCP_OPTION_ARRAY, *LPDHCP_OPTION_ARRAY;
|
366
|
+
=end
|
367
|
+
class DHCP_OPTION_ARRAY < DHCPS_Struct
|
368
|
+
layout :num_elements, :uint32,
|
369
|
+
:options, :pointer
|
370
|
+
|
371
|
+
def as_ruby_struct
|
372
|
+
0.upto(self[:num_elements]-1).inject([]) do |all, offset|
|
373
|
+
all << DHCP_OPTION.new(self[:options] + offset*DHCP_OPTION.size).as_ruby_struct
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
#
|
379
|
+
# DHCP_RESERVED_SCOPE data structure describes an reserved DHCP scope.
|
380
|
+
#
|
381
|
+
# Available fields:
|
382
|
+
# :reserved_ip_address [String],
|
383
|
+
# :reserved_ip_subnet_address [String]
|
384
|
+
#
|
385
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363369(v=vs.85).aspx
|
386
|
+
#
|
387
|
+
class DHCP_RESERVED_SCOPE < DHCPS_Struct
|
388
|
+
layout :reserved_ip_address, :uint32,
|
389
|
+
:reserved_ip_subnet_address, :uint32
|
390
|
+
end
|
391
|
+
|
392
|
+
#
|
393
|
+
# DHCP_RESERVED_SCOPE_UNION describes a DHCP scope.
|
394
|
+
#
|
395
|
+
# Available fields:
|
396
|
+
# :subnet_scope_info [String],
|
397
|
+
# :reserved_scope_info [DHCP_RESERVED_SCOPE],
|
398
|
+
# :m_scope_info [String],
|
399
|
+
# :default_scope_info, unused
|
400
|
+
# :global_scope_info
|
401
|
+
#
|
402
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363361(v=vs.85).aspx
|
403
|
+
#
|
404
|
+
class DHCP_OPTION_SCOPE_INFO_UNION < FFI::Union
|
405
|
+
layout :subnet_scope_info, :uint32,
|
406
|
+
:reserved_scope_info, DHCP_RESERVED_SCOPE,
|
407
|
+
:m_scope_info, :pointer,
|
408
|
+
:default_scope_info, :pointer, # unused
|
409
|
+
:global_scope_info, :pointer
|
410
|
+
end
|
411
|
+
|
412
|
+
#
|
413
|
+
# DHCP_OPTION_SCOPE_INFO defines information about the options provided for a certain DHCP scope.
|
414
|
+
#
|
415
|
+
# Available fields:
|
416
|
+
# :scope_type [Fixnum], see DHCP_OPTION_SCOPE_TYPE
|
417
|
+
# :scope_info [DHCP_OPTION_SCOPE_INFO_UNION],
|
418
|
+
#
|
419
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363361(v=vs.85).aspx
|
420
|
+
#
|
421
|
+
class DHCP_OPTION_SCOPE_INFO < DHCPS_Struct
|
422
|
+
layout :scope_type, :uint32,
|
423
|
+
:scope_info, DHCP_OPTION_SCOPE_INFO_UNION
|
424
|
+
|
425
|
+
def self.build_for_subnet_scope(subnet_ip_address)
|
426
|
+
to_return = new
|
427
|
+
to_return[:scope_type] = DHCP_OPTION_SCOPE_TYPE::DhcpSubnetOptions
|
428
|
+
to_return[:scope_info][:subnet_scope_info] = to_return.ip_to_uint32(subnet_ip_address)
|
429
|
+
to_return
|
430
|
+
end
|
431
|
+
|
432
|
+
def self.build_for_reserved_scope(reserved_ip_address, subnet_ip_address)
|
433
|
+
to_return = new
|
434
|
+
to_return[:scope_type] = DHCP_OPTION_SCOPE_TYPE::DhcpReservedOptions
|
435
|
+
to_return[:scope_info][:reserved_scope_info][:reserved_ip_address] = to_return.ip_to_uint32(reserved_ip_address)
|
436
|
+
to_return[:scope_info][:reserved_scope_info][:reserved_ip_subnet_address] = to_return.ip_to_uint32(subnet_ip_address)
|
437
|
+
to_return
|
438
|
+
end
|
439
|
+
|
440
|
+
def self.build_for_multicast_scope(multicast_scope_name)
|
441
|
+
to_return = new
|
442
|
+
to_return[:scope_type] = DHCP_OPTION_SCOPE_TYPE::DhcpMScopeOptions
|
443
|
+
to_return[:scope_info][:m_scope_info] = FFI::MemoryPointer.from_string(to_return.to_wchar_string(multicast_scope_name))
|
444
|
+
to_return
|
445
|
+
end
|
446
|
+
|
447
|
+
def self.build_for_default_scope
|
448
|
+
to_return = new
|
449
|
+
to_return[:scope_type] = DHCP_OPTION_SCOPE_TYPE::DhcpDefaultOptions
|
450
|
+
to_return[:scope_info][:default_scope_info] = DHCP_OPTION_ARRAY.new.pointer
|
451
|
+
to_return
|
452
|
+
end
|
453
|
+
|
454
|
+
# TODO
|
455
|
+
def self.build_for_global_scope
|
456
|
+
raise "Not implemented yet"
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
#
|
461
|
+
# DHCP_OPTION_VALUE defines a DHCP option value.
|
462
|
+
#
|
463
|
+
# Available fields:
|
464
|
+
# :option_id [Fixnum], Option id
|
465
|
+
# :value [DHCP_OPTION_DATA], option value
|
466
|
+
#
|
467
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363367(v=vs.85).aspx
|
468
|
+
#
|
469
|
+
class DHCP_OPTION_VALUE < DHCPS_Struct
|
470
|
+
layout :option_id, :uint32,
|
471
|
+
:value, DHCP_OPTION_DATA
|
472
|
+
end
|
473
|
+
|
474
|
+
#
|
475
|
+
# DHCP_OPTION_VALUE_ARRAY defines a list of DHCP option values.
|
476
|
+
#
|
477
|
+
# Available fields:
|
478
|
+
# :bum_elements [Fixnum], The number of option values in the list
|
479
|
+
# :values [Array<DHCP_OPTION_DATA>], Array of option values
|
480
|
+
#
|
481
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/bb891963(v=vs.85).aspx
|
482
|
+
#
|
483
|
+
class DHCP_OPTION_VALUE_ARRAY < DHCPS_Struct
|
484
|
+
layout :num_elements, :uint32,
|
485
|
+
:values, :pointer
|
486
|
+
|
487
|
+
def as_ruby_struct
|
488
|
+
0.upto(self[:num_elements]-1).inject([]) do |all, offset|
|
489
|
+
all << DhcpsApi::DHCP_OPTION_VALUE.new(self[:values] + offset*DHCP_OPTION_VALUE.size).as_ruby_struct
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
=begin
|
495
|
+
typedef struct _DHCP_IP_RESERVATION_V4 {
|
496
|
+
DHCP_IP_ADDRESS ReservedIpAddress;
|
497
|
+
DHCP_CLIENT_UID *ReservedForClient;
|
498
|
+
BYTE bAllowedClientTypes;
|
499
|
+
} DHCP_IP_RESERVATION_V4, *LPDHCP_IP_RESERVATION_V4;
|
500
|
+
=end
|
501
|
+
class DHCP_IP_RESERVATION_V4 < DHCPS_Struct
|
502
|
+
layout :reserved_ip_address, :uint32,
|
503
|
+
:reserved_for_client, :pointer,
|
504
|
+
:b_allowed_client_types, :uint8 # see ClientType
|
505
|
+
end
|
506
|
+
|
507
|
+
=begin
|
508
|
+
typedef struct _DHCP_SUBNET_ELEMENT_DATA_V4 {
|
509
|
+
DHCP_SUBNET_ELEMENT_TYPE ElementType;
|
510
|
+
union {
|
511
|
+
DHCP_IP_RANGE *IpRange;
|
512
|
+
DHCP_HOST_INFO *SecondaryHost;
|
513
|
+
DHCP_IP_RESERVATION_V4 *ReservedIp;
|
514
|
+
DHCP_IP_RANGE *ExcludeIpRange;
|
515
|
+
DHCP_IP_CLUSTER *IpUsedCluster;
|
516
|
+
} Element;
|
517
|
+
} DHCP_SUBNET_ELEMENT_DATA_V4, *LPDHCP_SUBNET_ELEMENT_DATA_V4;
|
518
|
+
=end
|
519
|
+
class DHCP_SUBNET_ELEMENT < FFI::Union
|
520
|
+
layout :ip_range, :pointer,
|
521
|
+
:secondary_host, :pointer,
|
522
|
+
:reserved_ip, :pointer,
|
523
|
+
:exclude_ip_range, :pointer,
|
524
|
+
:ip_used_cluster, :pointer
|
525
|
+
end
|
526
|
+
|
527
|
+
class DHCP_SUBNET_ELEMENT_DATA_V4 < DHCPS_Struct
|
528
|
+
layout :element_type, :uint32,
|
529
|
+
:element, DHCP_SUBNET_ELEMENT
|
530
|
+
end
|
531
|
+
|
532
|
+
=begin
|
533
|
+
typedef struct _DHCP_SUBNET_INFO {
|
534
|
+
DHCP_IP_ADDRESS SubnetAddress;
|
535
|
+
DHCP_IP_MASK SubnetMask;
|
536
|
+
LPWSTR SubnetName;
|
537
|
+
LPWSTR SubnetComment;
|
538
|
+
DHCP_HOST_INFO PrimaryHost;
|
539
|
+
DHCP_SUBNET_STATE SubnetState;
|
540
|
+
} DHCP_SUBNET_INFO, *LPDHCP_SUBNET_INFO;
|
541
|
+
=end
|
542
|
+
class DHCP_SUBNET_INFO < DHCPS_Struct
|
543
|
+
layout :subnet_address, :uint32,
|
544
|
+
:subnet_mask, :uint32,
|
545
|
+
:subnet_name, :pointer,
|
546
|
+
:subnet_comment, :pointer,
|
547
|
+
:primary_host, DHCP_HOST_INFO,
|
548
|
+
:subnet_state, :uint32
|
549
|
+
|
550
|
+
ruby_struct_attr :uint32_to_ip, :subnet_address, :subnet_mask
|
551
|
+
ruby_struct_attr :to_string, :subnet_name, :subnet_comment
|
552
|
+
end
|
553
|
+
|
554
|
+
=begin
|
555
|
+
typedef struct _DHCP_IP_RANGE {
|
556
|
+
DHCP_IP_ADDRESS StartAddress;
|
557
|
+
DHCP_IP_ADDRESS EndAddress;
|
558
|
+
} DHCP_IP_RANGE, *LPDHCP_IP_RANGE;
|
559
|
+
=end
|
560
|
+
class DHCP_IP_RANGE < DHCPS_Struct
|
561
|
+
layout :start_address, :uint32,
|
562
|
+
:end_address, :uint32
|
563
|
+
|
564
|
+
ruby_struct_attr :uint32_to_ip, :subnet_address, :subnet_mask
|
565
|
+
end
|
566
|
+
|
567
|
+
#
|
568
|
+
# Data structures available in Win2012
|
569
|
+
#
|
570
|
+
|
571
|
+
=begin
|
572
|
+
typedef struct _DHCP_CLIENT_INFO_PB {
|
573
|
+
DHCP_IP_ADDRESS ClientIpAddress;
|
574
|
+
DHCP_IP_MASK SubnetMask;
|
575
|
+
DHCP_CLIENT_UID ClientHardwareAddress;
|
576
|
+
LPWSTR ClientName;
|
577
|
+
LPWSTR ClientComment;
|
578
|
+
DATE_TIME ClientLeaseExpires;
|
579
|
+
DHCP_HOST_INFO OwnerHost;
|
580
|
+
BYTE bClientType;
|
581
|
+
BYTE AddressState;
|
582
|
+
QuarantineStatus Status;
|
583
|
+
DATE_TIME ProbationEnds;
|
584
|
+
BOOL QuarantineCapable;
|
585
|
+
DWORD FilterStatus;
|
586
|
+
LPWSTR PolicyName;
|
587
|
+
} DHCP_CLIENT_INFO_PB, *LPDHCP_CLIENT_INFO_PB;
|
588
|
+
=end
|
589
|
+
class DHCP_CLIENT_INFO_PB < DhcpsApi::DHCPS_Struct
|
590
|
+
layout :client_ip_address, :uint32,
|
591
|
+
:subnet_mask, :uint32,
|
592
|
+
:client_hardware_address, DHCP_CLIENT_UID,
|
593
|
+
:client_name, :pointer,
|
594
|
+
:client_comment, :pointer,
|
595
|
+
:client_lease_expires, DATE_TIME,
|
596
|
+
:owner_host, DHCP_HOST_INFO,
|
597
|
+
:b_client_type, :uint8, # see ClientType
|
598
|
+
:address_state, :uint8,
|
599
|
+
:status, :uint32,
|
600
|
+
:probation_ends, DATE_TIME,
|
601
|
+
:quarantine_capable, :bool,
|
602
|
+
:filter_status, :uint32,
|
603
|
+
:policy_name, :pointer
|
604
|
+
|
605
|
+
ruby_struct_attr :uint32_to_ip, :client_ip_address, :subnet_mask
|
606
|
+
ruby_struct_attr :dhcp_client_uid_to_mac, :client_hardware_address
|
607
|
+
ruby_struct_attr :to_string, :client_name, :client_comment, :policy_name
|
608
|
+
end
|
609
|
+
|
610
|
+
=begin
|
611
|
+
typedef struct _DHCP_CLIENT_INFO_PB_ARRAY {
|
612
|
+
DWORD NumElements;
|
613
|
+
LPDHCP_CLIENT_INFO_PB *Clients;
|
614
|
+
} DHCP_CLIENT_INFO_PB_ARRAY, *LPDHCP_CLIENT_INFO_PB_ARRAY;
|
615
|
+
=end
|
616
|
+
class DHCP_CLIENT_INFO_PB_ARRAY < DhcpsApi::DHCPS_Struct
|
617
|
+
layout :num_elements, :uint32,
|
618
|
+
:clients, :pointer
|
619
|
+
end
|
620
|
+
|
621
|
+
=begin
|
622
|
+
typedef struct _DHCP_IP_RESERVATION_INFO {
|
623
|
+
DHCP_IP_ADDRESS ReservedIpAddress;
|
624
|
+
DHCP_CLIENT_UID ReservedForClient;
|
625
|
+
LPWSTR ReservedClientName;
|
626
|
+
LPWSTR ReservedClientDesc;
|
627
|
+
BYTE bAllowedClientTypes;
|
628
|
+
BYTE fOptionsPresent;
|
629
|
+
} DHCP_IP_RESERVATION_INFO, *LPDHCP_IP_RESERVATION_INFO;
|
630
|
+
=end
|
631
|
+
class DHCP_IP_RESERVATION_INFO < DHCPS_Struct
|
632
|
+
layout :reserved_ip_address, :uint32,
|
633
|
+
:reserved_for_client, DHCP_CLIENT_UID,
|
634
|
+
:reserved_client_name, :pointer,
|
635
|
+
:reserved_client_desc, :pointer,
|
636
|
+
:b_allowed_client_types, :uint8, # see ClientType
|
637
|
+
:f_options_present, :uint8
|
638
|
+
|
639
|
+
ruby_struct_attr :uint32_to_ip, :reserved_ip_address
|
640
|
+
ruby_struct_attr :dhcp_client_uid_to_mac, :reserved_for_client
|
641
|
+
ruby_struct_attr :to_string, :reserved_client_name, :reserved_client_desc
|
642
|
+
end
|
643
|
+
|
644
|
+
=begin
|
645
|
+
typedef struct _DHCP_RESERVATION_INFO_ARRAY {
|
646
|
+
DWORD NumElements;
|
647
|
+
LPDHCP_IP_RESERVATION_INFO *Elements;
|
648
|
+
} DHCP_RESERVATION_INFO_ARRAY, *LPDHCP_RESERVATION_INFO_ARRAY;
|
649
|
+
=end
|
650
|
+
class DHCP_RESERVATION_INFO_ARRAY < DHCPS_Struct
|
651
|
+
layout :num_elements, :uint32,
|
652
|
+
:elements, :pointer
|
653
|
+
end
|
654
|
+
end
|
data/lib/dhcpsapi/misc.rb
CHANGED
@@ -1,16 +1,4 @@
|
|
1
1
|
module DhcpsApi
|
2
|
-
=begin
|
3
|
-
DWORD DHCP_API_FUNCTION DhcpV4GetFreeIPAddress(
|
4
|
-
_In_opt_ LPWSTR ServerIpAddress,
|
5
|
-
_In_ DHCP_IP_ADDRESS ScopeId,
|
6
|
-
_In_ DHCP_IP_ADDRESS startIP,
|
7
|
-
_In_ DHCP_IP_ADDRESS endIP,
|
8
|
-
_In_ DWORD numFreeAddrReq,
|
9
|
-
_Out_ LPDHCP_IP_ARRAY *IPAddrList
|
10
|
-
);
|
11
|
-
=end
|
12
|
-
attach_function :DhcpV4GetFreeIPAddress, [:pointer, :uint32, :uint32, :uint32, :uint32, :pointer], :uint32
|
13
|
-
|
14
2
|
module Misc
|
15
3
|
# Returns free ip addresses as a List of Strings.
|
16
4
|
#
|
@@ -27,12 +15,12 @@ module DhcpsApi
|
|
27
15
|
#
|
28
16
|
def get_free_ip_address(subnet_address, start_address = nil, end_address = nil, num_of_addresses = 1)
|
29
17
|
dhcp_ip_array_ptr_ptr = FFI::MemoryPointer.new(:pointer)
|
30
|
-
error = DhcpsApi.DhcpV4GetFreeIPAddress(to_wchar_string(server_ip_address),
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
18
|
+
error = DhcpsApi::Win2012::Misc.DhcpV4GetFreeIPAddress(to_wchar_string(server_ip_address),
|
19
|
+
ip_to_uint32(subnet_address),
|
20
|
+
start_address.nil? ? 0 : ip_to_uint32(start_address),
|
21
|
+
end_address.nil? ? 0 : ip_to_uint32(end_address),
|
22
|
+
num_of_addresses,
|
23
|
+
dhcp_ip_array_ptr_ptr)
|
36
24
|
|
37
25
|
return [] if (error == 2 || error == 20126)
|
38
26
|
if is_error?(error)
|