Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

625 lines
19 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. mdhccapi.c
  5. Abstract:
  6. This file contains the client side APIs for the MCAST.
  7. Author:
  8. Munil Shah (munils) 02-Sept-97
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #include <dhcploc.h>
  15. #include <dhcppro.h>
  16. #include "mdhcpcli.h"
  17. DWORD
  18. MadcapInitGlobalData(
  19. VOID
  20. );
  21. VOID
  22. MadcapCleanupGlobalData(
  23. VOID
  24. );
  25. DWORD
  26. APIENTRY
  27. McastApiStartup(
  28. IN OUT PDWORD pVersion
  29. )
  30. /*++
  31. Routine Description:
  32. This routine returns the current version of the apis and allocates any
  33. necessary resources.
  34. Arguments:
  35. pVersion - Version of the api clients. On return contains version of the
  36. api implementation.
  37. Return Value:
  38. ERROR_NOT_SUPPORTED if client version greater than impl version.
  39. (other Win32 errors)
  40. --*/
  41. {
  42. DWORD Error;
  43. Error = ERROR_SUCCESS;
  44. if (!pVersion) {
  45. return ERROR_INVALID_PARAMETER;
  46. }
  47. // do we support this client version?
  48. if (*pVersion > MCAST_API_CURRENT_VERSION) {
  49. // not supported
  50. Error = ERROR_NOT_SUPPORTED;
  51. } else {
  52. // if client specified its version, use that
  53. // o/w assume version 1.0
  54. if (*pVersion) {
  55. gMadcapClientApplVersion = *pVersion;
  56. } else {
  57. gMadcapClientApplVersion = MCAST_API_VERSION_1;
  58. }
  59. }
  60. *pVersion = MCAST_API_CURRENT_VERSION;
  61. if( ERROR_SUCCESS == Error ) {
  62. Error = MadcapInitGlobalData();
  63. if (ERROR_SUCCESS != Error) {
  64. DhcpPrint((DEBUG_ERRORS, "McastApiStartup - Could not allocate resources %ld\n", Error));
  65. Error = ERROR_NO_SYSTEM_RESOURCES;
  66. }
  67. }
  68. return Error;
  69. }
  70. VOID
  71. APIENTRY
  72. McastApiCleanup(
  73. VOID
  74. )
  75. /*++
  76. Routine Description:
  77. This routine de-allocates resources allocated by the Startup routine.
  78. It must be called only AFTER a successful call to McastApiStartup.
  79. --*/
  80. {
  81. MadcapCleanupGlobalData();
  82. }
  83. DWORD
  84. APIENTRY
  85. McastEnumerateScopes(
  86. IN IP_ADDR_FAMILY AddrFamily,
  87. IN BOOL ReQuery,
  88. IN OUT PMCAST_SCOPE_ENTRY pScopeList,
  89. IN OUT PDWORD pScopeLen,
  90. OUT PDWORD pScopeCount
  91. )
  92. /*++
  93. Routine Description:
  94. This routine enumerates the multicast scopes available on the network.
  95. Arguments:
  96. AddrFamily - AF_INET for IPv4 and AF_INET6 for IPv6
  97. ReQuery - TRUE if the calls wants the list to be requried. FALSE o/w.
  98. pScopeList - pointer to the buffer where the scopelist is to be retrieved.
  99. This parameter can be NULL if only the length of the buffer is
  100. being retrieved.
  101. When this buffer is NULL, the API will force the re-query of the
  102. scope list from the MCAST servers.
  103. pScopeLen - Pointer to a variable that specifies the size, in bytes, of the
  104. buffer pointed to by the pScopeList parameter. When the function returns,
  105. this variable contains the size of the data copied to pScopeList;
  106. The pScopeLen parameter can not be NULL.
  107. If the buffer specified by pScopeList parameter is not large enough
  108. to hold the data, the function returns the value ERROR_MORE_DATA, and
  109. stores the required buffer size, in bytes, into the variable pointed
  110. to by pScopeLen.
  111. If pScopeList is NULL, and pScopeLen is non-NULL, the function returns
  112. ERROR_SUCCESS, and stores the size of the data, in bytes, in the variable
  113. pointed to by pScopeLen. This lets an application determine the best
  114. way to allocate a buffer for the scope list.
  115. pScopeCount - Pointer to a variable that will store total number of scopes returned
  116. in the pScopeList buffer.
  117. Return Value:
  118. The status of the operation.
  119. --*/
  120. {
  121. DWORD Error;
  122. // First check the validity of the arguments.
  123. // has startup been called?
  124. if ( !gMadcapClientApplVersion ) {
  125. DhcpPrint((DEBUG_ERRORS, "McastEnumerateScopes - Not ready. Client Version %d\n",
  126. gMadcapClientApplVersion));
  127. return ERROR_NOT_READY;
  128. }
  129. // Correct addr family?
  130. if (AF_INET != AddrFamily) {
  131. DhcpPrint((DEBUG_ERRORS, "McastEnumerateScopes - Invalid AddrFamily IPv%d\n", AddrFamily));
  132. return ERROR_INVALID_PARAMETER;
  133. }
  134. // pScopeLen can not be NULL.
  135. if ( !pScopeLen || IsBadWritePtr( pScopeLen, sizeof(DWORD) ) ) {
  136. DhcpPrint((DEBUG_ERRORS, "McastEnumerateScopes - Invalid ScopeLen param\n"));
  137. return ERROR_INVALID_PARAMETER;
  138. }
  139. // if pScopeList buffer is given, then pScopeCount can not be NULL.
  140. if ( pScopeList &&
  141. (!pScopeCount || IsBadWritePtr( pScopeCount, sizeof(DWORD)) ) ) {
  142. DhcpPrint((DEBUG_ERRORS, "McastEnumerateScopes - Invalid ScopeCount param\n"));
  143. return ERROR_INVALID_PARAMETER;
  144. }
  145. // if we are not requerying the list then pScopList can not be NULL.
  146. if (!ReQuery &&
  147. (!pScopeList || IsBadWritePtr( pScopeList, *pScopeLen ) ) ) {
  148. DhcpPrint((DEBUG_ERRORS, "McastEnumerateScopes - Invalid ScopeList & ReQuery param\n"));
  149. return ERROR_INVALID_PARAMETER;
  150. }
  151. // initialize the status.
  152. Error = STATUS_SUCCESS;
  153. // do we need to requery ?
  154. if ( ReQuery ) {
  155. // query the MCAST servers and get the new list of MScopes.
  156. Error = ObtainMScopeList();
  157. if ( ERROR_SUCCESS != Error ) {
  158. return Error;
  159. }
  160. } else {
  161. if( !gMadcapScopeList ) {
  162. return ERROR_NO_DATA;
  163. }
  164. }
  165. // Has the client specified the buffer?
  166. if ( pScopeList ) {
  167. // yes, copy the scopes.
  168. DhcpPrint((DEBUG_API, "McastEnumerateScopes - Copying existing mscope list\n"));
  169. return CopyMScopeList(
  170. pScopeList,
  171. pScopeLen,
  172. pScopeCount );
  173. } else {
  174. // no, just return the length of the scope list and the scope count.
  175. LOCK_MSCOPE_LIST();
  176. if( gMadcapScopeList != NULL ) {
  177. *pScopeLen = gMadcapScopeList->ScopeLen;
  178. if ( pScopeCount ) *pScopeCount = gMadcapScopeList->ScopeCount;
  179. Error = ERROR_SUCCESS;
  180. } else {
  181. Error = ERROR_NO_DATA;
  182. }
  183. UNLOCK_MSCOPE_LIST();
  184. }
  185. return Error;
  186. }
  187. DWORD
  188. APIENTRY
  189. McastGenUID(
  190. IN LPMCAST_CLIENT_UID pRequestID
  191. )
  192. /*++
  193. Routine Description:
  194. This routine generates the unique identifier which client can use to later pass
  195. to request/renew addresses.
  196. Arguments:
  197. pRequestID - Pointer to the UID struct where the identifier is to be stored. The
  198. buffer that holds the id should be at-least MCAST_CLIENT_ID_LEN long.
  199. Return Value:
  200. The status of the operation.
  201. --*/
  202. {
  203. if (!pRequestID) {
  204. return ERROR_INVALID_PARAMETER;
  205. }
  206. if (!pRequestID->ClientUID || IsBadWritePtr( pRequestID->ClientUID, pRequestID->ClientUIDLength) ) {
  207. return ERROR_INVALID_PARAMETER;
  208. }
  209. return GenMadcapClientUID( pRequestID->ClientUID, &pRequestID->ClientUIDLength );
  210. }
  211. DWORD
  212. APIENTRY
  213. McastRequestAddress(
  214. IN IP_ADDR_FAMILY AddrFamily,
  215. IN LPMCAST_CLIENT_UID pRequestID,
  216. IN PMCAST_SCOPE_CTX pScopeCtx,
  217. IN PMCAST_LEASE_REQUEST pAddrRequest,
  218. IN OUT PMCAST_LEASE_RESPONSE pAddrResponse
  219. )
  220. /*++
  221. Routine Description:
  222. This routine request multicast address(es) from the MCAST server.
  223. Arguments:
  224. AddrFamily - AF_INET for IPv4 and AF_INET6 for IPv6
  225. pRequestID - Unique identifier for this request. Client is responsible for
  226. generating unique identifier for every request. One recommendation
  227. is to use application specific context hashed by time.
  228. pRequestIDLen - Length of the pRequestID buffer.
  229. pScopeCtx - Pointer to the context of the scope from which the address is to
  230. be allocated. Scope context has to be retrieved via McastEnumerateScopes
  231. call before calling this.
  232. pAddrRequest - Pointer to the block containing all the parameters pertaining
  233. to multicast address request. The MCAST_API_VERSION_1 version of
  234. implementation supports allocation of only one address at a time.
  235. So the AddrCount and MinAddrCount value must be 1.ServerAddress
  236. field is ignored.
  237. pAddrResponse - Pointer to the block which contains the response paramters for
  238. the multicast address request. The caller is responsible for allocating
  239. the space for pAddrBuf for the requested number of addresses and
  240. setting the pointer to that space.
  241. Return Value:
  242. The status of the operation.
  243. --*/
  244. {
  245. PDHCP_CONTEXT pContext = NULL;
  246. DWORD Error;
  247. DWORD ScopeId;
  248. time_t TimeNow;
  249. time_t LocalLeaseStartTime;
  250. time_t LocalMaxLeaseStartTime;
  251. // do some param checking.
  252. // has startup been called?
  253. if ( !gMadcapClientApplVersion ) {
  254. DhcpPrint((DEBUG_ERRORS, "McastRequestAddress - Not ready. Client Version %d\n",
  255. gMadcapClientApplVersion));
  256. return ERROR_NOT_READY;
  257. }
  258. if (AF_INET != AddrFamily) {
  259. DhcpPrint((DEBUG_ERRORS, "McastRequestAddress - Invalid AddrFamily IPv%d\n", AddrFamily));
  260. return ERROR_INVALID_PARAMETER;
  261. }
  262. if ( !pRequestID || !pRequestID->ClientUID || !pAddrRequest || !pAddrResponse ) {
  263. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - one of parameter is NULL\n"));
  264. return ERROR_INVALID_PARAMETER;
  265. }
  266. if ( pAddrRequest->AddrCount != 1 || pAddrResponse->AddrCount < pAddrRequest->AddrCount) {
  267. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - currently support one address - requested %ld\n",
  268. pAddrRequest->AddrCount));
  269. return ERROR_INVALID_PARAMETER;
  270. }
  271. if ( pAddrRequest->pAddrBuf &&
  272. (*(DWORD UNALIGNED *)pAddrRequest->pAddrBuf) &&
  273. !CLASSD_NET_ADDR(*(DWORD UNALIGNED *)pAddrRequest->pAddrBuf)) {
  274. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - requested address not valid %s\n",
  275. DhcpIpAddressToDottedString(*(DWORD UNALIGNED *)pAddrRequest->pAddrBuf)));
  276. return ERROR_INVALID_PARAMETER;
  277. }
  278. if ( !pAddrResponse->pAddrBuf ) {
  279. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - response buffer has null pAddrBuf\n"));
  280. return ERROR_INVALID_PARAMETER;
  281. }
  282. if (pRequestID->ClientUIDLength < MCAST_CLIENT_ID_LEN) {
  283. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - requestid length %d too small\n",
  284. pRequestID->ClientUIDLength));
  285. return ERROR_INVALID_PARAMETER;
  286. }
  287. if ( !pScopeCtx ) {
  288. DhcpPrint((DEBUG_ERRORS, "McastRequestAddress - scope context not supplied\n"));
  289. return ERROR_INVALID_PARAMETER;
  290. }
  291. time(&TimeNow);
  292. LocalLeaseStartTime = LocalMaxLeaseStartTime = TimeNow;
  293. if ( pAddrRequest->LeaseStartTime > LocalLeaseStartTime ) {
  294. LocalLeaseStartTime = pAddrRequest->LeaseStartTime;
  295. }
  296. if ( pAddrRequest->MaxLeaseStartTime > LocalMaxLeaseStartTime ) {
  297. LocalMaxLeaseStartTime = pAddrRequest->MaxLeaseStartTime;
  298. }
  299. if ( LocalLeaseStartTime > LocalMaxLeaseStartTime ) {
  300. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - invalid start lease times\n"));
  301. return ERROR_INVALID_PARAMETER;
  302. }
  303. if ( pAddrRequest->LeaseDuration < pAddrRequest->MinLeaseDuration ) {
  304. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - invalid lease duration\n"));
  305. return ERROR_INVALID_PARAMETER;
  306. }
  307. Error = CreateMadcapContext(&pContext, pRequestID, pScopeCtx->Interface.IpAddrV4 );
  308. if ( ERROR_SUCCESS != Error ) goto Cleanup;
  309. APICTXT_ENABLED(pContext); // mark the context as being created by the API
  310. if (pAddrRequest->pAddrBuf && (*(DWORD UNALIGNED *)pAddrRequest->pAddrBuf) ) {
  311. pContext->DesiredIpAddress = *(DWORD UNALIGNED *)pAddrRequest->pAddrBuf;
  312. }
  313. //pContext->DhcpServerAddress = pScopeCtx->ServerID;
  314. Error = ObtainMadcapAddress(
  315. pContext,
  316. &pScopeCtx->ScopeID,
  317. pAddrRequest,
  318. pAddrResponse
  319. );
  320. Cleanup:
  321. if ( pContext )
  322. DhcpDestroyContext( pContext );
  323. return Error;
  324. }
  325. DWORD
  326. APIENTRY
  327. McastRenewAddress(
  328. IN IP_ADDR_FAMILY AddrFamily,
  329. IN LPMCAST_CLIENT_UID pRequestID,
  330. IN PMCAST_LEASE_REQUEST pRenewRequest,
  331. IN OUT PMCAST_LEASE_RESPONSE pRenewResponse
  332. )
  333. /*++
  334. Routine Description:
  335. This routine renews multicast address(es) from the MCAST server.
  336. Arguments:
  337. AddrFamily - AF_INET for IPv4 and AF_INET6 for IPv6
  338. pRequestID - Unique identifier that was used when the address(es) were
  339. obtained initially.
  340. RequestIDLen - Length of the pRequestID buffer.
  341. pRenewRequest - Pointer to the block containing all the parameters pertaining
  342. to the renew request.
  343. pRenewResponse - Pointer to the block which contains the response paramters for
  344. the renew request.The caller is responsible for allocating the
  345. space for pAddrBuf for the requested number of addresses and
  346. setting the pointer to that space.
  347. Return Value:
  348. The status of the operation.
  349. --*/
  350. {
  351. PDHCP_CONTEXT pContext = NULL;
  352. DWORD Error;
  353. DHCP_IP_ADDRESS SelectedServer;
  354. DWORD ScopeId;
  355. time_t TimeNow;
  356. // do some param checking.
  357. // has startup been called?
  358. if ( !gMadcapClientApplVersion ) {
  359. DhcpPrint((DEBUG_ERRORS, "McastRenewAddress - Not ready. Client Version %d\n",
  360. gMadcapClientApplVersion));
  361. return ERROR_NOT_READY;
  362. }
  363. if (AF_INET != AddrFamily) {
  364. DhcpPrint((DEBUG_ERRORS, "McastRenewAddress - Invalid AddrFamily IPv%d\n", AddrFamily));
  365. return ERROR_INVALID_PARAMETER;
  366. }
  367. if ( !pRequestID || !pRenewRequest || !pRenewResponse ) {
  368. DhcpPrint((DEBUG_ERRORS,"McastRenewAddress - one of parameter is NULL\n"));
  369. return ERROR_INVALID_PARAMETER;
  370. }
  371. if ( pRenewRequest->AddrCount != 1 ||
  372. pRenewResponse->AddrCount < pRenewRequest->AddrCount ||
  373. !pRenewResponse->pAddrBuf ||
  374. !pRenewRequest->pAddrBuf ||
  375. !CLASSD_NET_ADDR( *(DWORD UNALIGNED *)pRenewRequest->pAddrBuf) ) {
  376. DhcpPrint((DEBUG_ERRORS,"McastRenewAddress - address %s type V%d count %ld is invalid\n",
  377. DhcpIpAddressToDottedString( *(DWORD UNALIGNED *)pRenewRequest->pAddrBuf),
  378. pRenewRequest->AddrCount ));
  379. return ERROR_INVALID_PARAMETER;
  380. }
  381. if (!pRenewRequest->ServerAddress.IpAddrV4) {
  382. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - server address not specified \n"));
  383. return ERROR_INVALID_PARAMETER;
  384. }
  385. if (pRequestID->ClientUIDLength < MCAST_CLIENT_ID_LEN) {
  386. DhcpPrint((DEBUG_ERRORS,"McastRenewAddress - requestid length too small\n",
  387. pRequestID->ClientUIDLength));
  388. return ERROR_INVALID_PARAMETER;
  389. }
  390. time(&TimeNow);
  391. if ( pRenewRequest->LeaseStartTime > pRenewRequest->MaxLeaseStartTime ||
  392. (pRenewRequest->LeaseDuration < pRenewRequest->MinLeaseDuration)) {
  393. DhcpPrint((DEBUG_ERRORS,"McastRenewAddress - invalid lease times\n"));
  394. return ERROR_INVALID_PARAMETER;
  395. }
  396. Error = CreateMadcapContext(&pContext, pRequestID, INADDR_ANY);
  397. if ( ERROR_SUCCESS != Error) return Error;
  398. APICTXT_ENABLED(pContext); // mark the context as being created by the API
  399. pContext->DesiredIpAddress = *(DWORD UNALIGNED *)pRenewRequest->pAddrBuf;
  400. pContext->DhcpServerAddress = pRenewRequest->ServerAddress.IpAddrV4;
  401. Error = RenewMadcapAddress(
  402. pContext,
  403. NULL,
  404. pRenewRequest,
  405. pRenewResponse,
  406. 0
  407. );
  408. Cleanup:
  409. if ( pContext ) DhcpDestroyContext( pContext );
  410. return Error;
  411. }
  412. DWORD
  413. APIENTRY
  414. McastReleaseAddress(
  415. IN IP_ADDR_FAMILY AddrFamily,
  416. IN LPMCAST_CLIENT_UID pRequestID,
  417. IN PMCAST_LEASE_REQUEST pReleaseRequest
  418. )
  419. /*++
  420. Routine Description:
  421. This routine releases multicast address(es) from the MCAST server.
  422. Arguments:
  423. AddrFamily - AF_INET for IPv4 and AF_INET6 for IPv6
  424. pRequestID - Unique identifier that was used when the address(es) were
  425. obtained initially.
  426. pReleaseRequest - Pointer to the block containing all the parameters pertaining
  427. to the release request.
  428. Return Value:
  429. The status of the operation.
  430. --*/
  431. {
  432. PDHCP_CONTEXT pContext = NULL;
  433. DWORD Error;
  434. DHCP_IP_ADDRESS SelectedServer;
  435. DWORD ScopeId;
  436. // do some param checking.
  437. // has startup been called?
  438. if ( !gMadcapClientApplVersion ) {
  439. DhcpPrint((DEBUG_ERRORS, "McastReleaseAddress - Not ready. Client Version %d\n",
  440. gMadcapClientApplVersion));
  441. return ERROR_NOT_READY;
  442. }
  443. if (AF_INET != AddrFamily) {
  444. DhcpPrint((DEBUG_ERRORS, "McastReleaseAddress - Invalid AddrFamily IPv%d\n", AddrFamily));
  445. return ERROR_INVALID_PARAMETER;
  446. }
  447. if ( !pRequestID || !pReleaseRequest ) {
  448. DhcpPrint((DEBUG_ERRORS,"McastReleaseAddress - one of parameter is NULL\n"));
  449. return ERROR_INVALID_PARAMETER;
  450. }
  451. if ( pReleaseRequest->AddrCount != 1 ||
  452. !pReleaseRequest->pAddrBuf ||
  453. !CLASSD_NET_ADDR( *(DWORD UNALIGNED *)pReleaseRequest->pAddrBuf) ) {
  454. DhcpPrint((DEBUG_ERRORS,"McastReleaseAddress - address %s count %ld is invalid\n",
  455. DhcpIpAddressToDottedString( *(DWORD UNALIGNED *)pReleaseRequest->pAddrBuf), pReleaseRequest->AddrCount ));
  456. return ERROR_INVALID_PARAMETER;
  457. }
  458. if (!pReleaseRequest->ServerAddress.IpAddrV4) {
  459. DhcpPrint((DEBUG_ERRORS,"McastReleaseAddress - server address is invalid\n"));
  460. return ERROR_INVALID_PARAMETER;
  461. }
  462. if (pRequestID->ClientUIDLength < MCAST_CLIENT_ID_LEN) {
  463. DhcpPrint((DEBUG_ERRORS,"McastRequestAddress - requestid length too small\n",
  464. pRequestID->ClientUIDLength));
  465. return ERROR_INVALID_PARAMETER;
  466. }
  467. Error = CreateMadcapContext(&pContext, pRequestID, INADDR_ANY );
  468. if ( ERROR_SUCCESS != Error) return Error;
  469. APICTXT_ENABLED(pContext); // mark the context as being created by the API
  470. pContext->DhcpServerAddress = pReleaseRequest->ServerAddress.IpAddrV4;
  471. Error = ReleaseMadcapAddress(pContext);
  472. Cleanup:
  473. if ( pContext ) DhcpDestroyContext( pContext );
  474. return Error;
  475. }
  476.