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.
@@ -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
- ip_to_uint32(subnet_address),
32
- start_address.nil? ? 0 : ip_to_uint32(start_address),
33
- end_address.nil? ? 0 : ip_to_uint32(end_address),
34
- num_of_addresses,
35
- dhcp_ip_array_ptr_ptr)
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)