Source code of Windows XP (NT5)
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.

1645 lines
38 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. arpcfg.c - Configuration routines
  5. Abstract:
  6. Routines to read in configuration information for the ATMARP client.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 08-09-96 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUMBER 'GFCA'
  15. //
  16. // Size of local temp buffer
  17. //
  18. #define WORK_BUF_SIZE 200
  19. #define ASCII_TO_INT(val) \
  20. ( ( ((val) >= '0') && ('9' >= (val)) ) ? ((val) - '0') : \
  21. ( ((val) >= 'a') && ('z' >= (val)) ) ? ((val) - 'a' + 10) : \
  22. ( ((val) >= 'A') && ('Z' >= (val)) ) ? ((val) - 'A' + 10) : \
  23. 0 )
  24. //
  25. // Parameters for reading in a ULONG from configuration into an Interface
  26. // structure.
  27. //
  28. typedef struct _AA_READ_CONFIG_PARAMS
  29. {
  30. ULONG StructOffset; // Offset of param from beginning of struct
  31. PWCHAR ParameterName; // Name in config database
  32. ULONG DefaultValue;
  33. } AA_READ_CONFIG_PARAMS, *PAA_READ_CONFIG_PARAMS;
  34. #define AA_MAKE_RCP(Off, Name, Dflt) \
  35. { Off, Name, Dflt }
  36. #define LIS_CONFIG_ENTRY(Field, Name, Dflt) \
  37. AA_MAKE_RCP(FIELD_OFFSET(struct _ATMARP_INTERFACE, Field), Name, Dflt)
  38. #define AA_BANDWIDTH_UNSPECIFIED ((ULONG)-1)
  39. #define AA_PACKET_SIZE_UNSPECIFIED ((ULONG)-1)
  40. #define AA_MTU_UNSPECIFIED ((ULONG)-1)
  41. #define AA_SPEED_UNSPECIFIED ((ULONG)-1)
  42. //
  43. // List of ULONG parameters for an LIS
  44. //
  45. AA_READ_CONFIG_PARAMS AtmArpLISConfigTable[] =
  46. {
  47. LIS_CONFIG_ENTRY(SapSelector, L"SapSelector", AA_DEF_SELECTOR_VALUE),
  48. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_UNICAST].MaxHeaderBufs, L"MaxHeaderBufs", AA_DEF_MAX_HEADER_BUFFERS),
  49. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize, L"HeaderBufSize", AA_PKT_LLC_SNAP_HEADER_LENGTH),
  50. #ifdef IPMCAST
  51. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_NUNICAST].MaxHeaderBufs, L"McastMaxHeaderBufs", AA_DEF_MAX_HEADER_BUFFERS),
  52. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize, L"McastHeaderBufSize", sizeof(AA_MC_PKT_TYPE1_SHORT_HEADER)),
  53. #endif // IPMCAST
  54. LIS_CONFIG_ENTRY(ProtocolBufSize, L"ProtocolBufSize", AA_DEF_PROTOCOL_BUFFER_SIZE),
  55. LIS_CONFIG_ENTRY(MaxProtocolBufs, L"MaxProtocolBufs", AA_DEF_MAX_PROTOCOL_BUFFERS),
  56. LIS_CONFIG_ENTRY(MTU, L"MTU", AA_MTU_UNSPECIFIED),
  57. LIS_CONFIG_ENTRY(Speed, L"Speed", AA_SPEED_UNSPECIFIED),
  58. LIS_CONFIG_ENTRY(PVCOnly, L"PVCOnly", AA_DEF_PVC_ONLY_VALUE),
  59. LIS_CONFIG_ENTRY(ServerConnectInterval, L"ServerConnectInterval", AA_DEF_SERVER_CONNECT_INTERVAL),
  60. LIS_CONFIG_ENTRY(ServerRegistrationTimeout, L"ServerRegistrationTimeout", AA_DEF_SERVER_REGISTRATION_TIMEOUT),
  61. LIS_CONFIG_ENTRY(AddressResolutionTimeout, L"AddressResolutionTimeout", AA_DEF_ADDRESS_RESOLUTION_TIMEOUT),
  62. LIS_CONFIG_ENTRY(ARPEntryAgingTimeout, L"ARPEntryAgingTimeout", AA_DEF_ARP_ENTRY_AGING_TIMEOUT),
  63. LIS_CONFIG_ENTRY(InARPWaitTimeout, L"InARPWaitTimeout", AA_DEF_INARP_WAIT_TIMEOUT),
  64. LIS_CONFIG_ENTRY(ServerRefreshTimeout, L"ServerRefreshTimeout", AA_DEF_SERVER_REFRESH_INTERVAL),
  65. LIS_CONFIG_ENTRY(MinWaitAfterNak, L"MinWaitAfterNak", AA_DEF_MIN_WAIT_AFTER_NAK),
  66. LIS_CONFIG_ENTRY(MaxRegistrationAttempts, L"MaxRegistrationAttempts", AA_DEF_MAX_REGISTRATION_ATTEMPTS),
  67. LIS_CONFIG_ENTRY(MaxResolutionAttempts, L"MaxResolutionAttempts", AA_DEF_MAX_RESOLUTION_ATTEMPTS),
  68. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendPeakBandwidth, L"DefaultSendBandwidth", AA_BANDWIDTH_UNSPECIFIED),
  69. LIS_CONFIG_ENTRY(DefaultFlowSpec.ReceivePeakBandwidth, L"DefaultReceiveBandwidth", AA_BANDWIDTH_UNSPECIFIED),
  70. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendMaxSize, L"DefaultSendMaxSize", AA_PACKET_SIZE_UNSPECIFIED),
  71. LIS_CONFIG_ENTRY(DefaultFlowSpec.ReceiveMaxSize, L"DefaultReceiveMaxSize", AA_PACKET_SIZE_UNSPECIFIED),
  72. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendServiceType, L"DefaultServiceType", AA_DEF_FLOWSPEC_SERVICETYPE),
  73. LIS_CONFIG_ENTRY(DefaultFlowSpec.AgingTime, L"DefaultVCAgingTimeout", AA_DEF_VC_AGING_TIMEOUT)
  74. #ifdef IPMCAST
  75. ,
  76. LIS_CONFIG_ENTRY(MARSConnectInterval, L"MARSConnectInterval", AA_DEF_SERVER_CONNECT_INTERVAL),
  77. LIS_CONFIG_ENTRY(MARSRegistrationTimeout, L"MARSRegistrationTimeout", AA_DEF_SERVER_REGISTRATION_TIMEOUT),
  78. LIS_CONFIG_ENTRY(MARSKeepAliveTimeout, L"MARSKeepAliveTimeout", AA_DEF_MARS_KEEPALIVE_TIMEOUT),
  79. LIS_CONFIG_ENTRY(JoinTimeout, L"JoinTimeout", AA_DEF_MARS_JOIN_TIMEOUT),
  80. LIS_CONFIG_ENTRY(LeaveTimeout, L"LeaveTimeout", AA_DEF_MARS_LEAVE_TIMEOUT),
  81. LIS_CONFIG_ENTRY(MaxDelayBetweenMULTIs, L"MaxDelayBetweenMULTIs", AA_DEF_MULTI_TIMEOUT),
  82. LIS_CONFIG_ENTRY(MulticastEntryAgingTimeout, L"MulticastEntryAgingTimeout", AA_DEF_MCAST_IP_ENTRY_AGING_TIMEOUT),
  83. LIS_CONFIG_ENTRY(MinRevalidationDelay, L"MinMulticastRevalidationDelay", AA_DEF_MIN_MCAST_REVALIDATION_DELAY),
  84. LIS_CONFIG_ENTRY(MaxRevalidationDelay, L"MaxMulticastRevalidationDelay", AA_DEF_MAX_MCAST_REVALIDATION_DELAY),
  85. LIS_CONFIG_ENTRY(MinPartyRetryDelay, L"MinMulticastPartyRetryDelay", AA_DEF_MIN_MCAST_PARTY_RETRY_DELAY),
  86. LIS_CONFIG_ENTRY(MaxPartyRetryDelay, L"MaxMulticastPartyRetryDelay", AA_DEF_MAX_MCAST_PARTY_RETRY_DELAY),
  87. LIS_CONFIG_ENTRY(MaxJoinOrLeaveAttempts, L"MaxJoinLeaveAttempts", AA_DEF_MAX_JOIN_LEAVE_ATTEMPTS)
  88. #endif // IPMCAST
  89. };
  90. //
  91. // Size of above table.
  92. //
  93. #define LIS_CONFIG_ENTRIES \
  94. sizeof(AtmArpLISConfigTable)/sizeof(AA_READ_CONFIG_PARAMS)
  95. //
  96. // Names of LIS parameters and subkey names that don't appear
  97. // in the above table.
  98. //
  99. #define AA_LIS_IP_CONFIG_STRING L"IPConfig"
  100. #define AA_LIS_ATMARP_SERVER_LIST_KEY L"ARPServerList"
  101. #define AA_LIS_MARS_SERVER_LIST_KEY L"MARServerList"
  102. #define AA_LIS_ATMARP_SERVER_ADDRESS L"AtmAddress"
  103. #define AA_LIS_ATMARP_SERVER_SUBADDRESS L"AtmSubaddress"
  104. #define AA_LIS_STATIC_ARP_LIST L"StaticArpList"
  105. #ifdef DHCP_OVER_ATM
  106. #define AA_LIS_DHCP_SERVER_ATM_ADDRESS L"DhcpServerAtmAddress"
  107. #endif // DHCP_OVER_ATM
  108. #ifdef QOS_HEURISTICS
  109. #define AA_LIS_FLOW_INFO_KEY L"FlowInfo"
  110. #define AA_LIS_FLOW_INFO_ENABLED L"FlowInfoEnabled"
  111. #define FLOW_CONFIG_ENTRY(Field, Name, Dflt) \
  112. AA_MAKE_RCP(FIELD_OFFSET(struct _ATMARP_FLOW_INFO, Field), Name, Dflt)
  113. AA_READ_CONFIG_PARAMS AtmArpFlowConfigTable[] =
  114. {
  115. FLOW_CONFIG_ENTRY(PacketSizeLimit, L"PacketSizeLimit", AAF_DEF_LOWBW_SEND_THRESHOLD),
  116. FLOW_CONFIG_ENTRY(FlowSpec.SendPeakBandwidth, L"SendBandwidth", AAF_DEF_LOWBW_SEND_BANDWIDTH),
  117. FLOW_CONFIG_ENTRY(FlowSpec.ReceivePeakBandwidth, L"ReceiveBandwidth", AAF_DEF_LOWBW_RECV_BANDWIDTH),
  118. FLOW_CONFIG_ENTRY(FlowSpec.SendServiceType, L"ServiceType", AAF_DEF_LOWBW_SERVICETYPE),
  119. FLOW_CONFIG_ENTRY(FlowSpec.Encapsulation, L"Encapsulation", AAF_DEF_LOWBW_ENCAPSULATION),
  120. FLOW_CONFIG_ENTRY(FlowSpec.AgingTime, L"AgingTime", AAF_DEF_LOWBW_AGING_TIME),
  121. };
  122. #define AA_FLOW_INFO_ENTRIES \
  123. (sizeof(AtmArpFlowConfigTable)/sizeof(AA_READ_CONFIG_PARAMS))
  124. #endif // QOS_HEURISTICS
  125. EXTERN
  126. NDIS_STATUS
  127. AtmArpCfgReadAdapterConfiguration(
  128. IN PATMARP_ADAPTER pAdapter
  129. )
  130. /*++
  131. Routine Description:
  132. Reads the following adapter configuration information from the
  133. registry:
  134. * pAdapter->ConfigString (MultiSz list of LISs for this adapter).
  135. Arguments:
  136. pAdapter - Points to our adapter structure.
  137. Return Value:
  138. NDIS Status code
  139. --*/
  140. {
  141. NDIS_HANDLE ConfigHandle;
  142. NDIS_STATUS Status;
  143. PNDIS_STRING pConfigString = &pAdapter->ConfigString;
  144. NdisOpenProtocolConfiguration(
  145. &Status,
  146. &ConfigHandle,
  147. pConfigString
  148. );
  149. if (Status != NDIS_STATUS_SUCCESS)
  150. {
  151. ConfigHandle = NULL;
  152. }
  153. else
  154. {
  155. //
  156. // Read in the IPConfig string. If this is not present,
  157. // fail this call.
  158. //
  159. NDIS_STRING IPConfigName = NDIS_STRING_CONST("IPConfig");
  160. PNDIS_CONFIGURATION_PARAMETER pParam;
  161. NdisReadConfiguration(
  162. &Status,
  163. &pParam,
  164. ConfigHandle,
  165. &IPConfigName,
  166. NdisParameterMultiString
  167. );
  168. if ((Status == NDIS_STATUS_SUCCESS) &&
  169. (pParam->ParameterType == NdisParameterMultiString))
  170. {
  171. NDIS_STRING *pSrcString = &(pParam->ParameterData.StringData);
  172. NDIS_STRING *pDestString = &(pAdapter->IPConfigString);
  173. PWSTR Buffer = NULL;
  174. AA_ALLOC_MEM(Buffer, WCHAR, pSrcString->Length*sizeof(*Buffer));
  175. if (Buffer == NULL)
  176. {
  177. Status = NDIS_STATUS_RESOURCES;
  178. }
  179. else
  180. {
  181. AA_COPY_MEM(
  182. Buffer,
  183. pSrcString->Buffer,
  184. pSrcString->Length
  185. );
  186. pDestString->Buffer = Buffer;
  187. pDestString->Length = pSrcString->Length;
  188. pDestString->MaximumLength = pSrcString->Length;
  189. }
  190. }
  191. else
  192. {
  193. Status = NDIS_STATUS_FAILURE;
  194. }
  195. }
  196. if (ConfigHandle != NULL)
  197. {
  198. NdisCloseConfiguration(ConfigHandle);
  199. ConfigHandle = NULL;
  200. }
  201. AADEBUGP(AAD_VERY_LOUD,
  202. ("OpenAdapterConfig: pAdapter 0x%x, Status 0x%x\n",
  203. pAdapter, Status));
  204. return Status;
  205. }
  206. NDIS_HANDLE
  207. AtmArpCfgOpenLISConfiguration(
  208. IN PATMARP_ADAPTER pAdapter,
  209. IN UINT LISNumber
  210. #ifdef NEWARP
  211. ,
  212. OUT PNDIS_STRING pIPConfigString
  213. #endif // NEWARP
  214. )
  215. /*++
  216. Routine Description:
  217. Open and return a handle to the configuration section for the
  218. given LIS.
  219. Arguments:
  220. pAdapter - Points to our adapter context.
  221. LISNumber - The zero-based index for the LIS.
  222. pIPConfigString - Place where we return the IP Configuration
  223. string for this interface.
  224. Return Value:
  225. A valid handle if successful, NULL otherwise.
  226. --*/
  227. {
  228. NDIS_HANDLE AdapterConfigHandle;
  229. NDIS_HANDLE SubkeyHandle;
  230. NDIS_STATUS Status;
  231. NDIS_STRING KeyName;
  232. #if DBG
  233. SubkeyHandle = NULL;
  234. #endif // DBG
  235. do
  236. {
  237. NDIS_STRING String;
  238. PWSTR p;
  239. NDIS_HANDLE InterfaceConfigHandle;
  240. NDIS_STRING OurSectionName = ATMARP_NAME_STRING;
  241. ULONG i;
  242. //
  243. // Get the config string for the specified LIS.
  244. //
  245. for (i = 0, p = pAdapter->IPConfigString.Buffer;
  246. (*p != L'\0') && (i < LISNumber);
  247. i++)
  248. {
  249. NdisInitUnicodeString(&String, p);
  250. p = (PWSTR)((PUCHAR)p + String.Length + sizeof(WCHAR));
  251. }
  252. if (*p == L'\0')
  253. {
  254. Status = NDIS_STATUS_FAILURE;
  255. break;
  256. }
  257. NdisInitUnicodeString(pIPConfigString, p);
  258. NdisOpenProtocolConfiguration(
  259. &Status,
  260. &InterfaceConfigHandle,
  261. pIPConfigString
  262. );
  263. if (Status != NDIS_STATUS_SUCCESS)
  264. {
  265. break;
  266. }
  267. //
  268. // Get to our configuration section for this interface.
  269. //
  270. NdisOpenConfigurationKeyByName(
  271. &Status,
  272. InterfaceConfigHandle,
  273. &OurSectionName,
  274. &SubkeyHandle
  275. );
  276. //
  277. // We don't need the main Interface section open anymore.
  278. //
  279. NdisCloseConfiguration(InterfaceConfigHandle);
  280. break;
  281. }
  282. while (FALSE);
  283. AADEBUGP(AAD_VERY_LOUD,
  284. ("OpenLISConfiguration: LIS %d, Status 0x%x, subkey 0x%x\n",
  285. LISNumber, Status, SubkeyHandle));
  286. if (Status == NDIS_STATUS_SUCCESS)
  287. {
  288. return (SubkeyHandle);
  289. }
  290. else
  291. {
  292. return (NULL);
  293. }
  294. }
  295. NDIS_HANDLE
  296. AtmArpCfgOpenLISConfigurationByName(
  297. IN PATMARP_ADAPTER pAdapter,
  298. IN PNDIS_STRING pIPConfigString
  299. )
  300. /*++
  301. Routine Description:
  302. Open and return a handle to the configuration section for the
  303. given LIS. Same functionality as AtmArpCfgOpenLISConfiguration, except
  304. that we look up the adapter based on the config string.
  305. Arguments:
  306. pAdapter - Points to our adapter context.
  307. pIPConfigString - Specifies the configuration registry
  308. key name.
  309. Return Value:
  310. A valid handle if successful, NULL otherwise.
  311. --*/
  312. {
  313. NDIS_HANDLE AdapterConfigHandle;
  314. NDIS_HANDLE SubkeyHandle;
  315. NDIS_STATUS Status;
  316. NDIS_STRING KeyName;
  317. #if DBG
  318. SubkeyHandle = NULL;
  319. #endif // DBG
  320. do
  321. {
  322. NDIS_HANDLE InterfaceConfigHandle;
  323. NDIS_STRING OurSectionName = ATMARP_NAME_STRING;
  324. NdisOpenProtocolConfiguration(
  325. &Status,
  326. &InterfaceConfigHandle,
  327. pIPConfigString
  328. );
  329. if (Status != NDIS_STATUS_SUCCESS)
  330. {
  331. break;
  332. }
  333. //
  334. // Get to our configuration section for this interface.
  335. //
  336. NdisOpenConfigurationKeyByName(
  337. &Status,
  338. InterfaceConfigHandle,
  339. &OurSectionName,
  340. &SubkeyHandle
  341. );
  342. //
  343. // We don't need the main Interface section open anymore.
  344. //
  345. NdisCloseConfiguration(InterfaceConfigHandle);
  346. break;
  347. }
  348. while (FALSE);
  349. AADEBUGP(AAD_VERY_LOUD,
  350. ("OpenLISConfigurationByName: Status 0x%x, subkey 0x%x\n",
  351. Status, SubkeyHandle));
  352. if (Status == NDIS_STATUS_SUCCESS)
  353. {
  354. return (SubkeyHandle);
  355. }
  356. else
  357. {
  358. return (NULL);
  359. }
  360. }
  361. VOID
  362. AtmArpCfgCloseLISConfiguration(
  363. NDIS_HANDLE LISConfigHandle
  364. )
  365. /*++
  366. Routine Description:
  367. Close a configuration handle for an LIS.
  368. Arguments:
  369. LISConfigHandle - Handle to the LIS configuration section.
  370. Return Value:
  371. None
  372. --*/
  373. {
  374. NdisCloseConfiguration(LISConfigHandle);
  375. }
  376. NDIS_STATUS
  377. AtmArpCfgReadLISConfiguration(
  378. IN NDIS_HANDLE LISConfigHandle,
  379. IN PATMARP_INTERFACE pInterface
  380. )
  381. /*++
  382. Routine Description:
  383. Get all configuration parameters for the specified LIS. We first
  384. fill in all configurable parameters with default values, and then
  385. overwrite them with values from the configuration database.
  386. Arguments:
  387. LISComfigHandle - the handle returned by AtmArpOpenLISConfiguration
  388. pInterface - the ATMARP Interface structure for this LIS.
  389. Return Value:
  390. NDIS_STATUS_SUCCESS if we were able to read in all config info.
  391. NDIS_STATUS_RESOURCES if we came across an allocation failure.
  392. NDIS_STATUS_FAILURE for any other kind of error.
  393. --*/
  394. {
  395. NDIS_STATUS Status;
  396. PAA_READ_CONFIG_PARAMS pParamEntry;
  397. ULONG i;
  398. PATM_SAP pAtmSap;
  399. PATM_ADDRESS pAtmAddress; // SAP address
  400. NDIS_STRING ParameterName;
  401. PNDIS_CONFIGURATION_PARAMETER pNdisConfigurationParameter;
  402. do
  403. {
  404. //
  405. // Read in all the ULONGs first.
  406. //
  407. pParamEntry = AtmArpLISConfigTable;
  408. for (i = 0; i < LIS_CONFIG_ENTRIES; i++)
  409. {
  410. NdisInitUnicodeString(
  411. &ParameterName,
  412. pParamEntry->ParameterName
  413. );
  414. NdisReadConfiguration(
  415. &Status,
  416. &pNdisConfigurationParameter,
  417. LISConfigHandle,
  418. &ParameterName,
  419. NdisParameterInteger
  420. );
  421. if (Status != NDIS_STATUS_SUCCESS)
  422. {
  423. //
  424. // Error in accessing this parameter -- use the default.
  425. //
  426. *(ULONG *)((PUCHAR)pInterface + pParamEntry->StructOffset) =
  427. pParamEntry->DefaultValue;
  428. }
  429. else
  430. {
  431. *(ULONG *)((PUCHAR)pInterface + pParamEntry->StructOffset) =
  432. pNdisConfigurationParameter->ParameterData.IntegerData;
  433. }
  434. pParamEntry++;
  435. }
  436. //
  437. // Postprocessing. Sanity checks on some values.
  438. // Round up some sizes to make them multiples of 4.
  439. //
  440. pInterface->ProtocolBufSize = ROUND_TO_8_BYTES(pInterface->ProtocolBufSize);
  441. pInterface->HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize = ROUND_UP(pInterface->HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize);
  442. #ifdef IPMCAST
  443. pInterface->HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize = ROUND_UP(pInterface->HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize);
  444. #endif // IPMCAST
  445. //
  446. // More postprocessing: use the SAP Selector value to set up our
  447. // "basic" listening SAP.
  448. //
  449. pInterface->SapList.pInterface = pInterface;
  450. pInterface->SapList.Flags = AA_SAP_REG_STATE_IDLE;
  451. pInterface->SapList.pInfo->SapType = SAP_TYPE_NSAP;
  452. pInterface->SapList.pInfo->SapLength = sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  453. pAtmSap = (PATM_SAP)(pInterface->SapList.pInfo->Sap);
  454. AA_COPY_MEM((PUCHAR)&(pAtmSap->Blli), &AtmArpDefaultBlli, sizeof(ATM_BLLI_IE));
  455. AA_COPY_MEM((PUCHAR)&(pAtmSap->Bhli), &AtmArpDefaultBhli, sizeof(ATM_BHLI_IE));
  456. pAtmSap->NumberOfAddresses = 1;
  457. pAtmAddress = (PATM_ADDRESS)pAtmSap->Addresses;
  458. pAtmAddress->AddressType = SAP_FIELD_ANY_AESA_REST;
  459. pAtmAddress->NumberOfDigits = ATM_ADDRESS_LENGTH;
  460. pAtmAddress->Address[ATM_ADDRESS_LENGTH-1] = (UCHAR)(pInterface->SapSelector);
  461. pInterface->NumberOfSaps = 1;
  462. //
  463. // If the MTU wasn't specified, get it from the adapter.
  464. //
  465. if (pInterface->MTU == AA_MTU_UNSPECIFIED)
  466. {
  467. pInterface->MTU = pInterface->pAdapter->MaxPacketSize - AA_PKT_LLC_SNAP_HEADER_LENGTH;
  468. }
  469. else
  470. {
  471. //
  472. // If the MTU value isn't within bounds, default to 9180 bytes.
  473. //
  474. if ((pInterface->MTU < 9180) || (pInterface->MTU > 65535 - 8))
  475. {
  476. pInterface->MTU = 9180;
  477. }
  478. }
  479. //
  480. // If the I/F speed wasn't specified, get it from the adapter.
  481. //
  482. if (pInterface->Speed == AA_SPEED_UNSPECIFIED)
  483. {
  484. //
  485. // Convert from bytes/sec to bits/sec
  486. //
  487. pInterface->Speed = (pInterface->pAdapter->LineRate.Outbound * 8);
  488. }
  489. //
  490. // Set up default flow parameters, if not specified, from the values
  491. // we got from the adapter.
  492. //
  493. if (pInterface->DefaultFlowSpec.SendPeakBandwidth == AA_BANDWIDTH_UNSPECIFIED)
  494. {
  495. pInterface->DefaultFlowSpec.SendPeakBandwidth = pInterface->pAdapter->LineRate.Outbound;
  496. pInterface->DefaultFlowSpec.SendAvgBandwidth = pInterface->pAdapter->LineRate.Outbound;
  497. }
  498. if (pInterface->DefaultFlowSpec.ReceivePeakBandwidth == AA_BANDWIDTH_UNSPECIFIED)
  499. {
  500. pInterface->DefaultFlowSpec.ReceivePeakBandwidth = pInterface->pAdapter->LineRate.Inbound;
  501. pInterface->DefaultFlowSpec.ReceiveAvgBandwidth = pInterface->pAdapter->LineRate.Inbound;
  502. }
  503. if (pInterface->DefaultFlowSpec.SendMaxSize == AA_PACKET_SIZE_UNSPECIFIED)
  504. {
  505. pInterface->DefaultFlowSpec.SendMaxSize = pInterface->MTU + AA_PKT_LLC_SNAP_HEADER_LENGTH;
  506. }
  507. if (pInterface->DefaultFlowSpec.ReceiveMaxSize == AA_PACKET_SIZE_UNSPECIFIED)
  508. {
  509. pInterface->DefaultFlowSpec.ReceiveMaxSize = pInterface->MTU + AA_PKT_LLC_SNAP_HEADER_LENGTH;
  510. }
  511. pInterface->DefaultFlowSpec.Encapsulation = AA_DEF_FLOWSPEC_ENCAPSULATION;
  512. pInterface->DefaultFlowSpec.SendServiceType =
  513. pInterface->DefaultFlowSpec.ReceiveServiceType = SERVICETYPE_BESTEFFORT;
  514. #ifndef NEWARP
  515. //
  516. // Get IP's ConfigName string for this interface.
  517. //
  518. NdisInitUnicodeString(&ParameterName, AA_LIS_IP_CONFIG_STRING);
  519. NdisReadConfiguration(
  520. &Status,
  521. &pNdisConfigurationParameter,
  522. LISConfigHandle,
  523. &ParameterName,
  524. NdisParameterString
  525. );
  526. if (Status != NDIS_STATUS_SUCCESS)
  527. {
  528. AADEBUGP(AAD_ERROR,
  529. ("Failed to read IP Config string, status 0x%x\n", Status));
  530. break;
  531. }
  532. //
  533. // Copy the string into our IF structure.
  534. //
  535. pInterface->IPConfigString.Length =
  536. pNdisConfigurationParameter->ParameterData.StringData.Length;
  537. AA_COPY_MEM(
  538. pInterface->IPConfigString.Buffer,
  539. pNdisConfigurationParameter->ParameterData.StringData.Buffer,
  540. pInterface->IPConfigString.Length);
  541. #endif // !NEWARP
  542. //
  543. // Get the list of ARP servers: go to the subkey containing the
  544. // list.
  545. //
  546. if (!pInterface->PVCOnly)
  547. {
  548. AtmArpCfgReadAtmAddressList(
  549. &(pInterface->ArpServerList),
  550. AA_LIS_ATMARP_SERVER_LIST_KEY,
  551. LISConfigHandle
  552. );
  553. if (pInterface->ArpServerList.ListSize == 0)
  554. {
  555. //
  556. // Assume PVC only environment.
  557. //
  558. pInterface->PVCOnly = TRUE;
  559. AADEBUGP(AAD_INFO, ("IF 0x%x set to PVC Only\n", pInterface));
  560. }
  561. #ifdef IPMCAST
  562. if (!pInterface->PVCOnly)
  563. {
  564. AtmArpCfgReadAtmAddressList(
  565. &(pInterface->MARSList),
  566. AA_LIS_MARS_SERVER_LIST_KEY,
  567. LISConfigHandle
  568. );
  569. }
  570. #endif // IPMCAST
  571. }
  572. //
  573. // Get any additional SAPs we are configured with. It doesn't matter
  574. // if none are configured.
  575. //
  576. (VOID) AtmArpCfgReadSAPList(
  577. pInterface,
  578. LISConfigHandle
  579. );
  580. #ifdef DHCP_OVER_ATM
  581. //
  582. // Get the ATM Address of the DHCP Server, if configured.
  583. //
  584. Status = AtmArpCfgReadAtmAddress(
  585. LISConfigHandle,
  586. &(pInterface->DhcpServerAddress),
  587. AA_LIS_DHCP_SERVER_ATM_ADDRESS
  588. );
  589. if (Status == NDIS_STATUS_SUCCESS)
  590. {
  591. pInterface->DhcpEnabled = TRUE;
  592. }
  593. #endif // DHCP_OVER_ATM
  594. #ifdef QOS_HEURISTICS
  595. //
  596. // Read in QOS Heuristics, if present.
  597. //
  598. Status = AtmArpCfgReadQosHeuristics(
  599. LISConfigHandle,
  600. pInterface
  601. );
  602. #endif // QOS_HEURISTICS
  603. //
  604. // Read in static IP-ATM entries, if present.
  605. //
  606. AtmArpCfgReadStaticArpEntries(
  607. LISConfigHandle,
  608. pInterface
  609. );
  610. Status = NDIS_STATUS_SUCCESS;
  611. break;
  612. }
  613. while (FALSE);
  614. return (Status);
  615. }
  616. VOID
  617. AtmArpCfgReadAtmAddressList(
  618. IN OUT PATMARP_SERVER_LIST pServerList,
  619. IN PWCHAR pListKeyName,
  620. IN NDIS_HANDLE LISConfigHandle
  621. )
  622. /*++
  623. Routine Description:
  624. Read in a Server list for an LIS from the configuration database.
  625. Notes:
  626. In the first implementation, we had subkeys for everything. The
  627. layout was:
  628. ARPServerList\Server1\AtmAddress - REG_SZ
  629. ARPServerList\Server2\AtmAddress - REG_SZ
  630. and so on.
  631. To simplify, we are changing this to:
  632. ARPServerList - REG_MULTI_SZ, containing multiple
  633. ATM Address strings.
  634. Arguments:
  635. pServerList - The list to be read into.
  636. pListKeyName - Name of key under which the list is present.
  637. LISConfigHandle - Handle to LIS configuration key.
  638. Return Value:
  639. None.
  640. SIDE EFFECT: *pServerList is updated.
  641. --*/
  642. {
  643. NDIS_HANDLE SubkeyHandle; // Handle for Server list subkey
  644. NDIS_HANDLE ServerEntryKeyHandle;
  645. NDIS_STATUS Status;
  646. PATMARP_SERVER_ENTRY pServerEntry;
  647. PATMARP_SERVER_ENTRY * ppNext; // Used for linking entries.
  648. NDIS_STRING SubkeyName;
  649. INT ReadCount;
  650. //
  651. // Try the simplified (see Routine Description above) way first.
  652. // Just open the given key name as a REG_MULTI_SZ.
  653. //
  654. do
  655. {
  656. PNDIS_CONFIGURATION_PARAMETER pParam;
  657. NDIS_STRING AddressListName;
  658. NDIS_STRING AddressString;
  659. PWSTR p;
  660. INT i;
  661. ReadCount = 0; // How many did we read here?
  662. //
  663. // Read all server addresses configured. Stop only when there are
  664. // no more addresses, or we have a resource failure.
  665. //
  666. // First, go to the end of the existing list.
  667. //
  668. ppNext = &(pServerList->pList);
  669. while (*ppNext != NULL_PATMARP_SERVER_ENTRY)
  670. {
  671. ppNext = &((*ppNext)->pNext);
  672. }
  673. NdisInitUnicodeString(&AddressListName, pListKeyName);
  674. NdisReadConfiguration(
  675. &Status,
  676. &pParam,
  677. LISConfigHandle,
  678. &AddressListName,
  679. NdisParameterMultiString
  680. );
  681. if ((Status != NDIS_STATUS_SUCCESS) ||
  682. (pParam->ParameterType != NdisParameterMultiString))
  683. {
  684. Status = NDIS_STATUS_FAILURE;
  685. break;
  686. }
  687. //
  688. // Go through the MULTI-string, each of which should be
  689. // an ATM address. Allocate a server entry for each and
  690. // link it to the list of servers.
  691. //
  692. for (p = pParam->ParameterData.StringData.Buffer, i = 0;
  693. *p != L'\0';
  694. i++)
  695. {
  696. NdisInitUnicodeString(&AddressString, p);
  697. p = (PWSTR)((PUCHAR)p + AddressString.Length + sizeof(WCHAR));
  698. AA_ALLOC_MEM(pServerEntry, ATMARP_SERVER_ENTRY, sizeof(ATMARP_SERVER_ENTRY));
  699. if (pServerEntry == NULL_PATMARP_SERVER_ENTRY)
  700. {
  701. Status = NDIS_STATUS_RESOURCES;
  702. break;
  703. }
  704. AA_SET_MEM(pServerEntry, 0, sizeof(ATMARP_SERVER_ENTRY));
  705. NdisConvertStringToAtmAddress(
  706. &Status,
  707. &AddressString,
  708. &pServerEntry->ATMAddress
  709. );
  710. if (Status == NDIS_STATUS_SUCCESS)
  711. {
  712. //
  713. // Link this entry to the list of ARP Server entries.
  714. //
  715. *ppNext = pServerEntry;
  716. ppNext = &(pServerEntry->pNext);
  717. pServerList->ListSize++;
  718. ReadCount++;
  719. }
  720. else
  721. {
  722. AA_FREE_MEM(pServerEntry);
  723. }
  724. }
  725. //
  726. // Fix up the status so we know what to do next.
  727. //
  728. if (ReadCount != 0)
  729. {
  730. //
  731. // Successfully read in atleast one.
  732. //
  733. Status = NDIS_STATUS_SUCCESS;
  734. }
  735. else
  736. {
  737. Status = NDIS_STATUS_FAILURE;
  738. }
  739. break;
  740. }
  741. while (FALSE);
  742. if (ReadCount != 0)
  743. {
  744. return;
  745. }
  746. //
  747. // For backward compatibility, try the older method.
  748. //
  749. do
  750. {
  751. NdisInitUnicodeString(&SubkeyName, pListKeyName);
  752. NdisOpenConfigurationKeyByName(
  753. &Status,
  754. LISConfigHandle,
  755. &SubkeyName,
  756. &SubkeyHandle
  757. );
  758. if (Status != NDIS_STATUS_SUCCESS)
  759. {
  760. break;
  761. }
  762. //
  763. // Read all server addresses configured. Stop only when there are
  764. // no more addresses, or we have a resource failure.
  765. //
  766. // First, go to the end of the existing list.
  767. //
  768. ppNext = &(pServerList->pList);
  769. while (*ppNext != NULL_PATMARP_SERVER_ENTRY)
  770. {
  771. ppNext = &((*ppNext)->pNext);
  772. }
  773. for (;;)
  774. {
  775. NdisOpenConfigurationKeyByIndex(
  776. &Status,
  777. SubkeyHandle,
  778. pServerList->ListSize,
  779. &SubkeyName,
  780. &ServerEntryKeyHandle
  781. );
  782. if (Status != NDIS_STATUS_SUCCESS)
  783. {
  784. break;
  785. }
  786. AA_ALLOC_MEM(pServerEntry, ATMARP_SERVER_ENTRY, sizeof(ATMARP_SERVER_ENTRY));
  787. if (pServerEntry == NULL_PATMARP_SERVER_ENTRY)
  788. {
  789. NdisCloseConfiguration(ServerEntryKeyHandle);
  790. Status = NDIS_STATUS_RESOURCES;
  791. break;
  792. }
  793. AA_SET_MEM(pServerEntry, 0, sizeof(ATMARP_SERVER_ENTRY));
  794. Status = AtmArpCfgReadAtmAddress(
  795. ServerEntryKeyHandle,
  796. &(pServerEntry->ATMAddress),
  797. AA_LIS_ATMARP_SERVER_ADDRESS
  798. );
  799. if (Status != NDIS_STATUS_SUCCESS)
  800. {
  801. AADEBUGP(AAD_ERROR,
  802. ("ReadAtmAddressList: bad status 0x%x reading server entry %d\n",
  803. Status,
  804. pServerList->ListSize));
  805. NdisCloseConfiguration(ServerEntryKeyHandle);
  806. AA_FREE_MEM(pServerEntry);
  807. Status = NDIS_STATUS_FAILURE;
  808. break;
  809. }
  810. Status = AtmArpCfgReadAtmAddress(
  811. ServerEntryKeyHandle,
  812. &(pServerEntry->ATMSubaddress),
  813. AA_LIS_ATMARP_SERVER_SUBADDRESS
  814. );
  815. if (Status != NDIS_STATUS_SUCCESS)
  816. {
  817. AADEBUGP(AAD_ERROR,
  818. ("ReadAtmAddressList: bad status 0x%x reading server entry %d\n",
  819. Status,
  820. pServerList->ListSize));
  821. NdisCloseConfiguration(ServerEntryKeyHandle);
  822. AA_FREE_MEM(pServerEntry);
  823. Status = NDIS_STATUS_FAILURE;
  824. break;
  825. }
  826. //
  827. // Link this entry to the list of ARP Server entries.
  828. //
  829. *ppNext = pServerEntry;
  830. ppNext = &(pServerEntry->pNext);
  831. pServerList->ListSize++;
  832. NdisCloseConfiguration(ServerEntryKeyHandle);
  833. }
  834. NdisCloseConfiguration(SubkeyHandle);
  835. break;
  836. }
  837. while (FALSE);
  838. return;
  839. }
  840. NDIS_STATUS
  841. AtmArpCfgReadSAPList(
  842. IN PATMARP_INTERFACE pInterface,
  843. IN NDIS_HANDLE LISConfigHandle
  844. )
  845. /*++
  846. Routine Description:
  847. Read in any additional SAPs we are configured to listen on. These are
  848. used to support additional services over the IP/ATM client, that may be
  849. accessible via SAP information that is different from the "basic" SAP
  850. we register on an interface. For example, "well-known" address.
  851. Arguments:
  852. pInterface - Pointer to ATMARP Interface structure for this LIS
  853. LISConfigHandle - Handle to LIS configuration key.
  854. Return Value:
  855. For now, NDIS_STATUS_SUCCESS always.
  856. --*/
  857. {
  858. NDIS_STATUS Status;
  859. Status = NDIS_STATUS_SUCCESS;
  860. // TBD -- code AtmArpCfgReadSAPList
  861. return (Status);
  862. }
  863. //
  864. // Special characters in ATM address string stored in config database.
  865. //
  866. #define BLANK_CHAR L' '
  867. #define PUNCTUATION_CHAR L'.'
  868. #define E164_START_CHAR L'+'
  869. NDIS_STATUS
  870. AtmArpCfgReadAtmAddress(
  871. IN NDIS_HANDLE ConfigHandle,
  872. IN PATM_ADDRESS pAtmAddress,
  873. IN PWCHAR pValueName
  874. )
  875. /*++
  876. Routine Description:
  877. Read in an ATM Address from the configuration database.
  878. Arguments:
  879. ConfigHandle - Handle returned by NdisOpenProtoXXX
  880. pAtmAddress - where to read in the ATM address
  881. pValueName - Pointer to name of value key.
  882. Return Value:
  883. NDIS_STATUS_SUCCESS if the value was read in successfully
  884. NDIS_STATUS_FILE_NOT_FOUND if the value was not found
  885. NDIS_STATUS_FAILURE on any other kind of failure
  886. --*/
  887. {
  888. NDIS_STRING ParameterName;
  889. PNDIS_CONFIGURATION_PARAMETER pNdisConfigurationParameter;
  890. NDIS_STATUS Status;
  891. NdisInitUnicodeString(&ParameterName, pValueName);
  892. NdisReadConfiguration(
  893. &Status,
  894. &pNdisConfigurationParameter,
  895. ConfigHandle,
  896. &ParameterName,
  897. NdisParameterString
  898. );
  899. if (Status == NDIS_STATUS_SUCCESS)
  900. {
  901. NdisConvertStringToAtmAddress(
  902. &Status,
  903. &(pNdisConfigurationParameter->ParameterData.StringData),
  904. pAtmAddress
  905. );
  906. }
  907. return (Status);
  908. }
  909. #ifdef QOS_HEURISTICS
  910. NDIS_STATUS
  911. AtmArpCfgReadQosHeuristics(
  912. IN NDIS_HANDLE LISConfigHandle,
  913. IN PATMARP_INTERFACE pInterface
  914. )
  915. /*++
  916. Routine Description:
  917. Read in QoS heuristics configured for this interface. If we do find
  918. these parameters configured, we turn on heuristics by setting the
  919. packet classification handlers in the Interface structure. If nothing
  920. is configured, the packet classification routines are NULLed out, and
  921. all data is "best effort".
  922. Arguments:
  923. LISConfigHandle - Handle returned by NdisOpenProtoXXX
  924. pInterface - Interface being configured.
  925. Return Value:
  926. NDIS_STATUS always, as of now.
  927. --*/
  928. {
  929. NDIS_STATUS Status;
  930. NDIS_STRING SubkeyName;
  931. NDIS_STRING ParameterName;
  932. NDIS_HANDLE FlowInfoHandle; // "FlowInfo" under LIS
  933. NDIS_HANDLE FlowHandle; // For each Flow under "FlowInfo"
  934. INT NumFlowsConfigured;
  935. PATMARP_FLOW_INFO pFlowInfo;
  936. PATMARP_FLOW_INFO *ppNextFlow;
  937. PAA_READ_CONFIG_PARAMS pParamEntry;
  938. INT i;
  939. PNDIS_CONFIGURATION_PARAMETER pNdisConfigurationParameter;
  940. NumFlowsConfigured = 0;
  941. do
  942. {
  943. //
  944. // Check if QoS heuristics are enabled.
  945. //
  946. NdisInitUnicodeString(
  947. &ParameterName,
  948. AA_LIS_FLOW_INFO_ENABLED
  949. );
  950. NdisReadConfiguration(
  951. &Status,
  952. &pNdisConfigurationParameter,
  953. LISConfigHandle,
  954. &ParameterName,
  955. NdisParameterInteger
  956. );
  957. if (Status != NDIS_STATUS_SUCCESS)
  958. {
  959. AADEBUGP(AAD_INFO, ("IF 0x%x: could not read %ws\n",
  960. pInterface, AA_LIS_FLOW_INFO_ENABLED));
  961. break;
  962. }
  963. if (pNdisConfigurationParameter->ParameterData.IntegerData == 0)
  964. {
  965. AADEBUGP(AAD_INFO, ("IF 0x%x: Flow Info disabled\n", pInterface));
  966. break;
  967. }
  968. NdisInitUnicodeString(&SubkeyName, AA_LIS_FLOW_INFO_KEY);
  969. NdisOpenConfigurationKeyByName(
  970. &Status,
  971. LISConfigHandle,
  972. &SubkeyName,
  973. &FlowInfoHandle
  974. );
  975. if (Status != NDIS_STATUS_SUCCESS)
  976. {
  977. AADEBUGP(AAD_INFO, ("IF 0x%x: No flows configured\n", pInterface));
  978. break;
  979. }
  980. //
  981. // Read in all flows configured. Stop when there are no more
  982. // configured flows, or we run out of memory.
  983. //
  984. for (;;)
  985. {
  986. //
  987. // Open the next key under the Flow Info section.
  988. //
  989. AA_SET_MEM(&SubkeyName, 0, sizeof(SubkeyName));
  990. NdisOpenConfigurationKeyByIndex(
  991. &Status,
  992. FlowInfoHandle,
  993. NumFlowsConfigured,
  994. &SubkeyName,
  995. &FlowHandle
  996. );
  997. if (Status != NDIS_STATUS_SUCCESS)
  998. {
  999. break;
  1000. }
  1001. AA_ALLOC_MEM(pFlowInfo, ATMARP_FLOW_INFO, sizeof(ATMARP_FLOW_INFO));
  1002. if (pFlowInfo == (PATMARP_FLOW_INFO)NULL)
  1003. {
  1004. NdisCloseConfiguration(FlowHandle);
  1005. break;
  1006. }
  1007. //
  1008. // Initialize with defaults.
  1009. //
  1010. AA_COPY_MEM(pFlowInfo, &AtmArpDefaultFlowInfo, sizeof(ATMARP_FLOW_INFO));
  1011. pFlowInfo->FlowSpec.SendMaxSize =
  1012. pFlowInfo->FlowSpec.ReceiveMaxSize = pInterface->pAdapter->MaxPacketSize;
  1013. //
  1014. // Read in configured values.
  1015. //
  1016. pParamEntry = AtmArpFlowConfigTable;
  1017. for (i = 0; i < AA_FLOW_INFO_ENTRIES; i++)
  1018. {
  1019. NdisInitUnicodeString(
  1020. &ParameterName,
  1021. pParamEntry->ParameterName
  1022. );
  1023. NdisReadConfiguration(
  1024. &Status,
  1025. &pNdisConfigurationParameter,
  1026. FlowHandle,
  1027. &ParameterName,
  1028. NdisParameterInteger
  1029. );
  1030. if (Status != NDIS_STATUS_SUCCESS)
  1031. {
  1032. //
  1033. // Error in accessing this parameter -- use the default.
  1034. //
  1035. *(ULONG *)((PUCHAR)pFlowInfo + pParamEntry->StructOffset) =
  1036. pParamEntry->DefaultValue;
  1037. }
  1038. else
  1039. {
  1040. *(ULONG *)((PUCHAR)pFlowInfo + pParamEntry->StructOffset) =
  1041. pNdisConfigurationParameter->ParameterData.IntegerData;
  1042. AADEBUGP(AAD_LOUD,
  1043. ("Flow Info #%d: %ws = %d\n",
  1044. NumFlowsConfigured,
  1045. pParamEntry->ParameterName,
  1046. pNdisConfigurationParameter->ParameterData.IntegerData));
  1047. }
  1048. pParamEntry++;
  1049. }
  1050. NdisCloseConfiguration(FlowHandle);
  1051. //
  1052. // Link this in the appropriate point in the list of flows.
  1053. // We keep the list sorted in ascending order of PacketSizeLimit.
  1054. //
  1055. ppNextFlow = &(pInterface->pFlowInfoList);
  1056. while (*ppNextFlow != (PATMARP_FLOW_INFO)NULL)
  1057. {
  1058. if (pFlowInfo->PacketSizeLimit < (*ppNextFlow)->PacketSizeLimit)
  1059. {
  1060. //
  1061. // Found the place.
  1062. //
  1063. break;
  1064. }
  1065. else
  1066. {
  1067. ppNextFlow = &((*ppNextFlow)->pNextFlow);
  1068. }
  1069. }
  1070. //
  1071. // Insert the new Flow at its designated place.
  1072. //
  1073. pFlowInfo->pNextFlow = *ppNextFlow;
  1074. *ppNextFlow = pFlowInfo;
  1075. NumFlowsConfigured ++;
  1076. }
  1077. NdisCloseConfiguration(FlowInfoHandle);
  1078. }
  1079. while (FALSE);
  1080. #ifdef GPC
  1081. if (pAtmArpGlobalInfo->GpcClientHandle != NULL)
  1082. #else
  1083. if (NumFlowsConfigured > 0)
  1084. #endif // GPC
  1085. {
  1086. //
  1087. // Set the packet classification handlers.
  1088. //
  1089. pInterface->pGetPacketSpecFunc = AtmArpQosGetPacketSpecs;
  1090. pInterface->pFlowMatchFunc = AtmArpQosDoFlowsMatch;
  1091. #ifndef GPC
  1092. //
  1093. // We don't want to look at patterns within the packet.
  1094. // Let the GPC do it for us.
  1095. //
  1096. pInterface->pFilterMatchFunc = AtmArpQosDoFiltersMatch;
  1097. #endif // GPC
  1098. }
  1099. return (NDIS_STATUS_SUCCESS);
  1100. }
  1101. #endif // QOS_HEURISTICS
  1102. VOID
  1103. AtmArpCfgReadStaticArpEntries(
  1104. IN NDIS_HANDLE LISConfigHandle,
  1105. IN PATMARP_INTERFACE pInterface
  1106. )
  1107. /*++
  1108. Routine Description:
  1109. Read in a list of IP-ATM mappings for this interface.
  1110. This information is in a Multi-string in the following format:
  1111. "<IPaddress1>-<ATMaddress1>
  1112. <IPaddress2>-<ATMaddress2>
  1113. ...."
  1114. NOTE: we don't support subaddress for now.
  1115. Arguments:
  1116. LISConfigHandle - Handle to LIS configuration key.
  1117. pInterface - Pointer to interface
  1118. Return Value:
  1119. None.
  1120. --*/
  1121. {
  1122. NDIS_STATUS Status;
  1123. PNDIS_CONFIGURATION_PARAMETER pParam;
  1124. NDIS_STRING ArpListKeyName;
  1125. NDIS_STRING AddressString;
  1126. ATM_ADDRESS ATMAddress;
  1127. IP_ADDRESS IPAddress;
  1128. PWSTR p, q;
  1129. INT i, j;
  1130. do
  1131. {
  1132. NdisInitUnicodeString(&ArpListKeyName, AA_LIS_STATIC_ARP_LIST);
  1133. NdisReadConfiguration(
  1134. &Status,
  1135. &pParam,
  1136. LISConfigHandle,
  1137. &ArpListKeyName,
  1138. NdisParameterMultiString
  1139. );
  1140. if ((Status != NDIS_STATUS_SUCCESS) ||
  1141. (pParam->ParameterType != NdisParameterMultiString))
  1142. {
  1143. break;
  1144. }
  1145. //
  1146. // Go through the MULTI-string, each of which should be
  1147. // an <IP, ATM> tuple. Create a static mapping for each
  1148. // one successfully read in. Skip invalid entries.
  1149. //
  1150. for (p = pParam->ParameterData.StringData.Buffer, i = 0;
  1151. *p != L'\0';
  1152. i++)
  1153. {
  1154. NdisInitUnicodeString(&AddressString, p);
  1155. q = p;
  1156. //
  1157. // Prepare early for the next iteration in case we
  1158. // skip this entry and continue on.
  1159. //
  1160. p = (PWSTR)((PUCHAR)p + AddressString.Length + sizeof(WCHAR));
  1161. //
  1162. // Find the '-' and replace it with a NULL char.
  1163. //
  1164. for (j = 0; j < AddressString.Length; j++, q++)
  1165. {
  1166. if (*q == L'-')
  1167. {
  1168. *q++ = L'\0';
  1169. //
  1170. // q now points to the character following the hyphen.
  1171. //
  1172. break;
  1173. }
  1174. }
  1175. if (j == AddressString.Length)
  1176. {
  1177. AADEBUGP(AAD_WARNING, ("CfgReadStatic..: did not find - in string: %ws\n",
  1178. AddressString.Buffer));
  1179. continue;
  1180. }
  1181. //
  1182. // Parse the IP address first.
  1183. //
  1184. if (!AtmArpConvertStringToIPAddress(
  1185. AddressString.Buffer,
  1186. &IPAddress))
  1187. {
  1188. AADEBUGP(AAD_WARNING, ("CfgReadStatic..: bad IP addr string: %ws\n",
  1189. AddressString.Buffer));
  1190. continue;
  1191. }
  1192. //
  1193. // Convert to net-endian for the call to AtmArpLearnIPToAtm.
  1194. //
  1195. IPAddress = HOST_TO_NET_LONG(IPAddress);
  1196. //
  1197. // Now parse the ATM Address.
  1198. //
  1199. NdisInitUnicodeString(&AddressString, q);
  1200. NdisConvertStringToAtmAddress(
  1201. &Status,
  1202. &AddressString,
  1203. &ATMAddress
  1204. );
  1205. if (Status != NDIS_STATUS_SUCCESS)
  1206. {
  1207. AADEBUGP(AAD_WARNING, ("CfgReadStatic...: Status %x, bad ATM addr string(%d): %ws\n",
  1208. Status, AddressString.Length, AddressString.Buffer));
  1209. continue;
  1210. }
  1211. //
  1212. // Got a pair - enter them in the ARP table.
  1213. //
  1214. AADEBUGPMAP(AAD_VERY_LOUD,
  1215. "Static", &IPAddress, &ATMAddress);
  1216. (VOID)AtmArpLearnIPToAtm(
  1217. pInterface,
  1218. &IPAddress,
  1219. (UCHAR)AA_PKT_ATM_ADDRESS_TO_TYPE_LEN(&ATMAddress),
  1220. (PUCHAR)&ATMAddress.Address[0],
  1221. (UCHAR)0, // no subaddress
  1222. (PUCHAR)NULL,
  1223. TRUE // Static Entry
  1224. );
  1225. }
  1226. }
  1227. while (FALSE);
  1228. return;
  1229. }
  1230. #define IP_ADDRESS_STRING_LENGTH (16+2) // +2 for double NULL on MULTI_SZ
  1231. BOOLEAN
  1232. AtmArpConvertStringToIPAddress(
  1233. IN PWCHAR AddressString,
  1234. OUT PULONG IpAddress
  1235. )
  1236. /*++
  1237. Routine Description
  1238. This function converts an Internet standard 4-octet dotted decimal
  1239. IP address string into a numeric IP address. Unlike inet_addr(), this
  1240. routine does not support address strings of less than 4 octets nor does
  1241. it support octal and hexadecimal octets.
  1242. Copied from tcpip\ip\ntip.c
  1243. Arguments
  1244. AddressString - IP address in dotted decimal notation
  1245. IpAddress - Pointer to a variable to hold the resulting address
  1246. Return Value:
  1247. TRUE if the address string was converted. FALSE otherwise.
  1248. --*/
  1249. {
  1250. UNICODE_STRING unicodeString;
  1251. STRING aString;
  1252. UCHAR dataBuffer[IP_ADDRESS_STRING_LENGTH];
  1253. NTSTATUS status;
  1254. PUCHAR addressPtr, cp, startPointer, endPointer;
  1255. ULONG digit, multiplier;
  1256. INT i;
  1257. aString.Length = 0;
  1258. aString.MaximumLength = IP_ADDRESS_STRING_LENGTH;
  1259. aString.Buffer = dataBuffer;
  1260. NdisInitUnicodeString(&unicodeString, AddressString);
  1261. status = NdisUnicodeStringToAnsiString(
  1262. &aString,
  1263. &unicodeString
  1264. );
  1265. if (status != NDIS_STATUS_SUCCESS)
  1266. {
  1267. return(FALSE);
  1268. }
  1269. *IpAddress = 0;
  1270. addressPtr = (PUCHAR) IpAddress;
  1271. startPointer = dataBuffer;
  1272. endPointer = dataBuffer;
  1273. i = 3;
  1274. while (i >= 0)
  1275. {
  1276. //
  1277. // Collect the characters up to a '.' or the end of the string.
  1278. //
  1279. while ((*endPointer != '.') && (*endPointer != '\0')) {
  1280. endPointer++;
  1281. }
  1282. if (startPointer == endPointer) {
  1283. return(FALSE);
  1284. }
  1285. //
  1286. // Convert the number.
  1287. //
  1288. for ( cp = (endPointer - 1), multiplier = 1, digit = 0;
  1289. cp >= startPointer;
  1290. cp--, multiplier *= 10
  1291. ) {
  1292. if ((*cp < '0') || (*cp > '9') || (multiplier > 100)) {
  1293. return(FALSE);
  1294. }
  1295. digit += (multiplier * ((ULONG) (*cp - '0')));
  1296. }
  1297. if (digit > 255) {
  1298. return(FALSE);
  1299. }
  1300. addressPtr[i] = (UCHAR) digit;
  1301. //
  1302. // We are finished if we have found and converted 4 octets and have
  1303. // no other characters left in the string.
  1304. //
  1305. if ( (i-- == 0) &&
  1306. ((*endPointer == '\0') || (*endPointer == ' '))
  1307. ) {
  1308. return(TRUE);
  1309. }
  1310. if (*endPointer == '\0') {
  1311. return(FALSE);
  1312. }
  1313. startPointer = ++endPointer;
  1314. }
  1315. return(FALSE);
  1316. }