1# Copyright (c) 2003-2017 CORE Security Technologies 2# 3# This software is provided under under a slightly modified version 4# of the Apache Software License. See the accompanying LICENSE file 5# for more information. 6# 7# Author: Alberto Solino (@agsolino) 8# 9# Description: 10# [MS-DHCPM] Interface implementation 11# 12# Best way to learn how to use these calls is to grab the protocol standard 13# so you understand what the call does, and then read the test case located 14# at https://github.com/CoreSecurity/impacket/tree/master/impacket/testcases/SMB_RPC 15# 16# Some calls have helper functions, which makes it even easier to use. 17# They are located at the end of this file. 18# Helper functions start with "h"<name of the call>. 19# There are test cases for them too. 20# 21 22from impacket import system_errors 23from impacket.dcerpc.v5.dtypes import LPWSTR, ULONG, NULL, DWORD, BOOL, BYTE, LPDWORD, WORD 24from impacket.dcerpc.v5.ndr import NDRCALL, NDRUniConformantArray, NDRPOINTER, NDRSTRUCT, NDRENUM, NDRUNION 25from impacket.dcerpc.v5.rpcrt import DCERPCException 26from impacket.dcerpc.v5.enum import Enum 27from impacket.uuid import uuidtup_to_bin 28 29MSRPC_UUID_DHCPSRV = uuidtup_to_bin(('6BFFD098-A112-3610-9833-46C3F874532D', '1.0')) 30MSRPC_UUID_DHCPSRV2 = uuidtup_to_bin(('5B821720-F63B-11D0-AAD2-00C04FC324DB', '1.0')) 31 32 33class DCERPCSessionError(DCERPCException): 34 ERROR_MESSAGES = { 35 0x00004E2D: ("ERROR_DHCP_JET_ERROR", "An error occurred while accessing the DHCP server database."), 36 0x00004E25: ("ERROR_DHCP_SUBNET_NOT_PRESENT", "The specified IPv4 subnet does not exist."), 37 0x00004E54: ("ERROR_DHCP_SUBNET_EXISTS", "The IPv4 scope parameters are incorrect. Either the IPv4 scope already" 38 " exists, corresponding to the SubnetAddress and SubnetMask members of " 39 "the structure DHCP_SUBNET_INFO (section 2.2.1.2.8), or there is a " 40 "range overlap of IPv4 addresses between those associated with the " 41 "SubnetAddress and SubnetMask fields of the new IPv4 scope and the " 42 "subnet address and mask of an already existing IPv4 scope"), 43 44 } 45 def __init__(self, error_string=None, error_code=None, packet=None): 46 DCERPCException.__init__(self, error_string, error_code, packet) 47 48 def __str__(self): 49 key = self.error_code 50 if system_errors.ERROR_MESSAGES.has_key(key): 51 error_msg_short = system_errors.ERROR_MESSAGES[key][0] 52 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 53 return 'DHCPM SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 54 elif self.ERROR_MESSAGES.has_key(key): 55 error_msg_short = self.ERROR_MESSAGES[key][0] 56 error_msg_verbose = self.ERROR_MESSAGES[key][1] 57 return 'DHCPM SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 58 else: 59 return 'DHCPM SessionError: unknown error code: 0x%x' % self.error_code 60 61################################################################################ 62# CONSTANTS 63################################################################################ 64DHCP_SRV_HANDLE = LPWSTR 65DHCP_IP_ADDRESS = DWORD 66DHCP_IP_MASK = DWORD 67DHCP_OPTION_ID = DWORD 68 69# DHCP enumeratiom flags 70DHCP_FLAGS_OPTION_DEFAULT = 0x00000000 71DHCP_FLAGS_OPTION_IS_VENDOR = 0x00000003 72 73# Errors 74ERROR_DHCP_JET_ERROR = 0x00004E2D 75ERROR_DHCP_SUBNET_NOT_PRESENT = 0x00004E25 76ERROR_DHCP_SUBNET_EXISTS = 0x00004E54 77################################################################################ 78# STRUCTURES 79################################################################################ 80# 2.2.1.1.3 DHCP_SEARCH_INFO_TYPE 81class DHCP_SEARCH_INFO_TYPE(NDRENUM): 82 class enumItems(Enum): 83 DhcpClientIpAddress = 0 84 DhcpClientHardwareAddress = 1 85 DhcpClientName = 2 86 87# 2.2.1.1.11 QuarantineStatus 88class QuarantineStatus(NDRENUM): 89 class enumItems(Enum): 90 NOQUARANTINE = 0 91 RESTRICTEDACCESS = 1 92 DROPPACKET = 2 93 PROBATION = 3 94 EXEMPT = 4 95 DEFAULTQUARSETTING = 5 96 NOQUARINFO = 6 97 98# 2.2.1.2.7 DHCP_HOST_INFO 99class DHCP_HOST_INFO(NDRSTRUCT): 100 structure = ( 101 ('IpAddress', DHCP_IP_ADDRESS), 102 ('NetBiosName', LPWSTR), 103 ('HostName', LPWSTR), 104 ) 105 106# 2.2.1.2.9 DHCP_BINARY_DATA 107class BYTE_ARRAY(NDRUniConformantArray): 108 item = 'c' 109 110class PBYTE_ARRAY(NDRPOINTER): 111 referent = ( 112 ('Data', BYTE_ARRAY), 113 ) 114 115class DHCP_BINARY_DATA(NDRSTRUCT): 116 structure = ( 117 ('DataLength', DWORD), 118 ('Data_', PBYTE_ARRAY), 119 ) 120 121DHCP_CLIENT_UID = DHCP_BINARY_DATA 122 123# 2.2.1.2.11 DATE_TIME 124class DATE_TIME(NDRSTRUCT): 125 structure = ( 126 ('dwLowDateTime', DWORD), 127 ('dwHighDateTime', DWORD), 128 ) 129 130# 2.2.1.2.19 DHCP_CLIENT_INFO_VQ 131class DHCP_CLIENT_INFO_VQ(NDRSTRUCT): 132 structure = ( 133 ('ClientIpAddress', DHCP_IP_ADDRESS), 134 ('SubnetMask', DHCP_IP_MASK), 135 ('ClientHardwareAddress', DHCP_CLIENT_UID), 136 ('ClientName', LPWSTR), 137 ('ClientComment', LPWSTR), 138 ('ClientLeaseExpires', DATE_TIME), 139 ('OwnerHost', DHCP_HOST_INFO), 140 ('bClientType', BYTE), 141 ('AddressState', BYTE), 142 ('Status', QuarantineStatus), 143 ('ProbationEnds', DATE_TIME), 144 ('QuarantineCapable', BOOL), 145 ) 146 147class DHCP_CLIENT_SEARCH_UNION(NDRUNION): 148 union = { 149 DHCP_SEARCH_INFO_TYPE.DhcpClientIpAddress: ('ClientIpAddress', DHCP_IP_ADDRESS), 150 DHCP_SEARCH_INFO_TYPE.DhcpClientHardwareAddress: ('ClientHardwareAddress', DHCP_CLIENT_UID), 151 DHCP_SEARCH_INFO_TYPE.DhcpClientName: ('ClientName', LPWSTR), 152 } 153 154class DHCP_SEARCH_INFO(NDRSTRUCT): 155 structure = ( 156 ('SearchType', DHCP_SEARCH_INFO_TYPE), 157 ('SearchInfo', DHCP_CLIENT_SEARCH_UNION), 158 ) 159 160# 2.2.1.2.14 DHCP_CLIENT_INFO_V4 161class DHCP_CLIENT_INFO_V4(NDRSTRUCT): 162 structure = ( 163 ('ClientIpAddress', DHCP_IP_ADDRESS), 164 ('SubnetMask', DHCP_IP_MASK), 165 ('ClientHardwareAddress', DHCP_CLIENT_UID), 166 ('ClientName', LPWSTR), 167 ('ClientComment', LPWSTR), 168 ('ClientLeaseExpires', DATE_TIME), 169 ('OwnerHost', DHCP_HOST_INFO), 170 ('bClientType', BYTE), 171 ) 172 173class DHCP_CLIENT_INFO_V5(NDRSTRUCT): 174 structure = ( 175 ('ClientIpAddress', DHCP_IP_ADDRESS), 176 ('SubnetMask', DHCP_IP_MASK), 177 ('ClientHardwareAddress', DHCP_CLIENT_UID), 178 ('ClientName', LPWSTR), 179 ('ClientComment', LPWSTR), 180 ('ClientLeaseExpires', DATE_TIME), 181 ('OwnerHost', DHCP_HOST_INFO), 182 ('bClientType', BYTE), 183 ('AddressState', BYTE), 184 ) 185 186class LPDHCP_CLIENT_INFO_V4(NDRPOINTER): 187 referent = ( 188 ('Data', DHCP_CLIENT_INFO_V4), 189 ) 190 191class LPDHCP_CLIENT_INFO_V5(NDRPOINTER): 192 referent = ( 193 ('Data', DHCP_CLIENT_INFO_V5), 194 ) 195 196# 2.2.1.2.115 DHCP_CLIENT_INFO_PB 197class DHCP_CLIENT_INFO_PB(NDRSTRUCT): 198 structure = ( 199 ('ClientIpAddress', DHCP_IP_ADDRESS), 200 ('SubnetMask', DHCP_IP_MASK), 201 ('ClientHardwareAddress', DHCP_CLIENT_UID), 202 ('ClientName', LPWSTR), 203 ('ClientComment', LPWSTR), 204 ('ClientLeaseExpires', DATE_TIME), 205 ('OwnerHost', DHCP_HOST_INFO), 206 ('bClientType', BYTE), 207 ('AddressState', BYTE), 208 ('Status', QuarantineStatus), 209 ('ProbationEnds', DATE_TIME), 210 ('QuarantineCapable', BOOL), 211 ('FilterStatus', DWORD), 212 ('PolicyName', LPWSTR), 213 ) 214 215class LPDHCP_CLIENT_INFO_PB(NDRPOINTER): 216 referent = ( 217 ('Data', DHCP_CLIENT_INFO_PB), 218 ) 219 220class LPDHCP_CLIENT_INFO_VQ(NDRPOINTER): 221 referent = ( 222 ('Data', DHCP_CLIENT_INFO_VQ), 223 ) 224 225class DHCP_CLIENT_INFO_VQ_ARRAY(NDRUniConformantArray): 226 item = LPDHCP_CLIENT_INFO_VQ 227 228class LPDHCP_CLIENT_INFO_VQ_ARRAY(NDRPOINTER): 229 referent = ( 230 ('Data', DHCP_CLIENT_INFO_VQ_ARRAY), 231 ) 232 233class DHCP_CLIENT_INFO_ARRAY_VQ(NDRSTRUCT): 234 structure = ( 235 ('NumElements', DWORD), 236 ('Clients', LPDHCP_CLIENT_INFO_VQ_ARRAY), 237 ) 238 239class LPDHCP_CLIENT_INFO_ARRAY_VQ(NDRPOINTER): 240 referent = ( 241 ('Data', DHCP_CLIENT_INFO_ARRAY_VQ), 242 ) 243 244class DHCP_CLIENT_INFO_V4_ARRAY(NDRUniConformantArray): 245 item = LPDHCP_CLIENT_INFO_V4 246 247class DHCP_CLIENT_INFO_V5_ARRAY(NDRUniConformantArray): 248 item = LPDHCP_CLIENT_INFO_V5 249 250class LPDHCP_CLIENT_INFO_V4_ARRAY(NDRPOINTER): 251 referent = ( 252 ('Data', DHCP_CLIENT_INFO_V4_ARRAY), 253 ) 254 255class LPDHCP_CLIENT_INFO_V5_ARRAY(NDRPOINTER): 256 referent = ( 257 ('Data', DHCP_CLIENT_INFO_V5_ARRAY), 258 ) 259 260class DHCP_CLIENT_INFO_ARRAY_V4(NDRSTRUCT): 261 structure = ( 262 ('NumElements', DWORD), 263 ('Clients', LPDHCP_CLIENT_INFO_V4_ARRAY), 264 ) 265 266class DHCP_CLIENT_INFO_ARRAY_V5(NDRSTRUCT): 267 structure = ( 268 ('NumElements', DWORD), 269 ('Clients', LPDHCP_CLIENT_INFO_V4_ARRAY), 270 ) 271 272class LPDHCP_CLIENT_INFO_ARRAY_V5(NDRPOINTER): 273 referent = ( 274 ('Data', DHCP_CLIENT_INFO_ARRAY_V5), 275 ) 276 277class LPDHCP_CLIENT_INFO_ARRAY_V4(NDRPOINTER): 278 referent = ( 279 ('Data', DHCP_CLIENT_INFO_ARRAY_V4), 280 ) 281 282class DHCP_IP_ADDRESS_ARRAY(NDRUniConformantArray): 283 item = DHCP_IP_ADDRESS 284 285class LPDHCP_IP_ADDRESS_ARRAY(NDRPOINTER): 286 referent = ( 287 ('Data', DHCP_IP_ADDRESS_ARRAY), 288 ) 289 290class DHCP_IP_ARRAY(NDRSTRUCT): 291 structure = ( 292 ('NumElements', DWORD), 293 ('Elements', LPDHCP_IP_ADDRESS_ARRAY), 294 ) 295 296class DHCP_SUBNET_STATE(NDRENUM): 297 class enumItems(Enum): 298 DhcpSubnetEnabled = 0 299 DhcpSubnetDisabled = 1 300 DhcpSubnetEnabledSwitched = 2 301 DhcpSubnetDisabledSwitched = 3 302 DhcpSubnetInvalidState = 4 303 304class DHCP_SUBNET_INFO(NDRSTRUCT): 305 structure = ( 306 ('SubnetAddress', DHCP_IP_ADDRESS), 307 ('SubnetMask', DHCP_IP_MASK), 308 ('SubnetName', LPWSTR), 309 ('SubnetComment', LPWSTR), 310 ('PrimaryHost', DHCP_HOST_INFO), 311 ('SubnetState', DHCP_SUBNET_STATE), 312 ) 313 314class LPDHCP_SUBNET_INFO(NDRPOINTER): 315 referent = ( 316 ('Data', DHCP_SUBNET_INFO), 317 ) 318 319class DHCP_OPTION_SCOPE_TYPE(NDRENUM): 320 class enumItems(Enum): 321 DhcpDefaultOptions = 0 322 DhcpGlobalOptions = 1 323 DhcpSubnetOptions = 2 324 DhcpReservedOptions = 3 325 DhcpMScopeOptions = 4 326 327class DHCP_RESERVED_SCOPE(NDRSTRUCT): 328 structure = ( 329 ('ReservedIpAddress', DHCP_IP_ADDRESS), 330 ('ReservedIpSubnetAddress', DHCP_IP_ADDRESS), 331 ) 332 333class DHCP_OPTION_SCOPE_UNION(NDRUNION): 334 union = { 335 DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions : (), 336 DHCP_OPTION_SCOPE_TYPE.DhcpGlobalOptions : (), 337 DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions : ('SubnetScopeInfo', DHCP_IP_ADDRESS), 338 DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions : ('ReservedScopeInfo', DHCP_RESERVED_SCOPE), 339 DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions : ('MScopeInfo', LPWSTR), 340 } 341 342class DHCP_OPTION_SCOPE_INFO(NDRSTRUCT): 343 structure = ( 344 ('ScopeType', DHCP_OPTION_SCOPE_TYPE), 345 ('ScopeInfo', DHCP_OPTION_SCOPE_UNION), 346 ) 347 348class LPDHCP_OPTION_SCOPE_INFO(NDRPOINTER): 349 referent = ( 350 ('Data', DHCP_OPTION_SCOPE_INFO) 351 ) 352 353class DWORD_DWORD(NDRSTRUCT): 354 structure = ( 355 ('DWord1', DWORD), 356 ('DWord2', DWORD), 357 ) 358 359class DHCP_BOOTP_IP_RANGE(NDRSTRUCT): 360 structure = ( 361 ('StartAddress', DHCP_IP_ADDRESS), 362 ('EndAddress', DHCP_IP_ADDRESS), 363 ('BootpAllocated', ULONG), 364 ('MaxBootpAllowed', DHCP_IP_ADDRESS), 365 ('MaxBootpAllowed', ULONG ), 366 ) 367 368class DHCP_IP_RESERVATION_V4(NDRSTRUCT): 369 structure = ( 370 ('ReservedIpAddress', DHCP_IP_ADDRESS), 371 ('ReservedForClient', DHCP_CLIENT_UID), 372 ('bAllowedClientTypes', BYTE), 373 ) 374 375class DHCP_IP_RANGE(NDRSTRUCT): 376 structure = ( 377 ('StartAddress', DHCP_IP_ADDRESS), 378 ('EndAddress', DHCP_IP_ADDRESS), 379 ) 380 381class DHCP_IP_CLUSTER(NDRSTRUCT): 382 structure = ( 383 ('ClusterAddress', DHCP_IP_ADDRESS), 384 ('ClusterMask', DWORD), 385 ) 386 387class DHCP_SUBNET_ELEMENT_TYPE(NDRENUM): 388 class enumItems(Enum): 389 DhcpIpRanges = 0 390 DhcpSecondaryHosts = 1 391 DhcpReservedIps = 2 392 DhcpExcludedIpRanges = 3 393 DhcpIpUsedClusters = 4 394 DhcpIpRangesDhcpOnly = 5 395 DhcpIpRangesDhcpBootp = 6 396 DhcpIpRangesBootpOnly = 7 397 398class DHCP_SUBNET_ELEMENT_UNION_V5(NDRUNION): 399 union = { 400 DHCP_SUBNET_ELEMENT_TYPE.DhcpIpRanges : ('IpRange', DHCP_BOOTP_IP_RANGE), 401 DHCP_SUBNET_ELEMENT_TYPE.DhcpSecondaryHosts : ('SecondaryHost', DHCP_HOST_INFO), 402 DHCP_SUBNET_ELEMENT_TYPE.DhcpReservedIps : ('ReservedIp', DHCP_IP_RESERVATION_V4), 403 DHCP_SUBNET_ELEMENT_TYPE.DhcpExcludedIpRanges : ('ExcludeIpRange', DHCP_IP_RANGE), 404 DHCP_SUBNET_ELEMENT_TYPE.DhcpIpUsedClusters : ('IpUsedCluster', DHCP_IP_CLUSTER), 405 } 406 407class DHCP_SUBNET_ELEMENT_DATA_V5(NDRSTRUCT): 408 structure = ( 409 ('ElementType', DHCP_SUBNET_ELEMENT_TYPE), 410 ('Element', DHCP_SUBNET_ELEMENT_UNION_V5), 411 ) 412 413class LPDHCP_SUBNET_ELEMENT_DATA_V5(NDRUniConformantArray): 414 item = DHCP_SUBNET_ELEMENT_DATA_V5 415 416class DHCP_SUBNET_ELEMENT_INFO_ARRAY_V5(NDRSTRUCT): 417 structure = ( 418 ('NumElements', DWORD), 419 ('Elements', LPDHCP_SUBNET_ELEMENT_DATA_V5), 420 ) 421 422class LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V5(NDRPOINTER): 423 referent = ( 424 ('Data', DHCP_SUBNET_ELEMENT_INFO_ARRAY_V5) 425 ) 426 427class DHCP_OPTION_DATA_TYPE(NDRENUM): 428 class enumItems(Enum): 429 DhcpByteOption = 0 430 DhcpWordOption = 1 431 DhcpDWordOption = 2 432 DhcpDWordDWordOption = 3 433 DhcpIpAddressOption = 4 434 DhcpStringDataOption = 5 435 DhcpBinaryDataOption = 6 436 DhcpEncapsulatedDataOption = 7 437 DhcpIpv6AddressOption = 8 438 439class DHCP_OPTION_ELEMENT_UNION(NDRUNION): 440 commonHdr = ( 441 ('tag', DHCP_OPTION_DATA_TYPE), 442 ) 443 union = { 444 DHCP_OPTION_DATA_TYPE.enumItems.DhcpByteOption : ('ByteOption', BYTE), 445 DHCP_OPTION_DATA_TYPE.enumItems.DhcpWordOption : ('WordOption', WORD), 446 DHCP_OPTION_DATA_TYPE.enumItems.DhcpDWordOption : ('DWordOption', DWORD), 447 DHCP_OPTION_DATA_TYPE.enumItems.DhcpDWordDWordOption : ('DWordDWordOption', DWORD_DWORD), 448 DHCP_OPTION_DATA_TYPE.enumItems.DhcpIpAddressOption : ('IpAddressOption', DHCP_IP_ADDRESS), 449 DHCP_OPTION_DATA_TYPE.enumItems.DhcpStringDataOption : ('StringDataOption', LPWSTR), 450 DHCP_OPTION_DATA_TYPE.enumItems.DhcpBinaryDataOption : ('BinaryDataOption', DHCP_BINARY_DATA), 451 DHCP_OPTION_DATA_TYPE.enumItems.DhcpEncapsulatedDataOption: ('EncapsulatedDataOption', DHCP_BINARY_DATA), 452 DHCP_OPTION_DATA_TYPE.enumItems.DhcpIpv6AddressOption : ('Ipv6AddressDataOption', LPWSTR), 453 } 454 455class DHCP_OPTION_DATA_ELEMENT(NDRSTRUCT): 456 structure = ( 457 ('OptionType', DHCP_OPTION_DATA_TYPE), 458 ('Element', DHCP_OPTION_ELEMENT_UNION), 459 ) 460 461class DHCP_OPTION_DATA_ELEMENT_ARRAY2(NDRUniConformantArray): 462 item = DHCP_OPTION_DATA_ELEMENT 463 464class LPDHCP_OPTION_DATA_ELEMENT(NDRPOINTER): 465 referent = ( 466 ('Data', DHCP_OPTION_DATA_ELEMENT_ARRAY2), 467 ) 468 469class DHCP_OPTION_DATA(NDRSTRUCT): 470 structure = ( 471 ('NumElements', DWORD), 472 ('Elements', LPDHCP_OPTION_DATA_ELEMENT), 473 ) 474 475class DHCP_OPTION_VALUE(NDRSTRUCT): 476 structure = ( 477 ('OptionID', DHCP_OPTION_ID), 478 ('Value', DHCP_OPTION_DATA), 479 ) 480 481class PDHCP_OPTION_VALUE(NDRPOINTER): 482 referent = ( 483 ('Data', DHCP_OPTION_VALUE), 484 ) 485 486class DHCP_OPTION_VALUE_ARRAY2(NDRUniConformantArray): 487 item = DHCP_OPTION_VALUE 488 489class LPDHCP_OPTION_VALUE(NDRPOINTER): 490 referent = ( 491 ('Data', DHCP_OPTION_VALUE_ARRAY2), 492 ) 493 494class DHCP_OPTION_VALUE_ARRAY(NDRSTRUCT): 495 structure = ( 496 ('NumElements', DWORD), 497 ('Values', LPDHCP_OPTION_VALUE), 498 ) 499 500class LPDHCP_OPTION_VALUE_ARRAY(NDRPOINTER): 501 referent = ( 502 ('Data', DHCP_OPTION_VALUE_ARRAY), 503 ) 504 505class DHCP_ALL_OPTION_VALUES(NDRSTRUCT): 506 structure = ( 507 ('ClassName', LPWSTR), 508 ('VendorName', LPWSTR), 509 ('IsVendor', BOOL), 510 ('OptionsArray', LPDHCP_OPTION_VALUE_ARRAY), 511 ) 512 513class OPTION_VALUES_ARRAY(NDRUniConformantArray): 514 item = DHCP_ALL_OPTION_VALUES 515 516class LPOPTION_VALUES_ARRAY(NDRPOINTER): 517 referent = ( 518 ('Data', OPTION_VALUES_ARRAY), 519 ) 520 521class DHCP_ALL_OPTION_VALUES(NDRSTRUCT): 522 structure = ( 523 ('Flags', DWORD), 524 ('NumElements', DWORD), 525 ('Options', LPOPTION_VALUES_ARRAY), 526 ) 527 528class LPDHCP_ALL_OPTION_VALUES(NDRPOINTER): 529 referent = ( 530 ('Data', DHCP_ALL_OPTION_VALUES), 531 ) 532 533################################################################################ 534# RPC CALLS 535################################################################################ 536# Interface dhcpsrv 537class DhcpGetSubnetInfo(NDRCALL): 538 opnum = 2 539 structure = ( 540 ('ServerIpAddress', DHCP_SRV_HANDLE), 541 ('SubnetAddress', DHCP_IP_ADDRESS), 542 ) 543 544class DhcpGetSubnetInfoResponse(NDRCALL): 545 structure = ( 546 ('SubnetInfo', LPDHCP_SUBNET_INFO), 547 ('ErrorCode', ULONG), 548 ) 549 550class DhcpEnumSubnets(NDRCALL): 551 opnum = 3 552 structure = ( 553 ('ServerIpAddress', DHCP_SRV_HANDLE), 554 ('ResumeHandle', LPDWORD), 555 ('PreferredMaximum', DWORD), 556 ) 557 558class DhcpEnumSubnetsResponse(NDRCALL): 559 structure = ( 560 ('ResumeHandle', LPDWORD), 561 ('EnumInfo', DHCP_IP_ARRAY), 562 ('EnumRead', DWORD), 563 ('EnumTotal', DWORD), 564 ('ErrorCode', ULONG), 565 ) 566 567class DhcpGetOptionValue(NDRCALL): 568 opnum = 13 569 structure = ( 570 ('ServerIpAddress', DHCP_SRV_HANDLE), 571 ('OptionID', DHCP_OPTION_ID), 572 ('ScopeInfo', DHCP_OPTION_SCOPE_INFO), 573 ) 574 575class DhcpGetOptionValueResponse(NDRCALL): 576 structure = ( 577 ('OptionValue', PDHCP_OPTION_VALUE), 578 ('ErrorCode', ULONG), 579 ) 580 581class DhcpEnumOptionValues(NDRCALL): 582 opnum = 14 583 structure = ( 584 ('ServerIpAddress', DHCP_SRV_HANDLE), 585 ('ScopeInfo', DHCP_OPTION_SCOPE_INFO), 586 ('ResumeHandle', LPDWORD), 587 ('PreferredMaximum', DWORD), 588 ) 589 590class DhcpEnumOptionValuesResponse(NDRCALL): 591 structure = ( 592 ('ResumeHandle', DWORD), 593 ('OptionValues', LPDHCP_OPTION_VALUE_ARRAY), 594 ('OptionsRead', DWORD), 595 ('OptionsTotal', DWORD), 596 ('ErrorCode', ULONG), 597 ) 598 599class DhcpGetClientInfoV4(NDRCALL): 600 opnum = 34 601 structure = ( 602 ('ServerIpAddress', DHCP_SRV_HANDLE), 603 ('SearchInfo', DHCP_SEARCH_INFO), 604 ) 605 606class DhcpGetClientInfoV4Response(NDRCALL): 607 structure = ( 608 ('ClientInfo', LPDHCP_CLIENT_INFO_V4), 609 ('ErrorCode', ULONG), 610 ) 611 612class DhcpEnumSubnetClientsV4(NDRCALL): 613 opnum = 35 614 structure = ( 615 ('ServerIpAddress', DHCP_SRV_HANDLE), 616 ('SubnetAddress', DHCP_IP_ADDRESS), 617 ('ResumeHandle', DWORD), 618 ('PreferredMaximum', DWORD), 619 ) 620 621class DhcpEnumSubnetClientsV4Response(NDRCALL): 622 structure = ( 623 ('ResumeHandle', LPDWORD), 624 ('ClientInfo', LPDHCP_CLIENT_INFO_ARRAY_V4), 625 ('ClientsRead', DWORD), 626 ('ClientsTotal', DWORD), 627 ('ErrorCode', ULONG), 628 ) 629 630# Interface dhcpsrv2 631 632class DhcpEnumSubnetClientsV5(NDRCALL): 633 opnum = 0 634 structure = ( 635 ('ServerIpAddress', DHCP_SRV_HANDLE), 636 ('SubnetAddress', DHCP_IP_ADDRESS), 637 ('ResumeHandle', LPDWORD), 638 ('PreferredMaximum', DWORD), 639 ) 640 641class DhcpEnumSubnetClientsV5Response(NDRCALL): 642 structure = ( 643 ('ResumeHandle', DWORD), 644 ('ClientsInfo', LPDHCP_CLIENT_INFO_ARRAY_V5), 645 ('ClientsRead', DWORD), 646 ('ClientsTotal', DWORD), 647 ) 648 649class DhcpGetOptionValueV5(NDRCALL): 650 opnum = 21 651 structure = ( 652 ('ServerIpAddress', DHCP_SRV_HANDLE), 653 ('Flags', DWORD), 654 ('OptionID', DHCP_OPTION_ID), 655 ('ClassName', LPWSTR), 656 ('VendorName', LPWSTR), 657 ('ScopeInfo', DHCP_OPTION_SCOPE_INFO), 658 ) 659 660class DhcpGetOptionValueV5Response(NDRCALL): 661 structure = ( 662 ('OptionValue', PDHCP_OPTION_VALUE), 663 ('ErrorCode', ULONG), 664 ) 665 666class DhcpEnumOptionValuesV5(NDRCALL): 667 opnum = 22 668 structure = ( 669 ('ServerIpAddress', DHCP_SRV_HANDLE), 670 ('Flags', DWORD), 671 ('ClassName', LPWSTR), 672 ('VendorName', LPWSTR), 673 ('ScopeInfo', DHCP_OPTION_SCOPE_INFO), 674 ('ResumeHandle', LPDWORD), 675 ('PreferredMaximum', DWORD), 676 ) 677 678class DhcpEnumOptionValuesV5Response(NDRCALL): 679 structure = ( 680 ('ResumeHandle', DWORD), 681 ('OptionValues', LPDHCP_OPTION_VALUE_ARRAY), 682 ('OptionsRead', DWORD), 683 ('OptionsTotal', DWORD), 684 ('ErrorCode', ULONG), 685 ) 686 687class DhcpGetAllOptionValues(NDRCALL): 688 opnum = 30 689 structure = ( 690 ('ServerIpAddress', DHCP_SRV_HANDLE), 691 ('Flags', DWORD), 692 ('ScopeInfo', DHCP_OPTION_SCOPE_INFO), 693 ) 694 695class DhcpGetAllOptionValuesResponse(NDRCALL): 696 structure = ( 697 ('Values', LPDHCP_ALL_OPTION_VALUES), 698 ('ErrorCode', ULONG), 699 ) 700 701class DhcpEnumSubnetElementsV5(NDRCALL): 702 opnum = 38 703 structure = ( 704 ('ServerIpAddress', DHCP_SRV_HANDLE), 705 ('SubnetAddress', DHCP_IP_ADDRESS), 706 ('EnumElementType', DHCP_SUBNET_ELEMENT_TYPE), 707 ('ResumeHandle', LPDWORD), 708 ('PreferredMaximum', DWORD), 709 ) 710 711class DhcpEnumSubnetElementsV5Response(NDRCALL): 712 structure = ( 713 ('ResumeHandle', DWORD), 714 ('EnumElementInfo', LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V5), 715 ('ElementsRead', DWORD), 716 ('ElementsTotal', DWORD), 717 ('ErrorCode', ULONG), 718 ) 719 720class DhcpEnumSubnetClientsVQ(NDRCALL): 721 opnum = 47 722 structure = ( 723 ('ServerIpAddress', DHCP_SRV_HANDLE), 724 ('SubnetAddress', DHCP_IP_ADDRESS), 725 ('ResumeHandle', LPDWORD), 726 ('PreferredMaximum', DWORD), 727 ) 728 729class DhcpEnumSubnetClientsVQResponse(NDRCALL): 730 structure = ( 731 ('ResumeHandle', LPDWORD), 732 ('ClientInfo', LPDHCP_CLIENT_INFO_ARRAY_VQ), 733 ('ClientsRead', DWORD), 734 ('ClientsTotal', DWORD), 735 ('ErrorCode', ULONG), 736 ) 737 738class DhcpV4GetClientInfo(NDRCALL): 739 opnum = 123 740 structure = ( 741 ('ServerIpAddress', DHCP_SRV_HANDLE), 742 ('SearchInfo', DHCP_SEARCH_INFO), 743 ) 744 745class DhcpV4GetClientInfoResponse(NDRCALL): 746 structure = ( 747 ('ClientInfo', LPDHCP_CLIENT_INFO_PB), 748 ('ErrorCode', ULONG), 749 ) 750 751################################################################################ 752# OPNUMs and their corresponding structures 753################################################################################ 754OPNUMS = { 755 0: (DhcpEnumSubnetClientsV5, DhcpEnumSubnetClientsV5Response), 756 2: (DhcpGetSubnetInfo, DhcpGetSubnetInfoResponse), 757 3: (DhcpEnumSubnets, DhcpEnumSubnetsResponse), 758 13: (DhcpGetOptionValue, DhcpGetOptionValueResponse), 759 14: (DhcpEnumOptionValues, DhcpEnumOptionValuesResponse), 760 21: (DhcpGetOptionValueV5, DhcpGetOptionValueV5Response), 761 22: (DhcpEnumOptionValuesV5, DhcpEnumOptionValuesV5Response), 762 30: (DhcpGetAllOptionValues, DhcpGetAllOptionValuesResponse), 763 34: (DhcpGetClientInfoV4, DhcpGetClientInfoV4Response), 764 35: (DhcpEnumSubnetClientsV4, DhcpEnumSubnetClientsV4Response), 765 38: (DhcpEnumSubnetElementsV5, DhcpEnumSubnetElementsV5Response), 766 47: (DhcpEnumSubnetClientsVQ, DhcpEnumSubnetClientsVQResponse), 767 123: (DhcpV4GetClientInfo, DhcpV4GetClientInfoResponse), 768} 769 770 771################################################################################ 772# HELPER FUNCTIONS 773################################################################################ 774def hDhcpGetClientInfoV4(dce, searchType, searchValue): 775 request = DhcpGetClientInfoV4() 776 777 request['ServerIpAddress'] = NULL 778 request['SearchInfo']['SearchType'] = searchType 779 request['SearchInfo']['SearchInfo']['tag'] = searchType 780 if searchType == DHCP_SEARCH_INFO_TYPE.DhcpClientIpAddress: 781 request['SearchInfo']['SearchInfo']['ClientIpAddress'] = searchValue 782 elif searchType == DHCP_SEARCH_INFO_TYPE.DhcpClientHardwareAddress: 783 # This should be a DHCP_BINARY_DATA 784 request['SearchInfo']['SearchInfo']['ClientHardwareAddress'] = searchValue 785 else: 786 request['SearchInfo']['SearchInfo']['ClientName'] = searchValue 787 788 return dce.request(request) 789 790def hDhcpGetSubnetInfo(dce, subnetaddress): 791 request = DhcpGetSubnetInfo() 792 793 request['ServerIpAddress'] = NULL 794 request['SubnetAddress'] = subnetaddress 795 resp = dce.request(request) 796 797 return resp 798 799def hDhcpGetOptionValue(dce, optionID, scopetype=DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions, options=NULL): 800 request = DhcpGetOptionValue() 801 802 request['ServerIpAddress'] = NULL 803 request['OptionID'] = optionID 804 request['ScopeInfo']['ScopeType'] = scopetype 805 if scopetype != DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions and scopetype != DHCP_OPTION_SCOPE_TYPE.DhcpGlobalOptions: 806 request['ScopeInfo']['ScopeInfo']['tag'] = scopetype 807 if scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions: 808 request['ScopeInfo']['ScopeInfo']['SubnetScopeInfo'] = options 809 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions: 810 request['ScopeInfo']['ScopeInfo']['ReservedScopeInfo'] = options 811 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions: 812 request['ScopeInfo']['ScopeInfo']['MScopeInfo'] = options 813 814 status = system_errors.ERROR_MORE_DATA 815 while status == system_errors.ERROR_MORE_DATA: 816 try: 817 resp = dce.request(request) 818 except DCERPCException, e: 819 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 820 raise 821 resp = e.get_packet() 822 return resp 823 824def hDhcpEnumOptionValues(dce, scopetype=DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions, options=NULL, 825 preferredMaximum=0xffffffff): 826 request = DhcpEnumOptionValues() 827 828 request['ServerIpAddress'] = NULL 829 request['ScopeInfo']['ScopeType'] = scopetype 830 if scopetype != DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions and scopetype != DHCP_OPTION_SCOPE_TYPE.DhcpGlobalOptions: 831 request['ScopeInfo']['ScopeInfo']['tag'] = scopetype 832 if scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions: 833 request['ScopeInfo']['ScopeInfo']['SubnetScopeInfo'] = options 834 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions: 835 request['ScopeInfo']['ScopeInfo']['ReservedScopeInfo'] = options 836 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions: 837 request['ScopeInfo']['ScopeInfo']['MScopeInfo'] = options 838 request['ResumeHandle'] = NULL 839 request['PreferredMaximum'] = preferredMaximum 840 841 status = system_errors.ERROR_MORE_DATA 842 while status == system_errors.ERROR_MORE_DATA: 843 try: 844 resp = dce.request(request) 845 except DCERPCException, e: 846 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 847 raise 848 resp = e.get_packet() 849 return resp 850 851def hDhcpEnumOptionValuesV5(dce, flags=DHCP_FLAGS_OPTION_DEFAULT, classname=NULL, vendorname=NULL, 852 scopetype=DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions, options=NULL, 853 preferredMaximum=0xffffffff): 854 request = DhcpEnumOptionValuesV5() 855 856 request['ServerIpAddress'] = NULL 857 request['Flags'] = flags 858 request['ClassName'] = classname 859 request['VendorName'] = vendorname 860 request['ScopeInfo']['ScopeType'] = scopetype 861 request['ScopeInfo']['ScopeInfo']['tag'] = scopetype 862 if scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions: 863 request['ScopeInfo']['ScopeInfo']['SubnetScopeInfo'] = options 864 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions: 865 request['ScopeInfo']['ScopeInfo']['ReservedScopeInfo'] = options 866 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions: 867 request['ScopeInfo']['ScopeInfo']['MScopeInfo'] = options 868 request['ResumeHandle'] = NULL 869 request['PreferredMaximum'] = preferredMaximum 870 871 status = system_errors.ERROR_MORE_DATA 872 while status == system_errors.ERROR_MORE_DATA: 873 try: 874 resp = dce.request(request) 875 except DCERPCException, e: 876 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 877 raise 878 resp = e.get_packet() 879 return resp 880 881def hDhcpGetOptionValueV5(dce, option_id, flags=DHCP_FLAGS_OPTION_DEFAULT, classname=NULL, vendorname=NULL, 882 scopetype=DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions, options=NULL): 883 request = DhcpGetOptionValueV5() 884 885 request['ServerIpAddress'] = NULL 886 request['Flags'] = flags 887 request['OptionID'] = option_id 888 request['ClassName'] = classname 889 request['VendorName'] = vendorname 890 request['ScopeInfo']['ScopeType'] = scopetype 891 request['ScopeInfo']['ScopeInfo']['tag'] = scopetype.value 892 if scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions: 893 request['ScopeInfo']['ScopeInfo']['SubnetScopeInfo'] = options 894 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions: 895 request['ScopeInfo']['ScopeInfo']['ReservedScopeInfo'] = options 896 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions: 897 request['ScopeInfo']['ScopeInfo']['MScopeInfo'] = options 898 899 status = system_errors.ERROR_MORE_DATA 900 while status == system_errors.ERROR_MORE_DATA: 901 try: 902 resp = dce.request(request) 903 except DCERPCException, e: 904 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 905 raise 906 resp = e.get_packet() 907 return resp 908 909def hDhcpGetAllOptionValues(dce, scopetype=DHCP_OPTION_SCOPE_TYPE.DhcpDefaultOptions, options=NULL): 910 request = DhcpGetAllOptionValues() 911 912 request['ServerIpAddress'] = NULL 913 request['Flags'] = NULL 914 request['ScopeInfo']['ScopeType'] = scopetype 915 request['ScopeInfo']['ScopeInfo']['tag'] = scopetype 916 if scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpSubnetOptions: 917 request['ScopeInfo']['ScopeInfo']['SubnetScopeInfo'] = options 918 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpReservedOptions: 919 request['ScopeInfo']['ScopeInfo']['ReservedScopeInfo'] = options 920 elif scopetype == DHCP_OPTION_SCOPE_TYPE.DhcpMScopeOptions: 921 request['ScopeInfo']['ScopeInfo']['MScopeInfo'] = options 922 923 status = system_errors.ERROR_MORE_DATA 924 while status == system_errors.ERROR_MORE_DATA: 925 try: 926 resp = dce.request(request) 927 except DCERPCException, e: 928 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 929 raise 930 resp = e.get_packet() 931 return resp 932 933def hDhcpEnumSubnets(dce, preferredMaximum=0xffffffff): 934 request = DhcpEnumSubnets() 935 936 request['ServerIpAddress'] = NULL 937 request['ResumeHandle'] = NULL 938 request['PreferredMaximum'] = preferredMaximum 939 status = system_errors.ERROR_MORE_DATA 940 while status == system_errors.ERROR_MORE_DATA: 941 try: 942 resp = dce.request(request) 943 except DCERPCException, e: 944 if str(e).find('STATUS_MORE_ENTRIES') < 0: 945 raise 946 resp = e.get_packet() 947 return resp 948 949def hDhcpEnumSubnetClientsVQ(dce, preferredMaximum=0xffffffff): 950 request = DhcpEnumSubnetClientsVQ() 951 952 request['ServerIpAddress'] = NULL 953 request['SubnetAddress'] = NULL 954 request['ResumeHandle'] = NULL 955 request['PreferredMaximum'] = preferredMaximum 956 status = system_errors.ERROR_MORE_DATA 957 while status == system_errors.ERROR_MORE_DATA: 958 try: 959 resp = dce.request(request) 960 except DCERPCException, e: 961 if str(e).find('STATUS_MORE_ENTRIES') < 0: 962 raise 963 resp = e.get_packet() 964 return resp 965 966def hDhcpEnumSubnetClientsV4(dce, preferredMaximum=0xffffffff): 967 request = DhcpEnumSubnetClientsV4() 968 969 request['ServerIpAddress'] = NULL 970 request['SubnetAddress'] = NULL 971 request['ResumeHandle'] = NULL 972 request['PreferredMaximum'] = preferredMaximum 973 status = system_errors.ERROR_MORE_DATA 974 while status == system_errors.ERROR_MORE_DATA: 975 try: 976 resp = dce.request(request) 977 except DCERPCException, e: 978 if str(e).find('STATUS_MORE_ENTRIES') < 0: 979 raise 980 resp = e.get_packet() 981 return resp 982 983def hDhcpEnumSubnetClientsV5(dce, subnetAddress=0, preferredMaximum=0xffffffff): 984 request = DhcpEnumSubnetClientsV5() 985 986 request['ServerIpAddress'] = NULL 987 request['SubnetAddress'] = subnetAddress 988 request['ResumeHandle'] = NULL 989 request['PreferredMaximum'] = preferredMaximum 990 status = system_errors.ERROR_MORE_DATA 991 while status == system_errors.ERROR_MORE_DATA: 992 try: 993 resp = dce.request(request) 994 except DCERPCSessionError, e: 995 if str(e).find('STATUS_MORE_ENTRIES') < 0: 996 raise 997 resp = e.get_packet() 998 return resp 999 1000def hDhcpEnumSubnetElementsV5(dce, subnet_address, element_type=DHCP_SUBNET_ELEMENT_TYPE.DhcpIpRanges, preferredMaximum=0xffffffff): 1001 request = DhcpEnumSubnetElementsV5() 1002 1003 request['ServerIpAddress'] = NULL 1004 request['SubnetAddress'] = subnet_address 1005 request['EnumElementType'] = element_type 1006 request['ResumeHandle'] = NULL 1007 request['PreferredMaximum'] = preferredMaximum 1008 1009 status = system_errors.ERROR_MORE_DATA 1010 while status == system_errors.ERROR_MORE_DATA: 1011 try: 1012 resp = dce.request(request) 1013 except DCERPCException, e: 1014 if str(e).find('ERROR_NO_MORE_ITEMS') < 0: 1015 raise 1016 resp = e.get_packet() 1017 return resp 1018