1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241 |
- /*++
- Copyright (c) 2013 Minoca Corp. All Rights Reserved
- Module Name:
- dhcp.c
- Abstract:
- This module implements support for the Dynamic Host Configuration Protocol,
- or DHCP.
- Author:
- Evan Green 5-Apr-2013
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- //
- // Network layer drivers are supposed to be able to stand on their own (ie be
- // able to be implemented outside the core net library). For the builtin ones,
- // avoid including netcore.h, but still redefine those functions that would
- // otherwise generate imports.
- //
- #define NET_API __DLLEXPORT
- #include <minoca/kernel/driver.h>
- #include <minoca/net/netdrv.h>
- #include <minoca/net/ip4.h>
- //
- // --------------------------------------------------------------------- Macros
- //
- //
- // These macros get the renewal and binding times as a percentage of the total
- // lease time. The renewal time is at 50% of the lease and the rebinding time
- // is at 87.5% of the lease time.
- //
- #define DHCP_GET_DEFAULT_RENEWAL_TIME(_LeaseTime) (_LeaseTime) >> 1
- #define DHCP_GET_DEFAULT_REBINDING_TIME(_LeaseTime) \
- ((_LeaseTime) - ((_LeaseTime) >> 3))
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define DHCP_ALLOCATION_TAG 0x70636844 // 'pchD'
- //
- // Define the maximum number of DNS server addresses that will be saved in this
- // implementation.
- //
- #define DHCP_MAX_DNS_SERVERS 4
- //
- // Define some well-known port numbers.
- //
- #define DHCP_CLIENT_PORT 68
- #define DHCP_SERVER_PORT 67
- //
- // Define DHCP packet field values.
- //
- #define DHCP_OPERATION_REQUEST 0x01
- #define DHCP_OPERATION_REPLY 0x02
- #define DHCP_HARDWARE_TYPE_ETHERNET 0x01
- #define DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH 6
- #define DHCP_FLAG_BROADCAST 0x01
- #define DHCP_MAGIC_COOKIE 0x63825363
- #define DHCP_OPTION_HEADER_SIZE 2
- #define DHCP_SCRATCH_PACKET_SIZE 4096
- //
- // Define how many times discovery should be retried.
- //
- #define DHCP_DISCOVER_RETRY_COUNT 5
- //
- // Define how long to wait for an offer and acknowledge, in milliseconds.
- //
- #define DHCP_OFFER_TIMEOUT 8000
- #define DHCP_ACKNOWLEDGE_TIMEOUT DHCP_OFFER_TIMEOUT
- //
- // Define DHCP option codes.
- //
- #define DHCP_OPTION_PAD 0
- #define DHCP_OPTION_SUBNET_MASK 1
- #define DHCP_OPTION_TIME_OFFSET 2
- #define DHCP_OPTION_ROUTER 3
- #define DHCP_OPTION_DOMAIN_NAME_SERVER 6
- #define DHCP_OPTION_HOST_NAME 12
- #define DHCP_OPTION_DOMAIN_NAME 15
- #define DHCP_OPTION_REQUESTED_IP_ADDRESS 50
- #define DHCP_OPTION_IP_ADDRESS_LEASE_TIME 51
- #define DHCP_OPTION_OPTION_OVERLOAD 52
- #define DHCP_OPTION_DHCP_MESSAGE_TYPE 53
- #define DHCP_OPTION_DHCP_SERVER 54
- #define DHCP_OPTION_PARAMETER_REQUEST_LIST 55
- #define DHCP_OPTION_MESSAGE 56
- #define DHCP_OPTION_RENEWAL_TIME 58
- #define DHCP_OPTION_REBINDING_TIME 59
- #define DHCP_OPTION_TFTP_SERVER_NAME 66
- #define DHCP_OPTION_BOOT_FILE_NAME 67
- #define DHCP_OPTION_END 255
- //
- // Define DHCP message types.
- //
- #define DHCP_MESSAGE_DISCOVER 1
- #define DHCP_MESSAGE_OFFER 2
- #define DHCP_MESSAGE_REQUEST 3
- #define DHCP_MESSAGE_DECLINE 4
- #define DHCP_MESSAGE_ACKNOWLEDGE 5
- #define DHCP_MESSAGE_NAK 6
- #define DHCP_MESSAGE_RELEASE 7
- #define DHCP_MESSAGE_INFORM 8
- //
- // Define what goes in the discovery request.
- //
- #define DHCP_OPTION_MESSAGE_TYPE_SIZE 3
- #define DHCP_DISCOVER_OPTION_COUNT 2
- #define DHCP_DISCOVER_PARAMETER_REQUEST_COUNT 4
- #define DHCP_DISCOVER_OPTIONS_SIZE \
- (DHCP_OPTION_MESSAGE_TYPE_SIZE + \
- (DHCP_OPTION_HEADER_SIZE + \
- DHCP_DISCOVER_PARAMETER_REQUEST_COUNT) + 2)
- //
- // Define the minimum due time delta for the DHCP lease timer, in seconds.
- //
- #define DHCP_TIMER_DURATION_MINIMUM 60
- //
- // Define the debug flags for DHCP.
- //
- #define DHCP_DEBUG_FLAG_EXTEND 0x1
- #define DHCP_DEBUG_FLAG_OFFER 0X2
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- /*++
- Structure Description:
- This structure defines the structure of a DHCP packet request or response.
- After this structure, zero or more options may follow.
- Members:
- OperationCode - Stores the operation code, either request or reply.
- HardwareType - Stores the media type, pretty much always the code for
- "ethernet".
- HardwareAddressLength - Stores the length of a hardware address, pretty
- much always 6 for ethernet MAC addresses.
- Hops - Stores 0 usually, can be optionally set by relay agents when booting
- via a relay agent.
- TransactionIdentifier - Stores a unique value used to match requests to
- replies.
- Seconds - Stores the number of seconds since the client began the
- renewal or request process.
- Flags - Stores the broadcast flag.
- ClientIpAddress - Stores the client's current IP address.
- YourIpAddress - Stores the IP address being offered by the DHCP server.
- ServerIpAddress - Stores the IP address of the DHCP server.
- GatewayIpAddress - Stores the IP address to contact for requests outside
- the subnet.
- ClientHardwareAddress - Stores the hardware address associated with this
- offer.
- ServerName - Stores an optional NULL terminated string containing the
- server name, used by the BOOTP protocol
- BootFileName - Stores an optional fully qualified path to the BOOTP boot
- file name.
- MagicCookie - Stores a constant value. Options potentially follow after this
- magic.
- --*/
- typedef struct _DHCP_PACKET {
- UCHAR OperationCode;
- UCHAR HardwareType;
- UCHAR HardwareAddressLength;
- UCHAR Hops;
- ULONG TransactionIdentifier;
- USHORT Seconds;
- USHORT Flags;
- ULONG ClientIpAddress;
- ULONG YourIpAddress;
- ULONG ServerIpAddress;
- ULONG GatewayIpAddress;
- UCHAR ClientHardwareAddress[16];
- UCHAR ServerName[64];
- UCHAR BootFileName[128];
- ULONG MagicCookie;
- } PACKED DHCP_PACKET, *PDHCP_PACKET;
- /*++
- Structure Description:
- This structure defines the required data parsed from a DHCP response.
- Members:
- MessageType - Stores the DHCP option message type of the response. See
- DHCP_MESSAGE_* for values.
- ServerIpAddress - Stores the IP address of the DHCP server.
- OfferedIpAddress - Stores the IP address being offered by the DHCP server.
- RouterIpAddress - Stores the default gateway IP address associated with the
- offered address.Stores the IP address of the
- SubnetMask - Stores the subnet mask of the local network, as given by the
- DHCP server.
- DomainNameServer - Stores an array of DNS addresses associated with the
- offer.
- DomainNameServerCount - Stores the number of valid addresses in the DNS
- address array.
- LeaseTime - Stores the lease time returned in the offer or acknowledge, in
- seconds.
- RenewalTime - Stores the time until the renewal state begins, in seconds.
- RebindingTime - Stores the time until the rebinding state begins, in
- seconds.
- --*/
- typedef struct _DHCP_REPLY {
- UCHAR MessageType;
- ULONG ServerIpAddress;
- ULONG OfferedIpAddress;
- ULONG RouterIpAddress;
- ULONG SubnetMask;
- ULONG DomainNameServer[DHCP_MAX_DNS_SERVERS];
- ULONG DomainNameServerCount;
- ULONG LeaseTime;
- ULONG RenewalTime;
- ULONG RebindingTime;
- } DHCP_REPLY, *PDHCP_REPLY;
- typedef enum _DHCP_LEASE_STATE {
- DhcpLeaseStateInvalid,
- DhcpLeaseStateInitialize,
- DhcpLeaseStateBound,
- DhcpLeaseStateRenewing,
- DhcpLeaseStateRebinding
- } DHCP_LEASE_STATE, *PDHCP_LEASE_STATE;
- /*++
- Structure Description:
- This structure defines the DHCP state for a leased network address.
- Members:
- ListEntry - Stores pointers to the next and previous leased address handed
- out by DHCP.
- Link - Stores a pointer to the link that owns the link address entry.
- LinkAddress - Stores a pointer to the link address entry to which the lease
- was given.
- Timer - Stores a pointer to the timer that will trigger work to either
- renew or rebind the lease.
- Dpc - Stores a pointer to the DPC that is to run once the lease timer
- expires.
- WorkItem - Stores a pointer to the work item that is to be queued by the
- DPC.
- LeaseTime - Stores the total time of the lease.
- RenewalTime - Stores the time at which the lease enters the renewal phase.
- RebindingTime - Stores the time at which the lease enters the rebinding
- phase.
- State - Stores the state of the lease.
- ReferenceCount - Stores the number of references taken on the lease.
- --*/
- typedef struct _DHCP_LEASE {
- LIST_ENTRY ListEntry;
- PNET_LINK Link;
- PNET_LINK_ADDRESS_ENTRY LinkAddress;
- PKTIMER Timer;
- PDPC Dpc;
- PWORK_ITEM WorkItem;
- ULONG LeaseTime;
- ULONG RenewalTime;
- ULONG RebindingTime;
- DHCP_LEASE_STATE State;
- volatile ULONG ReferenceCount;
- } DHCP_LEASE, *PDHCP_LEASE;
- /*++
- Structure Description:
- This structure defines DHCP context used throughout the assignment
- sequence.
- Members:
- Link - Stores a pointer to the link to work on.
- LinkAddress - Stores a pointer to the link address entry to assign an
- address for.
- Lease - Stores a pointer to any existing lease for the given link and link
- address combination.
- ScratchPacket - Stores a pointer to a scratch packet, used for building
- requests.
- ScratchPacketSize - Stores the total size of the scratch packet, including
- extra length for options.
- ScratchPacketIoBuffer - Stores a pointer to an I/O buffer containing the
- scratch packet buffer.
- Socket - Stores a pointer to the UDP socket connection.
- ExpectedTransactionId - Stores the transaction ID that is expected to come
- back in the response. All others get ignored.
- OfferClientAddress - Stores the network address that the DHCP server is
- offering to this machine.
- OfferSubnetMask - Stores the subnet mask of the local network, as given by
- the DHCP server.
- OfferServerAddress - Stores the network address of the server making the
- offer.
- OfferRouter - Stores the default gateway address associated with the offered
- address.
- OfferDnsAddress - Stores an array of DNS addresses associated with the
- offer.
- OfferDnsAddressCount - Stores the number of valid addresses in the DNS
- address array.
- LeaseTime - Stores the lease time returned in the offer or acknowledge, in
- seconds.
- RenewalTime - Stores the time until the renewal state begins, in seconds.
- RebindingTime - Stores the time until the rebinding state begins, in
- seconds.
- LeaseRequestTime - Stores the time at which the lease was requested.
- --*/
- typedef struct _DHCP_CONTEXT {
- PNET_LINK Link;
- PNET_LINK_ADDRESS_ENTRY LinkAddress;
- PDHCP_LEASE Lease;
- PDHCP_PACKET ScratchPacket;
- ULONG ScratchPacketSize;
- PIO_BUFFER ScratchPacketIoBuffer;
- PIO_HANDLE Socket;
- ULONG ExpectedTransactionId;
- NETWORK_ADDRESS OfferClientAddress;
- NETWORK_ADDRESS OfferSubnetMask;
- NETWORK_ADDRESS OfferServerAddress;
- NETWORK_ADDRESS OfferRouter;
- NETWORK_ADDRESS OfferDnsAddress[DHCP_MAX_DNS_SERVERS];
- ULONG OfferDnsAddressCount;
- ULONG LeaseTime;
- ULONG RenewalTime;
- ULONG RebindingTime;
- SYSTEM_TIME LeaseRequestTime;
- } DHCP_CONTEXT, *PDHCP_CONTEXT;
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- VOID
- NetpDhcpAssignmentThread (
- PVOID Parameter
- );
- KSTATUS
- NetpDhcpBeginLeaseExtension (
- PDHCP_LEASE Lease
- );
- VOID
- NetpDhcpLeaseExtensionThread (
- PVOID Parameter
- );
- KSTATUS
- NetpDhcpBeginRelease (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- );
- VOID
- NetpDhcpReleaseThread (
- PVOID Parameter
- );
- KSTATUS
- NetpDhcpSendDiscover (
- PDHCP_CONTEXT Context
- );
- KSTATUS
- NetpDhcpReceiveOffer (
- PDHCP_CONTEXT Context
- );
- KSTATUS
- NetpDhcpSendRequest (
- PDHCP_CONTEXT Context
- );
- KSTATUS
- NetpDhcpReceiveAcknowledge (
- PDHCP_CONTEXT Context
- );
- KSTATUS
- NetpDhcpSendRelease (
- PDHCP_CONTEXT Context
- );
- KSTATUS
- NetpDhcpReceiveReply (
- PDHCP_CONTEXT Context,
- PDHCP_REPLY Reply
- );
- PDHCP_CONTEXT
- NetpDhcpCreateContext (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress,
- PDHCP_LEASE Lease
- );
- VOID
- NetpDhcpDestroyContext (
- PDHCP_CONTEXT Context
- );
- PDHCP_LEASE
- NetpDhcpCreateLease (
- VOID
- );
- VOID
- NetpDhcpLeaseAddReference (
- PDHCP_LEASE Lease
- );
- VOID
- NetpDhcpLeaseReleaseReference (
- PDHCP_LEASE Lease
- );
- PDHCP_LEASE
- NetpDhcpFindLease (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- );
- VOID
- NetpDhcpDestroyLease (
- PDHCP_LEASE AssignmentContext
- );
- VOID
- NetpDhcpQueueLeaseExtension (
- PDHCP_LEASE Lease
- );
- VOID
- NetpDhcpLeaseDpcRoutine (
- PDPC Dpc
- );
- VOID
- NetpDhcpLeaseWorkRoutine (
- PVOID Parameter
- );
- KSTATUS
- NetpDhcpCopyReplyToContext (
- PDHCP_CONTEXT Context,
- PDHCP_REPLY Reply
- );
- VOID
- NetpDhcpPrintContext (
- PDHCP_CONTEXT Context
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- LIST_ENTRY NetDhcpLeaseListHead;
- KSPIN_LOCK NetDhcpLeaseListLock;
- //
- // Store a bitfield of enabled DHCP debug flags. See DHCP_DEBUG_* definitions.
- //
- ULONG NetDhcpDebugFlags = 0x0;
- //
- // Set this debug value to overried the lease renewal and rebinding times.
- //
- BOOL NetDhcpDebugOverrideRenewal = FALSE;
- //
- // Set these values to the desired renewal and rebinding times if force renewal
- // is set.
- //
- ULONG NetDhcpDebugRenewalTime = 0;
- ULONG NetDhcpDebugRebindingTime = 0;
- //
- // Set these debug values to force failures in the renewal and/or rebinding
- // phase.
- //
- BOOL NetDhcpDebugFailRenewal = FALSE;
- BOOL NetDhcpDebugFailRebinding = FALSE;
- //
- // ------------------------------------------------------------------ Functions
- //
- VOID
- NetpDhcpInitialize (
- VOID
- )
- /*++
- Routine Description:
- This routine initializes support for DHCP.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- INITIALIZE_LIST_HEAD(&NetDhcpLeaseListHead);
- KeInitializeSpinLock(&NetDhcpLeaseListLock);
- return;
- }
- KSTATUS
- NetpDhcpBeginAssignment (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- )
- /*++
- Routine Description:
- This routine kicks off the process of assigning a network address to this
- link address entry by using DHCP.
- Arguments:
- Link - Supplies a pointer to the link to send the discovery request out on.
- LinkAddress - Supplies a pointer to the address structure to bind to.
- Return Value:
- Status code indicating whether or not the process was successfully
- initiated.
- --*/
- {
- PDHCP_CONTEXT DhcpContext;
- KSTATUS Status;
- DhcpContext = NetpDhcpCreateContext(Link, LinkAddress, NULL);
- if (DhcpContext == NULL) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- Status = PsCreateKernelThread(NetpDhcpAssignmentThread,
- DhcpContext,
- "DhcpAssignThread");
- if (!KSUCCESS(Status)) {
- NetpDhcpDestroyContext(DhcpContext);
- }
- return Status;
- }
- KSTATUS
- NetpDhcpCancelLease (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- )
- /*++
- Routine Description:
- This routine attempts to cancel a DHCP lease.
- Arguments:
- Link - Supplies a pointer to the network link to which the lease was
- provided.
- LinkAddress - Supplies a pointer to the network link address that was
- leased.
- Return Value:
- Status code.
- --*/
- {
- PDHCP_LEASE Lease;
- DHCP_LEASE_STATE LeaseState;
- BOOL LinkUp;
- KSTATUS Status;
- Status = STATUS_SUCCESS;
- Lease = NetpDhcpFindLease(Link, LinkAddress);
- if (Lease == NULL) {
- goto DhcpCancelLeaseEnd;
- }
- //
- // Remove the lease from the global list.
- //
- KeAcquireSpinLock(&NetDhcpLeaseListLock);
- LIST_REMOVE(&(Lease->ListEntry));
- Lease->ListEntry.Next = NULL;
- KeReleaseSpinLock(&NetDhcpLeaseListLock);
- //
- // Save the lease state. If the lease is in the initialized state then the
- // lease has expired (or never started).
- //
- LeaseState = Lease->State;
- ASSERT(LeaseState != DhcpLeaseStateInvalid);
- //
- // Release the original reference on the lease and the reference taken by
- // the find routine.
- //
- NetpDhcpLeaseReleaseReference(Lease);
- NetpDhcpLeaseReleaseReference(Lease);
- //
- // Be kind. If the link is still up, attempt to release the leased IP
- // address if it is in the bound, renewing, or rebinding state.
- //
- NetGetLinkState(Link, &LinkUp, NULL);
- if ((LinkUp != FALSE) && (LeaseState != DhcpLeaseStateInitialize)) {
- Status = NetpDhcpBeginRelease(Link, LinkAddress);
- if (!KSUCCESS(Status)) {
- goto DhcpCancelLeaseEnd;
- }
- }
- DhcpCancelLeaseEnd:
- return Status;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- NetpDhcpAssignmentThread (
- PVOID Parameter
- )
- /*++
- Routine Description:
- This routine attempts to assign an address to a link using DHCP.
- Arguments:
- Parameter - Supplies a pointer supplied by the creator of the thread, in
- this case a pointer to the DHCP context structure.
- Return Value:
- None.
- --*/
- {
- BOOL BroadcastEnabled;
- UINTN DataSize;
- PDHCP_CONTEXT DhcpContext;
- NETWORK_DEVICE_INFORMATION Information;
- PDHCP_LEASE Lease;
- BOOL LeaseAcquired;
- SYSTEM_TIME LeaseEndTime;
- IP4_ADDRESS LocalAddress;
- ULONG RetryCount;
- KSTATUS Status;
- PSTR Step;
- DhcpContext = (PDHCP_CONTEXT)Parameter;
- Lease = NULL;
- LeaseAcquired = FALSE;
- Step = "Init";
- ASSERT(DhcpContext->Lease == NULL);
- //
- // Make sure there are no left over leases for this link and link address
- // combination. If the DHCP assignment results in the same IP address then
- // an old lease will not be canceled by the networking core. If it results
- // in a different IP address then it will attempt to destroy the old lease,
- // preventing reuse of any current lease here.
- //
- Status = NetpDhcpCancelLease(DhcpContext->Link, DhcpContext->LinkAddress);
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- Lease = NetpDhcpCreateLease();
- if (Lease == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpAssignmentThreadEnd;
- }
- //
- // Create the scratch packet space and the socket.
- //
- DhcpContext->ScratchPacket = MmAllocatePagedPool(DHCP_SCRATCH_PACKET_SIZE,
- DHCP_ALLOCATION_TAG);
- if (DhcpContext->ScratchPacket == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpAssignmentThreadEnd;
- }
- DhcpContext->ScratchPacketSize = DHCP_SCRATCH_PACKET_SIZE;
- Status = MmCreateIoBuffer(DhcpContext->ScratchPacket,
- DhcpContext->ScratchPacketSize,
- IO_BUFFER_FLAG_KERNEL_MODE_DATA,
- &(DhcpContext->ScratchPacketIoBuffer));
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- Status = IoSocketCreate(NetDomainIp4,
- NetSocketDatagram,
- SOCKET_INTERNET_PROTOCOL_UDP,
- 0,
- &(DhcpContext->Socket));
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- //
- // Bind that socket to the known DHCP client port. The any address must be
- // used as the DHCP server will reply with broadcast packets and only an
- // unbound socket will pick those up.
- //
- RtlZeroMemory(&LocalAddress, sizeof(NETWORK_ADDRESS));
- LocalAddress.Domain = NetDomainIp4;
- LocalAddress.Port = DHCP_CLIENT_PORT;
- Status = IoSocketBindToAddress(TRUE,
- DhcpContext->Socket,
- DhcpContext->Link,
- (PNETWORK_ADDRESS)&LocalAddress,
- NULL,
- 0);
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- //
- // Enable broadcast messages on this socket.
- //
- BroadcastEnabled = TRUE;
- DataSize = sizeof(BOOL);
- Status = IoSocketGetSetInformation(DhcpContext->Socket,
- SocketInformationBasic,
- SocketBasicOptionBroadcastEnabled,
- &BroadcastEnabled,
- &DataSize,
- TRUE);
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- Lease->State = DhcpLeaseStateInitialize;
- NetpDhcpLeaseAddReference(Lease);
- DhcpContext->Lease = Lease;
- RetryCount = 0;
- while (RetryCount < DHCP_DISCOVER_RETRY_COUNT) {
- RetryCount += 1;
- //
- // Kick off the sequence by sending a discovery packet.
- //
- Step = "SendDiscover";
- Status = NetpDhcpSendDiscover(DhcpContext);
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Get the offer back from the server.
- //
- Step = "ReceiveOffer";
- Status = NetpDhcpReceiveOffer(DhcpContext);
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Request the address that came back.
- //
- Step = "SendRequest";
- Status = NetpDhcpSendRequest(DhcpContext);
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Get the acknowledge back to make sure the DHCP heard the request.
- //
- Step = "RecieveAcknowledge";
- Status = NetpDhcpReceiveAcknowledge(DhcpContext);
- if (!KSUCCESS(Status)) {
- continue;
- }
- break;
- }
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- LeaseAcquired = TRUE;
- //
- // Calculate the lease's end based on the DHCP offer.
- //
- RtlCopyMemory(&LeaseEndTime,
- &(DhcpContext->LeaseRequestTime),
- sizeof(SYSTEM_TIME));
- LeaseEndTime.Seconds += DhcpContext->LeaseTime;
- //
- // The address reservation is complete. Set the parameters in the link
- // address entry.
- //
- Step = "SetNetworkAddress";
- RtlZeroMemory(&Information, sizeof(NETWORK_DEVICE_INFORMATION));
- Information.Version = NETWORK_DEVICE_INFORMATION_VERSION;
- Information.Flags = NETWORK_DEVICE_FLAG_CONFIGURED;
- Information.Domain = NetDomainIp4;
- Information.ConfigurationMethod = NetworkAddressConfigurationDhcp;
- RtlCopyMemory(&(Information.Address),
- &(DhcpContext->OfferClientAddress),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.Subnet),
- &(DhcpContext->OfferSubnetMask),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.Gateway),
- &(DhcpContext->OfferRouter),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.DnsServers),
- &(DhcpContext->OfferDnsAddress),
- sizeof(NETWORK_ADDRESS) * DhcpContext->OfferDnsAddressCount);
- Information.DnsServerCount = DhcpContext->OfferDnsAddressCount;
- RtlCopyMemory(&(Information.LeaseServerAddress),
- &(DhcpContext->OfferServerAddress),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.LeaseStartTime),
- &(DhcpContext->LeaseRequestTime),
- sizeof(SYSTEM_TIME));
- RtlCopyMemory(&(Information.LeaseEndTime),
- &LeaseEndTime,
- sizeof(SYSTEM_TIME));
- Status = NetGetSetNetworkDeviceInformation(DhcpContext->Link,
- DhcpContext->LinkAddress,
- &Information,
- TRUE);
- if (!KSUCCESS(Status)) {
- goto DhcpAssignmentThreadEnd;
- }
- //
- // Celebrate the assignment with some debugger prints.
- //
- RtlDebugPrint("DHCP Assignment:\n");
- NetpDhcpPrintContext(DhcpContext);
- //
- // Finish initializing the lease, including adding it to the global list.
- //
- NetLinkAddReference(DhcpContext->Link);
- Lease->Link = DhcpContext->Link;
- Lease->LinkAddress = DhcpContext->LinkAddress;
- Lease->State = DhcpLeaseStateBound;
- Lease->LeaseTime = DhcpContext->LeaseTime;
- Lease->RenewalTime = DhcpContext->RenewalTime;
- Lease->RebindingTime = DhcpContext->RebindingTime;
- KeAcquireSpinLock(&NetDhcpLeaseListLock);
- INSERT_BEFORE(&(Lease->ListEntry), &NetDhcpLeaseListHead);
- KeReleaseSpinLock(&NetDhcpLeaseListLock);
- //
- // The lease is established. Set the lease timer so that a lease renewal is
- // attemtped at the time specified by the server.
- //
- NetpDhcpQueueLeaseExtension(Lease);
- DhcpAssignmentThreadEnd:
- if (!KSUCCESS(Status)) {
- RtlDebugPrint("Net: DHCP assignment failed at step '%s': %x.\n",
- Step,
- Status);
- //
- // If the routine failed after the lease was acquired, kindly release
- // the IP address back to the server.
- //
- if (LeaseAcquired != FALSE) {
- RtlZeroMemory(&Information, sizeof(NETWORK_DEVICE_INFORMATION));
- Information.Version = NETWORK_DEVICE_INFORMATION_VERSION;
- Information.Domain = NetDomainIp4;
- Information.ConfigurationMethod = NetworkAddressConfigurationNone;
- NetGetSetNetworkDeviceInformation(DhcpContext->Link,
- DhcpContext->LinkAddress,
- &Information,
- TRUE);
- NetpDhcpSendRelease(DhcpContext);
- }
- if (Lease != NULL) {
- NetpDhcpLeaseReleaseReference(Lease);
- }
- }
- NetpDhcpDestroyContext(DhcpContext);
- return;
- }
- KSTATUS
- NetpDhcpBeginLeaseExtension (
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine kicks off the process of extending the given DHCP lease.
- Arguments:
- Lease - Supplies a pointer to a DHCP lease that is to be renewed.
- Return Value:
- Status code indicating whether or not the process was successfully
- initiated.
- --*/
- {
- PDHCP_CONTEXT DhcpContext;
- KSTATUS Status;
- ASSERT(Lease->Link != NULL);
- ASSERT(Lease->LinkAddress != NULL);
- ASSERT((Lease->State == DhcpLeaseStateRenewing) ||
- (Lease->State == DhcpLeaseStateRebinding));
- DhcpContext = NetpDhcpCreateContext(Lease->Link, Lease->LinkAddress, Lease);
- if (DhcpContext == NULL) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- Status = PsCreateKernelThread(NetpDhcpLeaseExtensionThread,
- DhcpContext,
- "DhcpExtendThread");
- if (!KSUCCESS(Status)) {
- NetpDhcpDestroyContext(DhcpContext);
- return Status;
- }
- return STATUS_SUCCESS;
- }
- VOID
- NetpDhcpLeaseExtensionThread (
- PVOID Parameter
- )
- /*++
- Routine Description:
- This routine attempts to extend the lease on an address for a link using
- DHCP.
- Arguments:
- Parameter - Supplies a pointer supplied by the creator of the thread, in
- this case a pointer to the DHCP context structure.
- Return Value:
- None.
- --*/
- {
- PDHCP_CONTEXT DhcpContext;
- NETWORK_DEVICE_INFORMATION Information;
- PDHCP_LEASE Lease;
- SYSTEM_TIME LeaseEndTime;
- IP4_ADDRESS LocalAddress;
- BOOL LockHeld;
- KSTATUS Status;
- PSTR Step;
- ASSERT(KeGetRunLevel() == RunLevelLow);
- DhcpContext = (PDHCP_CONTEXT)Parameter;
- Lease = DhcpContext->Lease;
- LockHeld = FALSE;
- Step = "Init";
- ASSERT(Lease != NULL);
- ASSERT((Lease->State == DhcpLeaseStateRenewing) ||
- (Lease->State == DhcpLeaseStateRebinding));
- //
- // If the debug state is set to fail this phase, then skip to the end.
- //
- if (((NetDhcpDebugFailRenewal != FALSE) &&
- (Lease->State == DhcpLeaseStateRenewing)) ||
- ((NetDhcpDebugFailRebinding != FALSE) &&
- (Lease->State == DhcpLeaseStateRebinding))) {
- Step = "ForceFailure";
- Status = STATUS_TRY_AGAIN;
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Create the scratch packet space and the socket.
- //
- DhcpContext->ScratchPacket = MmAllocatePagedPool(DHCP_SCRATCH_PACKET_SIZE,
- DHCP_ALLOCATION_TAG);
- if (DhcpContext->ScratchPacket == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpLeaseExtensionThreadEnd;
- }
- DhcpContext->ScratchPacketSize = DHCP_SCRATCH_PACKET_SIZE;
- Status = MmCreateIoBuffer(DhcpContext->ScratchPacket,
- DhcpContext->ScratchPacketSize,
- IO_BUFFER_FLAG_KERNEL_MODE_DATA,
- &(DhcpContext->ScratchPacketIoBuffer));
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- Status = IoSocketCreate(NetDomainIp4,
- NetSocketDatagram,
- SOCKET_INTERNET_PROTOCOL_UDP,
- 0,
- &(DhcpContext->Socket));
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Bind that socket to the known DHCP client port. Make sure the link
- // address is still valid before copying it.
- //
- KeAcquireQueuedLock(DhcpContext->Link->QueuedLock);
- LockHeld = TRUE;
- if (DhcpContext->LinkAddress->Configured == FALSE) {
- Status = STATUS_NO_NETWORK_CONNECTION;
- goto DhcpLeaseExtensionThreadEnd;
- }
- RtlCopyMemory(&LocalAddress,
- &(DhcpContext->LinkAddress->Address),
- sizeof(NETWORK_ADDRESS));
- KeReleaseQueuedLock(DhcpContext->Link->QueuedLock);
- LockHeld = FALSE;
- LocalAddress.Port = DHCP_CLIENT_PORT;
- Status = IoSocketBindToAddress(TRUE,
- DhcpContext->Socket,
- DhcpContext->Link,
- (PNETWORK_ADDRESS)&LocalAddress,
- NULL,
- 0);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Request the address that came back.
- //
- Step = "SendRequest";
- Status = NetpDhcpSendRequest(DhcpContext);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Get the acknowledge back to make sure the DHCP heard the request.
- //
- Step = "RecieveAcknowledge";
- Status = NetpDhcpReceiveAcknowledge(DhcpContext);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Calculate the lease's end based on the DHCP offer.
- //
- RtlCopyMemory(&LeaseEndTime,
- &(DhcpContext->LeaseRequestTime),
- sizeof(SYSTEM_TIME));
- LeaseEndTime.Seconds += DhcpContext->LeaseTime;
- //
- // The lease extension is complete. Set the parameters in the link address
- // entry.
- //
- Step = "SetNetworkAddress";
- RtlZeroMemory(&Information, sizeof(NETWORK_DEVICE_INFORMATION));
- Information.Version = NETWORK_DEVICE_INFORMATION_VERSION;
- Information.Flags = NETWORK_DEVICE_FLAG_CONFIGURED;
- Information.Domain = NetDomainIp4;
- Information.ConfigurationMethod = NetworkAddressConfigurationDhcp;
- RtlCopyMemory(&(Information.Address),
- &(DhcpContext->OfferClientAddress),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.Subnet),
- &(DhcpContext->OfferSubnetMask),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.Gateway),
- &(DhcpContext->OfferRouter),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.DnsServers),
- &(DhcpContext->OfferDnsAddress),
- sizeof(NETWORK_ADDRESS) * DhcpContext->OfferDnsAddressCount);
- Information.DnsServerCount = DhcpContext->OfferDnsAddressCount;
- RtlCopyMemory(&(Information.LeaseServerAddress),
- &(DhcpContext->OfferServerAddress),
- sizeof(NETWORK_ADDRESS));
- RtlCopyMemory(&(Information.LeaseStartTime),
- &(DhcpContext->LeaseRequestTime),
- sizeof(SYSTEM_TIME));
- RtlCopyMemory(&(Information.LeaseEndTime),
- &LeaseEndTime,
- sizeof(SYSTEM_TIME));
- Status = NetGetSetNetworkDeviceInformation(DhcpContext->Link,
- DhcpContext->LinkAddress,
- &Information,
- TRUE);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseExtensionThreadEnd;
- }
- //
- // Celebrate the extnesion with some debugger prints.
- //
- RtlDebugPrint("DHCP Extension:\n");
- NetpDhcpPrintContext(DhcpContext);
- if ((NetDhcpDebugFlags & DHCP_DEBUG_FLAG_EXTEND) != 0) {
- RtlDebugPrint("Net: DHCP extended lease (0x%08x) for link (0x%08x) "
- "from state %d.\n",
- Lease,
- Lease->Link,
- Lease->State);
- }
- //
- // Mark that the lease is now in the bound state.
- //
- Lease->State = DhcpLeaseStateBound;
- //
- // The lease has been extended. Set the lease timer so that a lease
- // renewal is attemtped at the time specified by the server.
- //
- NetpDhcpQueueLeaseExtension(Lease);
- DhcpLeaseExtensionThreadEnd:
- if (LockHeld != FALSE) {
- KeReleaseQueuedLock(DhcpContext->Link->QueuedLock);
- }
- if (!KSUCCESS(Status)) {
- RtlDebugPrint("Net: DHCP lease extension failed at step '%s': %x.\n",
- Step,
- Status);
- //
- // No matter when the extension failed, try to queue lease extension
- // again. This is OK even if this routine fails after extending the
- // lease. There is no harm in prematurely asking the DHCP server for
- // an extension.
- //
- NetpDhcpQueueLeaseExtension(Lease);
- }
- NetpDhcpDestroyContext(DhcpContext);
- return;
- }
- KSTATUS
- NetpDhcpBeginRelease (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- )
- /*++
- Routine Description:
- This routine kicks off the process of releasing the IP address previously
- assigned to the given link and address via DHCP.
- Arguments:
- Link - Supplies a pointer to the link to send the discovery request out on.
- LinkAddress - Supplies a pointer to the address structure to bind to.
- Return Value:
- Status code indicating whether or not the process was successfully
- initiated.
- --*/
- {
- PDHCP_CONTEXT DhcpContext;
- KSTATUS Status;
- DhcpContext = NetpDhcpCreateContext(Link, LinkAddress, NULL);
- if (DhcpContext == NULL) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- Status = PsCreateKernelThread(NetpDhcpReleaseThread,
- DhcpContext,
- "DhcpReleaseThread");
- if (!KSUCCESS(Status)) {
- NetpDhcpDestroyContext(DhcpContext);
- return Status;
- }
- return STATUS_SUCCESS;
- }
- VOID
- NetpDhcpReleaseThread (
- PVOID Parameter
- )
- /*++
- Routine Description:
- This routine attempts to release the IP address previously assigned via
- DHCP.
- Arguments:
- Parameter - Supplies a pointer supplied by the creator of the thread, in
- this case a pointer to the DHCP context structure.
- Return Value:
- None.
- --*/
- {
- PDHCP_CONTEXT DhcpContext;
- IP4_ADDRESS LocalAddress;
- BOOL LockHeld;
- KSTATUS Status;
- PSTR Step;
- ASSERT(KeGetRunLevel() == RunLevelLow);
- DhcpContext = (PDHCP_CONTEXT)Parameter;
- LockHeld = FALSE;
- Step = "Init";
- //
- // Create the scratch packet space and the socket.
- //
- DhcpContext->ScratchPacket = MmAllocatePagedPool(DHCP_SCRATCH_PACKET_SIZE,
- DHCP_ALLOCATION_TAG);
- if (DhcpContext->ScratchPacket == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpLeaseReleaseThreadEnd;
- }
- DhcpContext->ScratchPacketSize = DHCP_SCRATCH_PACKET_SIZE;
- Status = MmCreateIoBuffer(DhcpContext->ScratchPacket,
- DhcpContext->ScratchPacketSize,
- IO_BUFFER_FLAG_KERNEL_MODE_DATA,
- &(DhcpContext->ScratchPacketIoBuffer));
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseReleaseThreadEnd;
- }
- Status = IoSocketCreate(NetDomainIp4,
- NetSocketDatagram,
- SOCKET_INTERNET_PROTOCOL_UDP,
- 0,
- &(DhcpContext->Socket));
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseReleaseThreadEnd;
- }
- //
- // Bind that socket to the known DHCP client port. Make sure the link
- // address is still valid before copying it.
- //
- KeAcquireQueuedLock(DhcpContext->Link->QueuedLock);
- LockHeld = TRUE;
- if (DhcpContext->LinkAddress->Configured == FALSE) {
- Status = STATUS_NO_NETWORK_CONNECTION;
- goto DhcpLeaseReleaseThreadEnd;
- }
- RtlCopyMemory(&LocalAddress,
- &(DhcpContext->LinkAddress->Address),
- sizeof(NETWORK_ADDRESS));
- KeReleaseQueuedLock(DhcpContext->Link->QueuedLock);
- LockHeld = FALSE;
- LocalAddress.Port = DHCP_CLIENT_PORT;
- Status = IoSocketBindToAddress(TRUE,
- DhcpContext->Socket,
- DhcpContext->Link,
- (PNETWORK_ADDRESS)&LocalAddress,
- NULL,
- 0);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseReleaseThreadEnd;
- }
- //
- // Request the address that came back.
- //
- Step = "SendRelease";
- Status = NetpDhcpSendRelease(DhcpContext);
- if (!KSUCCESS(Status)) {
- goto DhcpLeaseReleaseThreadEnd;
- }
- DhcpLeaseReleaseThreadEnd:
- if (LockHeld != FALSE) {
- KeReleaseQueuedLock(DhcpContext->Link->QueuedLock);
- }
- if (!KSUCCESS(Status)) {
- RtlDebugPrint("Net: DHCP lease release failed at step '%s': %x.\n",
- Step,
- Status);
- }
- NetpDhcpDestroyContext(DhcpContext);
- return;
- }
- KSTATUS
- NetpDhcpSendDiscover (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine sends the DHCP discovery request out onto the subnet.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Return Value:
- Status code indicating whether or not the discovery request was
- successfully sent.
- --*/
- {
- PBYTE OptionByte;
- SOCKET_IO_PARAMETERS Parameters;
- IP4_ADDRESS RemoteAddress;
- PDHCP_PACKET Request;
- KSTATUS Status;
- ULONG TotalPacketSize;
- Request = NULL;
- //
- // Initialize the DHCP discover request.
- //
- Request = Context->ScratchPacket;
- RtlZeroMemory(Request, sizeof(DHCP_PACKET));
- Request->OperationCode = DHCP_OPERATION_REQUEST;
- Request->HardwareType = DHCP_HARDWARE_TYPE_ETHERNET;
- Request->HardwareAddressLength = DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH;
- Request->Hops = 0;
- Request->TransactionIdentifier = HlQueryTimeCounter() & MAX_ULONG;
- Context->ExpectedTransactionId = Request->TransactionIdentifier;
- Request->Seconds = 0;
- Request->Flags = 0;
- Request->ClientIpAddress = 0;
- RtlCopyMemory(&(Request->ClientHardwareAddress),
- &(Context->LinkAddress->PhysicalAddress.Address),
- DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH);
- Request->MagicCookie = CPU_TO_NETWORK32(DHCP_MAGIC_COOKIE);
- //
- // Initialize the options, which come right after the request. The first
- // option tells the server this is a discovery request. Options are always
- // a tuple of (OptionType, LengthOfValue, Value).
- //
- OptionByte = (PBYTE)(Request + 1);
- *OptionByte = DHCP_OPTION_DHCP_MESSAGE_TYPE;
- OptionByte += 1;
- *OptionByte = 1;
- OptionByte += 1;
- *OptionByte = DHCP_MESSAGE_DISCOVER;
- OptionByte += 1;
- //
- // Add the parameter request list option. Five parameters are being
- // requested with the offer.
- //
- *OptionByte = DHCP_OPTION_PARAMETER_REQUEST_LIST;
- OptionByte += 1;
- *OptionByte = 5;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_SUBNET_MASK;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_ROUTER;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_DOMAIN_NAME;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_DOMAIN_NAME_SERVER;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_IP_ADDRESS_LEASE_TIME;
- OptionByte += 1;
- //
- // Add the end tag.
- //
- *OptionByte = DHCP_OPTION_END;
- OptionByte += 1;
- *OptionByte = 0;
- OptionByte += 1;
- TotalPacketSize = (UINTN)OptionByte - (UINTN)Request;
- ASSERT(TotalPacketSize <= Context->ScratchPacketSize);
- //
- // Send off this request!
- //
- RtlZeroMemory(&RemoteAddress, sizeof(NETWORK_ADDRESS));
- RemoteAddress.Domain = NetDomainIp4;
- RemoteAddress.Address = IP4_BROADCAST_ADDRESS;
- RemoteAddress.Port = DHCP_SERVER_PORT;
- RtlZeroMemory(&Parameters, sizeof(SOCKET_IO_PARAMETERS));
- Parameters.TimeoutInMilliseconds = WAIT_TIME_INDEFINITE;
- Parameters.NetworkAddress = &(RemoteAddress.NetworkAddress);
- Parameters.Size = TotalPacketSize;
- Status = IoSocketSendData(TRUE,
- Context->Socket,
- &Parameters,
- Context->ScratchPacketIoBuffer);
- if (!KSUCCESS(Status)) {
- goto DhcpSendDiscoverEnd;
- }
- if (Parameters.Size != TotalPacketSize) {
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto DhcpSendDiscoverEnd;
- }
- Status = STATUS_SUCCESS;
- DhcpSendDiscoverEnd:
- return Status;
- }
- KSTATUS
- NetpDhcpReceiveOffer (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine receives the DHCP offer response, hopefully.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Return Value:
- Status code.
- --*/
- {
- ULONG Attempts;
- DHCP_REPLY Reply;
- KSTATUS Status;
- Attempts = 5;
- while (Attempts != 0) {
- Attempts -= 1;
- //
- // Atempt to receive a reply from the DHCP server. Quit if the request
- // times out but try again for any other failure.
- //
- Status = NetpDhcpReceiveReply(Context, &Reply);
- if (Status == STATUS_TIMEOUT) {
- break;
- }
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Try again if an offer message was not received.
- //
- if (Reply.MessageType != DHCP_MESSAGE_OFFER) {
- RtlDebugPrint("Skipping DHCP message as it wasn't an offer (%d), "
- "instead it had a message type of %d.\n",
- DHCP_MESSAGE_OFFER,
- Reply.MessageType);
- continue;
- }
- //
- // Copy the reply to the context. This will make sure that all the
- // required information is present in the reply.
- //
- Status = NetpDhcpCopyReplyToContext(Context, &Reply);
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Print the offer to the debugger now that the context is filled in,
- // if requested.
- //
- if ((NetDhcpDebugFlags & DHCP_DEBUG_FLAG_OFFER) != 0) {
- RtlDebugPrint("Net: DHCP Offer\n");
- NetpDhcpPrintContext(Context);
- }
- Status = STATUS_SUCCESS;
- break;
- }
- return Status;
- }
- KSTATUS
- NetpDhcpSendRequest (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine sends the DHCP address request out onto the subnet.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Renew - Supplies a boolean indicating whether or not this is a request to
- renew a lease.
- Return Value:
- Status code indicating whether or not the discovery request was
- successfully sent.
- --*/
- {
- PIP4_ADDRESS Ip4Address;
- PDHCP_LEASE Lease;
- BOOL LockHeld;
- PBYTE OptionByte;
- SOCKET_IO_PARAMETERS Parameters;
- IP4_ADDRESS RemoteAddress;
- PDHCP_PACKET Request;
- PIP4_ADDRESS RequestedIp4Address;
- PIP4_ADDRESS ServerIp4Address;
- KSTATUS Status;
- ULONG TotalPacketSize;
- ASSERT(KeGetRunLevel() == RunLevelLow);
- ASSERT(Context->Lease != NULL);
- Lease = Context->Lease;
- LockHeld = FALSE;
- Request = NULL;
- //
- // Initialize the DHCP discover request.
- //
- Request = Context->ScratchPacket;
- RtlZeroMemory(Request, sizeof(DHCP_PACKET));
- Request->OperationCode = DHCP_OPERATION_REQUEST;
- Request->HardwareType = DHCP_HARDWARE_TYPE_ETHERNET;
- Request->HardwareAddressLength = DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH;
- Request->Hops = 0;
- Request->TransactionIdentifier = Context->ExpectedTransactionId;
- Request->Seconds = 0;
- Request->Flags = 0;
- Request->ClientIpAddress = 0;
- //
- // To renew or rebind a lease, the client IP address is set in the reqest
- // header.
- //
- if ((Lease->State == DhcpLeaseStateRenewing) ||
- (Lease->State == DhcpLeaseStateRebinding)) {
- //
- // Renew and rebind are trying to extend an already configured link
- // address's IP address. Make sure that the link address is still
- // configured before copying its data.
- //
- KeAcquireQueuedLock(Context->Link->QueuedLock);
- LockHeld = TRUE;
- if (Context->LinkAddress->Configured == FALSE) {
- Status = STATUS_NO_NETWORK_CONNECTION;
- goto DhcpSendRequestEnd;
- }
- Ip4Address = (PIP4_ADDRESS)&(Context->LinkAddress->Address);
- ASSERT(Ip4Address->Domain == NetDomainIp4);
- ASSERT(Ip4Address->Address != 0);
- Request->ClientIpAddress = Ip4Address->Address;
- KeReleaseQueuedLock(Context->Link->QueuedLock);
- LockHeld = FALSE;
- }
- //
- // The physical address of a link address entry does not change. There is
- // no need to acquire the lock here.
- //
- RtlCopyMemory(&(Request->ClientHardwareAddress),
- &(Context->LinkAddress->PhysicalAddress.Address),
- DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH);
- Request->MagicCookie = CPU_TO_NETWORK32(DHCP_MAGIC_COOKIE);
- //
- // Initialize the options, which come right after the request. The first
- // option tells the server this is a request (for an address). Options are
- // always a tuple of (OptionType, LengthOfValue, Value).
- //
- OptionByte = (PBYTE)(Request + 1);
- *OptionByte = DHCP_OPTION_DHCP_MESSAGE_TYPE;
- OptionByte += 1;
- *OptionByte = 1;
- OptionByte += 1;
- *OptionByte = DHCP_MESSAGE_REQUEST;
- OptionByte += 1;
- //
- // Add the parameter request list option. Five parameters are being
- // requested. This must match the parameters requested during the
- // discover message (if a discover message was sent before the request).
- //
- *OptionByte = DHCP_OPTION_PARAMETER_REQUEST_LIST;
- OptionByte += 1;
- *OptionByte = 5;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_SUBNET_MASK;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_ROUTER;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_DOMAIN_NAME;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_DOMAIN_NAME_SERVER;
- OptionByte += 1;
- *OptionByte = DHCP_OPTION_IP_ADDRESS_LEASE_TIME;
- OptionByte += 1;
- //
- // The requested IP address and server identifier options must not be sent
- // on a renew or rebind request.
- //
- if ((Lease->State != DhcpLeaseStateRenewing) &&
- (Lease->State != DhcpLeaseStateRebinding)) {
- //
- // Add the requested address.
- //
- ASSERT(sizeof(ULONG) == 4);
- RequestedIp4Address = (PIP4_ADDRESS)(&(Context->OfferClientAddress));
- *OptionByte = DHCP_OPTION_REQUESTED_IP_ADDRESS;
- OptionByte += 1;
- *OptionByte = 4;
- OptionByte += 1;
- *((PULONG)OptionByte) = RequestedIp4Address->Address;
- OptionByte += sizeof(ULONG);
- //
- // Add the server address.
- //
- ServerIp4Address = (PIP4_ADDRESS)(&(Context->OfferServerAddress));
- *OptionByte = DHCP_OPTION_DHCP_SERVER;
- OptionByte += 1;
- *OptionByte = 4;
- OptionByte += 1;
- *((PULONG)OptionByte) = ServerIp4Address->Address;
- OptionByte += sizeof(ULONG);
- }
- //
- // Add the end tag.
- //
- *OptionByte = DHCP_OPTION_END;
- OptionByte += 1;
- *OptionByte = 0;
- OptionByte += 1;
- TotalPacketSize = (UINTN)OptionByte - (UINTN)Request;
- ASSERT(TotalPacketSize <= Context->ScratchPacketSize);
- //
- // Record the time at which the request was sent. This will be considered
- // the lease start time upon success.
- //
- KeGetSystemTime(&(Context->LeaseRequestTime));
- //
- // Send off this request! On renew, it is unicast to the server that
- // initially offered the lease. Otherwise it's broadcast to let all the
- // other DHCP servers that made offers know which one was selected.
- //
- RtlZeroMemory(&RemoteAddress, sizeof(NETWORK_ADDRESS));
- RemoteAddress.Domain = NetDomainIp4;
- if (Lease->State == DhcpLeaseStateRenewing) {
- //
- // Make sure that the link address is still configured before copying
- // its data.
- //
- KeAcquireQueuedLock(Context->Link->QueuedLock);
- LockHeld = TRUE;
- if (Context->LinkAddress->Configured == FALSE) {
- Status = STATUS_NO_NETWORK_CONNECTION;
- goto DhcpSendRequestEnd;
- }
- Ip4Address = (PIP4_ADDRESS)&(Context->LinkAddress->LeaseServerAddress);
- ASSERT(Ip4Address->Domain == NetDomainIp4);
- ASSERT(Ip4Address->Address != 0);
- RemoteAddress.Address = Ip4Address->Address;
- KeReleaseQueuedLock(Context->Link->QueuedLock);
- LockHeld = FALSE;
- } else {
- RemoteAddress.Address = IP4_BROADCAST_ADDRESS;
- }
- RemoteAddress.Port = DHCP_SERVER_PORT;
- RtlZeroMemory(&Parameters, sizeof(SOCKET_IO_PARAMETERS));
- Parameters.TimeoutInMilliseconds = WAIT_TIME_INDEFINITE;
- Parameters.NetworkAddress = &(RemoteAddress.NetworkAddress);
- Parameters.Size = TotalPacketSize;
- Status = IoSocketSendData(TRUE,
- Context->Socket,
- &Parameters,
- Context->ScratchPacketIoBuffer);
- if (!KSUCCESS(Status)) {
- goto DhcpSendRequestEnd;
- }
- if (Parameters.Size != TotalPacketSize) {
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto DhcpSendRequestEnd;
- }
- Status = STATUS_SUCCESS;
- DhcpSendRequestEnd:
- if (LockHeld != FALSE) {
- KeReleaseQueuedLock(Context->Link->QueuedLock);
- }
- return Status;
- }
- KSTATUS
- NetpDhcpReceiveAcknowledge (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine receives the acknowledgement from the DHCP server to the
- request just made.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Return Value:
- Status code.
- --*/
- {
- ULONG Attempts;
- PIP4_ADDRESS ClientIp4Address;
- DHCP_REPLY Reply;
- PIP4_ADDRESS ServerIp4Address;
- KSTATUS Status;
- Attempts = 5;
- while (Attempts != 0) {
- Attempts -= 1;
- //
- // Atempt to receive a reply from the DHCP server. Quit if the request
- // times out but try again for any other failure.
- //
- Status = NetpDhcpReceiveReply(Context, &Reply);
- if (Status == STATUS_TIMEOUT) {
- break;
- }
- if (!KSUCCESS(Status)) {
- continue;
- }
- //
- // Try again if an acknowledge message was not received.
- //
- if (Reply.MessageType != DHCP_MESSAGE_ACKNOWLEDGE) {
- RtlDebugPrint("Skipping DHCP message as it wasn't an ACK (%d), "
- "instead it had a message type of %d.\n",
- DHCP_MESSAGE_ACKNOWLEDGE,
- Reply.MessageType);
- continue;
- }
- //
- // If the DHCP lease is initializing, then an offer should have already
- // been received and stored in the context. If the client or server
- // addresses were provided in the acknowledgement, ensure they are the
- // same as the original offer.
- //
- if (Context->Lease->State == DhcpLeaseStateInitialize) {
- ServerIp4Address = (PIP4_ADDRESS)(&(Context->OfferServerAddress));
- ClientIp4Address = (PIP4_ADDRESS)(&(Context->OfferClientAddress));
- if (((Reply.ServerIpAddress != 0) &&
- (Reply.ServerIpAddress != ServerIp4Address->Address)) ||
- ((Reply.OfferedIpAddress != 0) &&
- (Reply.OfferedIpAddress != ClientIp4Address->Address))) {
- continue;
- }
- //
- // If the lease time does not equal the offer's lease time, then
- // recalculate the renewal and rebinding times if they were not
- // supplied.
- //
- if ((Reply.LeaseTime != 0) &&
- (Reply.LeaseTime != Context->LeaseTime)) {
- if (Reply.RenewalTime == 0) {
- Reply.RenewalTime = DHCP_GET_DEFAULT_RENEWAL_TIME(
- Reply.LeaseTime);
- }
- if (Reply.RebindingTime == 0) {
- Reply.RebindingTime = DHCP_GET_DEFAULT_REBINDING_TIME(
- Reply.LeaseTime);
- }
- Context->LeaseTime = Reply.LeaseTime;
- Context->RenewalTime = Reply.RenewalTime;
- Context->RebindingTime = Reply.RebindingTime;
- }
- //
- // For the renewal and rebinding states, the acknowledgement should
- // contain the complete information for the renewal offer. Copy the
- // whole reply to the context. If something is missing, the copy
- // routine will fail.
- //
- } else {
- ASSERT((Context->Lease->State == DhcpLeaseStateRenewing) ||
- (Context->Lease->State == DhcpLeaseStateRebinding));
- Status = NetpDhcpCopyReplyToContext(Context, &Reply);
- if (!KSUCCESS(Status)) {
- continue;
- }
- }
- Status = STATUS_SUCCESS;
- break;
- }
- return Status;
- }
- KSTATUS
- NetpDhcpSendRelease (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine sends a release message to the DHCP server in order to release
- the IP address that the server leased to it.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Return Value:
- Status code.
- --*/
- {
- PIP4_ADDRESS Ip4Address;
- PBYTE OptionByte;
- SOCKET_IO_PARAMETERS Parameters;
- IP4_ADDRESS RemoteAddress;
- PDHCP_PACKET Request;
- PIP4_ADDRESS ServerIp4Address;
- KSTATUS Status;
- ULONG TotalPacketSize;
- Request = NULL;
- //
- // Initialize the DHCP release request.
- //
- Request = Context->ScratchPacket;
- RtlZeroMemory(Request, sizeof(DHCP_PACKET));
- Request->OperationCode = DHCP_OPERATION_REQUEST;
- Request->HardwareType = DHCP_HARDWARE_TYPE_ETHERNET;
- Request->HardwareAddressLength = DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH;
- Request->Hops = 0;
- Request->TransactionIdentifier = HlQueryTimeCounter() & MAX_ULONG;
- Context->ExpectedTransactionId = Request->TransactionIdentifier;
- Request->Seconds = 0;
- Request->Flags = 0;
- Ip4Address = (PIP4_ADDRESS)&(Context->OfferClientAddress);
- ASSERT(Ip4Address->Domain == NetDomainIp4);
- ASSERT(Ip4Address->Address != 0);
- Request->ClientIpAddress = Ip4Address->Address;
- RtlCopyMemory(&(Request->ClientHardwareAddress),
- &(Context->LinkAddress->PhysicalAddress.Address),
- DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH);
- Request->MagicCookie = CPU_TO_NETWORK32(DHCP_MAGIC_COOKIE);
- //
- // Initialize the options, which come right after the request. The first
- // option tells the server this is a release request. Options are always
- // a tuple of (OptionType, LengthOfValue, Value).
- //
- OptionByte = (PBYTE)(Request + 1);
- *OptionByte = DHCP_OPTION_DHCP_MESSAGE_TYPE;
- OptionByte += 1;
- *OptionByte = 1;
- OptionByte += 1;
- *OptionByte = DHCP_MESSAGE_RELEASE;
- OptionByte += 1;
- //
- // Add the server address.
- //
- ServerIp4Address = (PIP4_ADDRESS)(&(Context->OfferServerAddress));
- ASSERT(ServerIp4Address->Domain == NetDomainIp4);
- ASSERT(ServerIp4Address->Address != 0);
- *OptionByte = DHCP_OPTION_DHCP_SERVER;
- OptionByte += 1;
- *OptionByte = 4;
- OptionByte += 1;
- *((PULONG)OptionByte) = ServerIp4Address->Address;
- OptionByte += sizeof(ULONG);
- //
- // Add the end tag.
- //
- *OptionByte = DHCP_OPTION_END;
- OptionByte += 1;
- *OptionByte = 0;
- OptionByte += 1;
- TotalPacketSize = (UINTN)OptionByte - (UINTN)Request;
- ASSERT(TotalPacketSize <= Context->ScratchPacketSize);
- //
- // Send off this request!
- //
- RtlZeroMemory(&RemoteAddress, sizeof(NETWORK_ADDRESS));
- RemoteAddress.Domain = NetDomainIp4;
- Ip4Address = (PIP4_ADDRESS)&(Context->OfferServerAddress);
- ASSERT(Ip4Address->Domain == NetDomainIp4);
- ASSERT(Ip4Address->Address != 0);
- RemoteAddress.Address = Ip4Address->Address;
- RemoteAddress.Port = DHCP_SERVER_PORT;
- RtlZeroMemory(&Parameters, sizeof(SOCKET_IO_PARAMETERS));
- Parameters.TimeoutInMilliseconds = WAIT_TIME_INDEFINITE;
- Parameters.NetworkAddress = &(RemoteAddress.NetworkAddress);
- Parameters.Size = TotalPacketSize;
- Status = IoSocketSendData(TRUE,
- Context->Socket,
- &Parameters,
- Context->ScratchPacketIoBuffer);
- if (!KSUCCESS(Status)) {
- goto DhcpSendDiscoverEnd;
- }
- if (Parameters.Size != TotalPacketSize) {
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto DhcpSendDiscoverEnd;
- }
- Status = STATUS_SUCCESS;
- DhcpSendDiscoverEnd:
- return Status;
- }
- KSTATUS
- NetpDhcpReceiveReply (
- PDHCP_CONTEXT Context,
- PDHCP_REPLY Reply
- )
- /*++
- Routine Description:
- This routine attempts to receive a replay from the DHCP server for either
- an offer or an acknowledge packet.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Reply - Supplies a pointer to the DHCP reply context that is to be filled
- in by this routine.
- Return Value:
- Status code.
- --*/
- {
- ULONG AddressOffset;
- ULONG Offset;
- BYTE OptionByte;
- PBYTE OptionBytePointer;
- BYTE OptionLength;
- ULONGLONG PacketSize;
- SOCKET_IO_PARAMETERS Parameters;
- ULONG RebindingTime;
- PDHCP_PACKET Response;
- ULONG RouterIp;
- NETWORK_ADDRESS ServerAddress;
- ULONG ServerIp;
- KSTATUS Status;
- Response = Context->ScratchPacket;
- OptionBytePointer = (PUCHAR)Response;
- RtlZeroMemory(&Parameters, sizeof(SOCKET_IO_PARAMETERS));
- Parameters.TimeoutInMilliseconds = DHCP_ACKNOWLEDGE_TIMEOUT;
- Parameters.NetworkAddress = &ServerAddress;
- Parameters.Size = Context->ScratchPacketSize;
- Status = IoSocketReceiveData(TRUE,
- Context->Socket,
- &Parameters,
- Context->ScratchPacketIoBuffer);
- if (Status == STATUS_TIMEOUT) {
- goto DhcpReceiveReplyEnd;
- }
- if (!KSUCCESS(Status)) {
- RtlDebugPrint("NetpDhcpReceiveReply skipping packet because receive "
- "status was %x.\n",
- Status);
- goto DhcpReceiveReplyEnd;
- }
- PacketSize = Parameters.Size;
- //
- // Validate some basic attributes about the packet.
- //
- if (PacketSize < sizeof(DHCP_PACKET)) {
- RtlDebugPrint("DHCP ack packet too small. Was %d bytes, should "
- "have been at least %d bytes.\n",
- PacketSize,
- sizeof(DHCP_PACKET));
- Status = STATUS_DATA_LENGTH_MISMATCH;
- goto DhcpReceiveReplyEnd;
- }
- if (Response->OperationCode != DHCP_OPERATION_REPLY) {
- Status = STATUS_UNSUCCESSFUL;
- goto DhcpReceiveReplyEnd;
- }
- if ((Response->HardwareType != DHCP_HARDWARE_TYPE_ETHERNET) ||
- (Response->HardwareAddressLength !=
- DHCP_ETHERNET_HARDWARE_ADDRESS_LENGTH)) {
- RtlDebugPrint("DHCP packet skipped because hardware type or "
- "length didn't match standard ethernet.");
- Status = STATUS_UNSUCCESSFUL;
- goto DhcpReceiveReplyEnd;
- }
- if (NETWORK_TO_CPU32(Response->MagicCookie) != DHCP_MAGIC_COOKIE) {
- RtlDebugPrint("DHCP packet skipped because the magic cookie was "
- "wrong.\n");
- Status = STATUS_UNSUCCESSFUL;
- goto DhcpReceiveReplyEnd;
- }
- //
- // Quietly skip packets not directed at this request.
- //
- if (Response->TransactionIdentifier != Context->ExpectedTransactionId) {
- Status = STATUS_UNSUCCESSFUL;
- goto DhcpReceiveReplyEnd;
- }
- RtlZeroMemory(Reply, sizeof(DHCP_REPLY));
- Reply->ServerIpAddress = Response->ServerIpAddress;
- Reply->OfferedIpAddress = Response->YourIpAddress;
- //
- // Parse the options.
- //
- Offset = sizeof(DHCP_PACKET);
- while (Offset < PacketSize) {
- OptionByte = OptionBytePointer[Offset];
- Offset += 1;
- //
- // Skip padding.
- //
- if (OptionByte == DHCP_OPTION_PAD) {
- continue;
- }
- //
- // Stop if the end is reached.
- //
- if (OptionByte == DHCP_OPTION_END) {
- break;
- }
- //
- // Get the length of the option.
- //
- if (Offset >= PacketSize) {
- break;
- }
- OptionLength = OptionBytePointer[Offset];
- Offset += 1;
- //
- // Stop if the entire option value cannot be retrieved.
- //
- if (Offset + OptionLength > PacketSize) {
- break;
- }
- //
- // Parse the known options, starting with the message type.
- //
- if (OptionByte == DHCP_OPTION_DHCP_MESSAGE_TYPE) {
- Reply->MessageType = OptionBytePointer[Offset];
- } else if (OptionByte == DHCP_OPTION_DHCP_SERVER) {
- if (OptionLength == 4) {
- ServerIp = *((PULONG)(&(OptionBytePointer[Offset])));
- Reply->ServerIpAddress = ServerIp;
- }
- } else if (OptionByte == DHCP_OPTION_SUBNET_MASK) {
- if (OptionLength == 4) {
- Reply->SubnetMask = *((PULONG)(&(OptionBytePointer[Offset])));
- }
- } else if (OptionByte == DHCP_OPTION_ROUTER) {
- if (OptionLength == 4) {
- RouterIp = *((PULONG)(&(OptionBytePointer[Offset])));
- Reply->RouterIpAddress = RouterIp;
- }
- } else if (OptionByte == DHCP_OPTION_DOMAIN_NAME_SERVER) {
- AddressOffset = Offset;
- while (AddressOffset + 4 <= Offset + OptionLength) {
- Reply->DomainNameServer[Reply->DomainNameServerCount] =
- *((PULONG)(&(OptionBytePointer[AddressOffset])));
- AddressOffset += 4;
- Reply->DomainNameServerCount += 1;
- if (Reply->DomainNameServerCount == DHCP_MAX_DNS_SERVERS) {
- break;
- }
- }
- } else if (OptionByte == DHCP_OPTION_IP_ADDRESS_LEASE_TIME) {
- if (OptionLength == 4) {
- Reply->LeaseTime = *((PULONG)(&(OptionBytePointer[Offset])));
- Reply->LeaseTime = NETWORK_TO_CPU32(Reply->LeaseTime);
- }
- } else if (OptionByte == DHCP_OPTION_RENEWAL_TIME) {
- if (OptionLength == 4) {
- Reply->RenewalTime = *((PULONG)(&(OptionBytePointer[Offset])));
- Reply->RenewalTime = NETWORK_TO_CPU32(Reply->RenewalTime);
- }
- } else if (OptionByte == DHCP_OPTION_REBINDING_TIME) {
- if (OptionLength == 4) {
- RebindingTime = *((PULONG)(&(OptionBytePointer[Offset])));
- Reply->RebindingTime = NETWORK_TO_CPU32(RebindingTime);
- }
- }
- //
- // Skip over the option length.
- //
- Offset += OptionLength;
- }
- ASSERT(Status == STATUS_SUCCESS);
- //
- // Set the override renewal and rebinding times if enabled.
- //
- if (NetDhcpDebugOverrideRenewal != FALSE) {
- Reply->RenewalTime = NetDhcpDebugRenewalTime;
- Reply->RebindingTime = NetDhcpDebugRebindingTime;
- }
- DhcpReceiveReplyEnd:
- return Status;
- }
- PDHCP_CONTEXT
- NetpDhcpCreateContext (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress,
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine creates a DHCP context.
- Arguments:
- Link - Supplies a pointer to the network link for the DHCP context.
- LinkAddress - Supplies a pointer to the network link address for the DHCP
- context.
- Lease - Supplies an optional pointer to a DHCP lease to be associated with
- the context.
- Return Value:
- Returns a pointer to the newly allocated DHCP context on success, or NULL
- on failure.
- --*/
- {
- PDHCP_CONTEXT Context;
- Context = MmAllocatePagedPool(sizeof(DHCP_CONTEXT), DHCP_ALLOCATION_TAG);
- if (Context == NULL) {
- return NULL;
- }
- RtlZeroMemory(Context, sizeof(DHCP_CONTEXT));
- NetLinkAddReference(Link);
- Context->Link = Link;
- Context->LinkAddress = LinkAddress;
- if (Lease != NULL) {
- NetpDhcpLeaseAddReference(Lease);
- Context->Lease = Lease;
- }
- return Context;
- }
- VOID
- NetpDhcpDestroyContext (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine destroys the given DHCP context.
- Arguments:
- Context - Supplies a pointer to the DHCP context to destroy.
- Return Value:
- None.
- --*/
- {
- if (Context->Socket != NULL) {
- IoClose(Context->Socket);
- }
- if (Context->ScratchPacketIoBuffer != NULL) {
- MmFreeIoBuffer(Context->ScratchPacketIoBuffer);
- }
- if (Context->ScratchPacket != NULL) {
- MmFreePagedPool(Context->ScratchPacket);
- }
- ASSERT(Context->Link != NULL);
- NetLinkReleaseReference(Context->Link);
- if (Context->Lease != NULL) {
- NetpDhcpLeaseReleaseReference(Context->Lease);
- }
- MmFreePagedPool(Context);
- return;
- }
- PDHCP_LEASE
- NetpDhcpCreateLease (
- VOID
- )
- /*++
- Routine Description:
- This routine creates an the context for a DHCP lease.
- Arguments:
- None.
- Return Value:
- Returns a pointer to a DHCP lease context on success, or NULL on failure.
- --*/
- {
- PDHCP_LEASE NewLease;
- KSTATUS Status;
- NewLease = MmAllocateNonPagedPool(sizeof(DHCP_LEASE), DHCP_ALLOCATION_TAG);
- if (NewLease == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpCreateAssignmentContextEnd;
- }
- RtlZeroMemory(NewLease, sizeof(DHCP_LEASE));
- NewLease->ReferenceCount = 1;
- NewLease->Timer = KeCreateTimer(DHCP_ALLOCATION_TAG);
- if (NewLease->Timer == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpCreateAssignmentContextEnd;
- }
- NewLease->Dpc = KeCreateDpc(NetpDhcpLeaseDpcRoutine, NewLease);
- if (NewLease->Dpc == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpCreateAssignmentContextEnd;
- }
- NewLease->WorkItem = KeCreateWorkItem(NULL,
- WorkPriorityNormal,
- NetpDhcpLeaseWorkRoutine,
- NewLease,
- DHCP_ALLOCATION_TAG);
- if (NewLease->WorkItem == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto DhcpCreateAssignmentContextEnd;
- }
- Status = STATUS_SUCCESS;
- DhcpCreateAssignmentContextEnd:
- if (!KSUCCESS(Status)) {
- if (NewLease != NULL) {
- NetpDhcpDestroyLease(NewLease);
- NewLease = NULL;
- }
- }
- return NewLease;
- }
- VOID
- NetpDhcpLeaseAddReference (
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine increases the reference count on a DHCP lease.
- Arguments:
- Lease - Supplies a pointer to the DHCP lease whose reference count should
- be incremented.
- Return Value:
- None.
- --*/
- {
- ULONG OldReferenceCount;
- OldReferenceCount = RtlAtomicAdd32(&(Lease->ReferenceCount), 1);
- ASSERT((OldReferenceCount != 0) & (OldReferenceCount < 0x20000000));
- return;
- }
- VOID
- NetpDhcpLeaseReleaseReference (
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine decreases the reference count of a DHCP lease, and destroys
- the lease if the reference count drops to zero.
- Arguments:
- Lease - Supplies a pointer to the DHCP lease whose reference count should
- be decremented.
- Return Value:
- None.
- --*/
- {
- ULONG OldReferenceCount;
- OldReferenceCount = RtlAtomicAdd32(&(Lease->ReferenceCount), -1);
- ASSERT(OldReferenceCount != 0);
- if (OldReferenceCount == 1) {
- NetpDhcpDestroyLease(Lease);
- }
- return;
- }
- PDHCP_LEASE
- NetpDhcpFindLease (
- PNET_LINK Link,
- PNET_LINK_ADDRESS_ENTRY LinkAddress
- )
- /*++
- Routine Description:
- This routine attemps to find an existing lease for the given link and link
- address. If a lease is found, a reference is added to the lease.
- Arguments:
- Link - Supplies a pointer to a network link.
- LinkAddress - Supplies a pointer to a network link address.
- Return Value:
- Returns a pointer to the DHCP lease that exists for the given link and link
- address, or NULL if no such lease exists.
- --*/
- {
- PLIST_ENTRY CurrentEntry;
- PDHCP_LEASE CurrentLease;
- PDHCP_LEASE FoundLease;
- FoundLease = NULL;
- KeAcquireSpinLock(&NetDhcpLeaseListLock);
- CurrentEntry = NetDhcpLeaseListHead.Next;
- while (CurrentEntry != &(NetDhcpLeaseListHead)) {
- CurrentLease = LIST_VALUE(CurrentEntry, DHCP_LEASE, ListEntry);
- if ((CurrentLease->Link == Link) &&
- (CurrentLease->LinkAddress == LinkAddress)) {
- NetpDhcpLeaseAddReference(CurrentLease);
- FoundLease = CurrentLease;
- break;
- }
- CurrentEntry = CurrentEntry->Next;
- }
- KeReleaseSpinLock(&NetDhcpLeaseListLock);
- return FoundLease;
- }
- VOID
- NetpDhcpDestroyLease (
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine destroys a DHCP lease context.
- Arguments:
- Lease - Supplies a pointer to a DHCP lease.
- Return Value:
- None.
- --*/
- {
- ASSERT(Lease->ListEntry.Next == NULL);
- if (Lease->Link != NULL) {
- NetLinkReleaseReference(Lease->Link);
- }
- if (Lease->Timer != NULL) {
- KeDestroyTimer(Lease->Timer);
- }
- if (Lease->Dpc != NULL) {
- KeDestroyDpc(Lease->Dpc);
- }
- if (Lease->WorkItem != NULL) {
- KeDestroyWorkItem(Lease->WorkItem);
- }
- MmFreeNonPagedPool(Lease);
- return;
- }
- VOID
- NetpDhcpQueueLeaseExtension (
- PDHCP_LEASE Lease
- )
- /*++
- Routine Description:
- This routine queues the lease timer to attempt a lease extension. It
- determines the correct duration for the timer.
- Arguments:
- Lease - Supplies a pointer to the lease that needs its timer queued.
- Return Value:
- None.
- --*/
- {
- SYSTEM_TIME CurrentSystemTime;
- ULONGLONG DueTime;
- LONGLONG ElapsedLeaseTime;
- ULONGLONG StateChangeTime;
- KSTATUS Status;
- ULONGLONG TimerDuration;
- ULONGLONG TimeToStateChange;
- if (Lease->State == DhcpLeaseStateBound) {
- ASSERT(Lease->RenewalTime != 0);
- TimerDuration = Lease->RenewalTime;
- } else {
- KeGetSystemTime(&CurrentSystemTime);
- ElapsedLeaseTime = CurrentSystemTime.Seconds -
- Lease->LinkAddress->LeaseStartTime.Seconds;
- ASSERT(ElapsedLeaseTime >= 0);
- //
- // Determine the time of the next state change.
- //
- if (Lease->State == DhcpLeaseStateRenewing) {
- StateChangeTime = Lease->RebindingTime;
- } else {
- ASSERT(Lease->State == DhcpLeaseStateRebinding);
- StateChangeTime = Lease->LeaseTime;
- }
- //
- // Set the time for half the time until the next state change. If
- // that results in a timer duration that is less than the minimum,
- // just schedule the timer for the next state change time.
- //
- TimerDuration = 0;
- if (StateChangeTime > ElapsedLeaseTime) {
- TimeToStateChange = StateChangeTime - ElapsedLeaseTime;
- TimerDuration = TimeToStateChange >> 1;
- if (TimerDuration < DHCP_TIMER_DURATION_MINIMUM) {
- TimerDuration = TimeToStateChange;
- }
- }
- }
- TimerDuration *= MICROSECONDS_PER_SECOND;
- TimerDuration = KeConvertMicrosecondsToTimeTicks(TimerDuration);
- DueTime = HlQueryTimeCounter() + TimerDuration;
- Status = KeQueueTimer(Lease->Timer,
- TimerQueueSoft,
- DueTime,
- 0,
- 0,
- Lease->Dpc);
- ASSERT(KSUCCESS(Status));
- return;
- }
- VOID
- NetpDhcpLeaseDpcRoutine (
- PDPC Dpc
- )
- /*++
- Routine Description:
- This routine implements the DPC routine that fires when a lease timer
- expires. It queues the work item.
- Arguments:
- Dpc - Supplies a pointer to the DPC that is running.
- Return Value:
- None.
- --*/
- {
- PDHCP_LEASE Lease;
- Lease = (PDHCP_LEASE)Dpc->UserData;
- KeQueueWorkItem(Lease->WorkItem);
- return;
- }
- VOID
- NetpDhcpLeaseWorkRoutine (
- PVOID Parameter
- )
- /*++
- Routine Description:
- This routine implements the lease timer expiration work routine.
- Arguments:
- Parameter - Supplies a pointer to a lease context.
- Return Value:
- None.
- --*/
- {
- SYSTEM_TIME CurrentSystemTime;
- LONGLONG ElapsedLeaseTime;
- PDHCP_LEASE Lease;
- BOOL LinkUp;
- KSTATUS Status;
- Lease = (PDHCP_LEASE)Parameter;
- ASSERT(Lease->ReferenceCount >= 1);
- //
- // If the link is down then do not continue.
- //
- NetGetLinkState(Lease->Link, &LinkUp, NULL);
- if (LinkUp == FALSE) {
- return;
- }
- //
- // Determine the current state based on the time.
- //
- KeGetSystemTime(&CurrentSystemTime);
- ElapsedLeaseTime = CurrentSystemTime.Seconds -
- Lease->LinkAddress->LeaseStartTime.Seconds;
- //
- // If the elapsed time is greater than the lease time, then move back to
- // the initialize phase.
- //
- if (ElapsedLeaseTime >= Lease->LeaseTime) {
- Lease->State = DhcpLeaseStateInitialize;
- //
- // If the elapsed time is greater than or equal to the rebinding time,
- // then the lease is in the rebinding state.
- //
- } else if (ElapsedLeaseTime >= Lease->RebindingTime) {
- Lease->State = DhcpLeaseStateRebinding;
- //
- // Otherwise, even if the elapsed time is less than the renewal time, move
- // the lease to the renewal state.
- //
- } else {
- Lease->State = DhcpLeaseStateRenewing;
- }
- //
- // If the lease is back in the initialization state, then the lease
- // expired. Try to re-initialize the address. Note that the lease cannot be
- // destroyed in its own work-item. The re-assignment process will handle
- // destroying the lease.
- //
- if (Lease->State == DhcpLeaseStateInitialize) {
- Status = NetpDhcpBeginAssignment(Lease->Link, Lease->LinkAddress);
- if (!KSUCCESS(Status)) {
- //
- // TODO: Handle failed DHCP.
- //
- ASSERT(FALSE);
- }
- //
- // Otherwise schedule work to try to renew (or rebind) the lease. If this
- // fails, try again later.
- //
- } else {
- Status = NetpDhcpBeginLeaseExtension(Lease);
- if (!KSUCCESS(Status)) {
- NetpDhcpQueueLeaseExtension(Lease);
- }
- }
- return;
- }
- KSTATUS
- NetpDhcpCopyReplyToContext (
- PDHCP_CONTEXT Context,
- PDHCP_REPLY Reply
- )
- /*++
- Routine Description:
- This routine copies the state from the given reply into the context. It
- makes sure that all the necessary state is present in the reply.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Reply - Supplies a pointer to the DHCP reply context that will be copied to
- the DHCP context.
- Return Value:
- Status code.
- --*/
- {
- ULONG AddressIndex;
- PIP4_ADDRESS Ip4Address;
- KSTATUS Status;
- if ((Reply->ServerIpAddress == 0) ||
- (Reply->OfferedIpAddress == 0) ||
- (Reply->RouterIpAddress == 0) ||
- (Reply->SubnetMask == 0) ||
- (Reply->DomainNameServerCount == 0) ||
- (Reply->LeaseTime == 0)) {
- RtlDebugPrint("DHCP: A required parameter was missing from the "
- "reply:\n ServerIp: %x\n OfferedIpAddress: %x,\n "
- "Router: %x\n SubnetMask: %x\n "
- "DomainNameServerCount: %x\n LeaseTime: %x\n",
- Reply->ServerIpAddress,
- Reply->OfferedIpAddress,
- Reply->RouterIpAddress,
- Reply->SubnetMask,
- Reply->DomainNameServerCount,
- Reply->LeaseTime);
- Status = STATUS_INVALID_PARAMETER;
- goto DhcpCopyReplyToContextEnd;
- }
- //
- // Fill out the network address structures.
- //
- Ip4Address = (PIP4_ADDRESS)(&(Context->OfferClientAddress));
- Ip4Address->Domain = NetDomainIp4;
- Ip4Address->Address = Reply->OfferedIpAddress;
- Ip4Address = (PIP4_ADDRESS)(&(Context->OfferSubnetMask));
- Ip4Address->Domain = NetDomainIp4;
- Ip4Address->Address = Reply->SubnetMask;
- Ip4Address = (PIP4_ADDRESS)(&(Context->OfferServerAddress));
- Ip4Address->Domain = NetDomainIp4;
- Ip4Address->Address = Reply->ServerIpAddress;
- Ip4Address = (PIP4_ADDRESS)(&(Context->OfferRouter));
- Ip4Address->Domain = NetDomainIp4;
- Ip4Address->Address = Reply->RouterIpAddress;
- Context->OfferDnsAddressCount = Reply->DomainNameServerCount;
- for (AddressIndex = 0;
- AddressIndex < Reply->DomainNameServerCount;
- AddressIndex += 1) {
- Ip4Address =
- (PIP4_ADDRESS)(&(Context->OfferDnsAddress[AddressIndex]));
- Ip4Address->Domain = NetDomainIp4;
- Ip4Address->Address = Reply->DomainNameServer[AddressIndex];
- }
- //
- // Copy the lease time information.
- //
- Context->LeaseTime = Reply->LeaseTime;
- if (Reply->RenewalTime == 0) {
- Reply->RenewalTime = DHCP_GET_DEFAULT_RENEWAL_TIME(Reply->LeaseTime);
- }
- Context->RenewalTime = Reply->RenewalTime;
- if (Reply->RebindingTime == 0) {
- Reply->RebindingTime = DHCP_GET_DEFAULT_REBINDING_TIME(
- Reply->LeaseTime);
- }
- Context->RebindingTime = Reply->RebindingTime;
- Status = STATUS_SUCCESS;
- DhcpCopyReplyToContextEnd:
- return Status;
- }
- VOID
- NetpDhcpPrintContext (
- PDHCP_CONTEXT Context
- )
- /*++
- Routine Description:
- This routine prints out the IP address and lease time information for a
- DHCP context.
- Arguments:
- Context - Supplies a pointer to the DHCP context information.
- Return Value:
- None.
- --*/
- {
- RtlDebugPrint("%20s: %d.%d.%d.%d\n"
- "%20s: %d.%d.%d.%d\n"
- "%20s: %d.%d.%d.%d\n"
- "%20s: %d.%d.%d.%d\n"
- "%20s: %d hours.\n",
- "Server IP",
- (UCHAR)Context->OfferServerAddress.Address[0],
- (UCHAR)(Context->OfferServerAddress.Address[0] >> 8),
- (UCHAR)(Context->OfferServerAddress.Address[0] >> 16),
- (UCHAR)(Context->OfferServerAddress.Address[0] >> 24),
- "Offered IP",
- (UCHAR)Context->OfferClientAddress.Address[0],
- (UCHAR)(Context->OfferClientAddress.Address[0] >> 8),
- (UCHAR)(Context->OfferClientAddress.Address[0] >> 16),
- (UCHAR)(Context->OfferClientAddress.Address[0] >> 24),
- "Router IP",
- (UCHAR)Context->OfferRouter.Address[0],
- (UCHAR)(Context->OfferRouter.Address[0] >> 8),
- (UCHAR)(Context->OfferRouter.Address[0] >> 16),
- (UCHAR)(Context->OfferRouter.Address[0] >> 24),
- "DNS Server IP",
- (UCHAR)Context->OfferDnsAddress[0].Address[0],
- (UCHAR)(Context->OfferDnsAddress[0].Address[0] >> 8),
- (UCHAR)(Context->OfferDnsAddress[0].Address[0] >> 16),
- (UCHAR)(Context->OfferDnsAddress[0].Address[0] >> 24),
- "Lease Time",
- Context->LeaseTime / 3600);
- return;
- }
|