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.

659 lines
14 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. wanarp\info.c
  5. Abstract:
  6. The file contains the code that is involved with setting and
  7. getting info for the adapters and interfaces
  8. Revision History:
  9. AmritanR
  10. --*/
  11. #define __FILE_SIG__ INFO_SIG
  12. #include "inc.h"
  13. INT
  14. WanIpSetRequest(
  15. PVOID pvContext,
  16. NDIS_OID Oid,
  17. UINT Type
  18. )
  19. {
  20. return NDIS_STATUS_SUCCESS;
  21. }
  22. UINT
  23. WanIpAddAddress(
  24. IN PVOID pvContext,
  25. IN UINT uiType,
  26. IN DWORD dwAddress,
  27. IN DWORD dwMask,
  28. IN PVOID pvUnused
  29. )
  30. /*++
  31. Routine Description:
  32. This routine is called by the upper layer to add an address as a local
  33. address, or specify the broadcast address for this Interface
  34. Locks:
  35. Arguments:
  36. Return Value:
  37. NO_ERROR
  38. --*/
  39. {
  40. TraceEnter(ADPT, "WanAddAddress");
  41. Trace(ADPT, TRACE,
  42. ("AddAddress: %d.%d.%d.%d\n", PRINT_IPADDR(dwAddress)));
  43. TraceLeave(ADPT, "WanAddAddress");
  44. return (UINT)TRUE;
  45. }
  46. UINT
  47. WanIpDeleteAddress(
  48. IN PVOID pvContext,
  49. IN UINT uiType,
  50. IN DWORD dwAddress,
  51. IN DWORD dwMask
  52. )
  53. /*++
  54. Routine Description:
  55. Called to delete a local or proxy address.
  56. Locks:
  57. Arguments:
  58. Return Value:
  59. NO_ERROR
  60. --*/
  61. {
  62. TraceEnter(ADPT, "WanDeleteAddress");
  63. Trace(ADPT, TRACE,
  64. ("DeleteAddress: %d.%d.%d.%d\n", PRINT_IPADDR(dwAddress)));
  65. TraceLeave(ADPT, "WanDeleteAddress");
  66. return TRUE;
  67. }
  68. INT
  69. WanIpQueryInfo(
  70. IN PVOID pvIfContext,
  71. IN TDIObjectID *pTdiObjId,
  72. IN PNDIS_BUFFER pnbBuffer,
  73. IN PUINT puiSize,
  74. IN PVOID pvContext
  75. )
  76. /*++
  77. Routine Description:
  78. Routine is called by IP to query the MIB-II information related
  79. to the UMODE_INTERFACE. IP passes us a pointer to the ADAPTER. We map
  80. it to the UMODE_INTERFACE using the ADAPTER and pass back the
  81. statistics related to that UMODE_INTERFACE
  82. Locks:
  83. We acquire the adapter lock and get a pointer to the interface from the
  84. adapter. We dont lock the interface because all the info copied
  85. out is changed by InterlockedXxx. Also because the adapter has a mapping
  86. from to the interface, the interface can not be deleted since to
  87. to bring the refcount on the interface to 0, this mapping needs to be
  88. cleared from the adapter, which needs the adapter lock, which we are
  89. holding
  90. Arguments:
  91. pvIfContext The context we returned to IP, a pointer to the ADAPTER
  92. pTdiObjId
  93. pnbBuffer
  94. puiSize
  95. pvContext
  96. Return Value:
  97. TDI_INVALID_REQUEST
  98. TDI_INVALID_PARAMETER
  99. TDI_BUFFER_TOO_SMALL
  100. TDI_BUFFER_OVERFLOW
  101. TDI_SUCCESS
  102. --*/
  103. {
  104. PADAPTER pAdapter;
  105. PUMODE_INTERFACE pInterface;
  106. ULONG ulOffset;
  107. ULONG ulBufferSize;
  108. UINT BytesCopied = 0;
  109. BYTE rgbyInfoBuff[sizeof(IFEntry)];
  110. DWORD dwEntity;
  111. DWORD dwInstance;
  112. IFEntry *pIFE;
  113. NTSTATUS nStatus;
  114. KIRQL kiIrql;
  115. dwEntity = pTdiObjId->toi_entity.tei_entity;
  116. dwInstance = pTdiObjId->toi_entity.tei_instance;
  117. pAdapter = (PADAPTER)pvIfContext;
  118. //
  119. // We support only Interface MIBs - no address xlation - pretty much like
  120. // a loopback i/f (per Henry circa 1994)
  121. //
  122. if((dwEntity isnot IF_ENTITY) or
  123. (dwInstance isnot pAdapter->dwIfInstance))
  124. {
  125. return TDI_INVALID_REQUEST;
  126. }
  127. if(pTdiObjId->toi_type isnot INFO_TYPE_PROVIDER)
  128. {
  129. Trace(ADPT, INFO,
  130. ("IpQueryInfo: toi_type is wrong 0x%x\n",
  131. pTdiObjId->toi_type));
  132. return TDI_INVALID_PARAMETER;
  133. }
  134. //
  135. // a safe initialization.
  136. //
  137. ulBufferSize = *puiSize;
  138. *puiSize = 0;
  139. ulOffset = 0;
  140. if(pTdiObjId->toi_class is INFO_CLASS_GENERIC)
  141. {
  142. if(pTdiObjId->toi_id isnot ENTITY_TYPE_ID)
  143. {
  144. Trace(ADPT, INFO,
  145. ("IpQueryInfo: toi_id is wrong 0x%x\n",
  146. pTdiObjId->toi_id));
  147. return TDI_INVALID_PARAMETER;
  148. }
  149. //
  150. // He's trying to see what type we are.
  151. //
  152. if(ulBufferSize < sizeof(DWORD))
  153. {
  154. Trace(ADPT, ERROR,
  155. ("IpQueryInfo: Buffer size %d too small\n",
  156. ulBufferSize));
  157. return TDI_BUFFER_TOO_SMALL;
  158. }
  159. *(PDWORD)&rgbyInfoBuff[0] = (dwEntity is AT_ENTITY) ? AT_ARP : IF_MIB;
  160. #if NDISBUFFERISMDL
  161. nStatus = TdiCopyBufferToMdl(rgbyInfoBuff,
  162. 0,
  163. sizeof(DWORD),
  164. (PMDL)pnbBuffer,
  165. 0,
  166. &ulOffset);
  167. #else
  168. #error "Fix this"
  169. #endif
  170. *puiSize = ulOffset;
  171. return nStatus;
  172. }
  173. if(pTdiObjId->toi_class isnot INFO_CLASS_PROTOCOL)
  174. {
  175. Trace(ADPT, INFO,
  176. ("IpQueryInfo: toi_class is wrong 0x%x\n",
  177. pTdiObjId->toi_class));
  178. return TDI_INVALID_PARAMETER;
  179. }
  180. //
  181. // The usermust be asking for Interface level information.
  182. // See if we support what is being asked for
  183. //
  184. if(pTdiObjId->toi_id isnot IF_MIB_STATS_ID)
  185. {
  186. Trace(ADPT, INFO,
  187. ("IpQueryInfo: toi_id 0x%x is not MIB_STATS\n",
  188. pTdiObjId->toi_id));
  189. return TDI_INVALID_PARAMETER;
  190. }
  191. //
  192. // He's asking for statistics. Make sure his buffer is at least big
  193. // enough to hold the fixed part.
  194. //
  195. if(ulBufferSize < IFE_FIXED_SIZE)
  196. {
  197. Trace(ADPT, ERROR,
  198. ("IpQueryInfo: Buffer size %d smaller than IFE %d\n",
  199. ulBufferSize, IFE_FIXED_SIZE));
  200. return TDI_BUFFER_TOO_SMALL;
  201. }
  202. //
  203. // He's got enough to hold the fixed part. Build the IFEntry structure,
  204. // and copy it to his buffer.
  205. //
  206. pAdapter = (PADAPTER)pvIfContext;
  207. pIFE = (IFEntry *)rgbyInfoBuff;
  208. RtlZeroMemory(pIFE,
  209. sizeof(IFEntry));
  210. RtAcquireSpinLock(&(pAdapter->rlLock),
  211. &kiIrql);
  212. //
  213. // This stuff doesnt require an interface to be mapped
  214. //
  215. pIFE->if_index = pAdapter->dwAdapterIndex;
  216. pIFE->if_type = IF_TYPE_PPP;
  217. pIFE->if_physaddrlen = ARP_802_ADDR_LENGTH;
  218. pIFE->if_outqlen = pAdapter->ulQueueLen;
  219. pIFE->if_descrlen = VENDOR_DESCRIPTION_STRING_LEN;
  220. RtlCopyMemory(pIFE->if_physaddr,
  221. pAdapter->rgbyHardwareAddr,
  222. ARP_802_ADDR_LENGTH);
  223. if(pAdapter->byState isnot AS_MAPPED)
  224. {
  225. Trace(ADPT, INFO,
  226. ("IpQueryInfo: called for adapter %x that is unmapped\n",
  227. pAdapter));
  228. #if 0
  229. RtReleaseSpinLock(&(pAdapter->rlLock),
  230. kiIrql);
  231. return TDI_INVALID_PARAMETER;
  232. #endif
  233. }
  234. else
  235. {
  236. //
  237. // Get a pointer to the interface and lock the interface
  238. //
  239. pInterface = pAdapter->pInterface;
  240. RtAssert(pInterface);
  241. if(pAdapter->pConnEntry is NULL)
  242. {
  243. //
  244. // If a mapped adapter doesnt have an associated connection, then
  245. // it is either server adapter or router in process of connecting
  246. //
  247. RtAssert((pInterface->duUsage is DU_CALLIN) or
  248. ((pInterface->duUsage is DU_ROUTER) and
  249. (pInterface->dwOperState is IF_OPER_STATUS_CONNECTING)));
  250. pIFE->if_mtu = WANARP_DEFAULT_MTU;
  251. pIFE->if_speed = WANARP_DEFAULT_SPEED;
  252. }
  253. else
  254. {
  255. pIFE->if_mtu = pAdapter->pConnEntry->ulMtu;
  256. pIFE->if_speed = pAdapter->pConnEntry->ulSpeed;
  257. }
  258. pIFE->if_adminstatus = pInterface->dwAdminState;
  259. pIFE->if_operstatus = pInterface->dwOperState;
  260. pIFE->if_lastchange = pInterface->dwLastChange;
  261. pIFE->if_inoctets = pInterface->ulInOctets;
  262. pIFE->if_inucastpkts = pInterface->ulInUniPkts;
  263. pIFE->if_innucastpkts = pInterface->ulInNonUniPkts;
  264. pIFE->if_indiscards = pInterface->ulInDiscards;
  265. pIFE->if_inerrors = pInterface->ulInErrors;
  266. pIFE->if_inunknownprotos = pInterface->ulInUnknownProto;
  267. pIFE->if_outoctets = pInterface->ulOutOctets;
  268. pIFE->if_outucastpkts = pInterface->ulOutUniPkts;
  269. pIFE->if_outnucastpkts = pInterface->ulOutNonUniPkts;
  270. pIFE->if_outdiscards = pInterface->ulOutDiscards;
  271. pIFE->if_outerrors = pInterface->ulOutErrors;
  272. }
  273. #if NDISBUFFERISMDL
  274. nStatus = TdiCopyBufferToMdl(pIFE,
  275. 0,
  276. IFE_FIXED_SIZE,
  277. (PMDL)pnbBuffer,
  278. 0,
  279. &ulOffset);
  280. #else
  281. #error "Fix this"
  282. #endif
  283. //
  284. // See if he has room for the descriptor string.
  285. //
  286. if(ulBufferSize < (IFE_FIXED_SIZE + VENDOR_DESCRIPTION_STRING_LEN))
  287. {
  288. Trace(ADPT, INFO,
  289. ("IpQueryInfo: Buffer size %d too small for VENDOR string\n",
  290. ulBufferSize));
  291. //
  292. // Not enough room to copy the desc. string.
  293. //
  294. *puiSize = IFE_FIXED_SIZE;
  295. RtReleaseSpinLock(&(pAdapter->rlLock),
  296. kiIrql);
  297. return TDI_BUFFER_OVERFLOW;
  298. }
  299. #if NDISBUFFERISMDL
  300. nStatus = TdiCopyBufferToMdl(VENDOR_DESCRIPTION_STRING,
  301. 0,
  302. strlen(VENDOR_DESCRIPTION_STRING),
  303. (PMDL)pnbBuffer,
  304. ulOffset,
  305. &ulOffset);
  306. #else
  307. #error "Fix this"
  308. #endif
  309. *puiSize = IFE_FIXED_SIZE + VENDOR_DESCRIPTION_STRING_LEN;
  310. RtReleaseSpinLock(&(pAdapter->rlLock),
  311. kiIrql);
  312. return TDI_SUCCESS;
  313. }
  314. INT
  315. WanIpSetInfo(
  316. IN PVOID pvContext,
  317. IN TDIObjectID *pTdiObjId,
  318. IN PVOID pvBuffer,
  319. IN UINT uiSize
  320. )
  321. /*++
  322. Routine Description:
  323. The set info routine. We dont do anything here
  324. Locks:
  325. None because we arent changing anything
  326. Arguments:
  327. pvContext
  328. pTdiObjId
  329. pvBuffer
  330. uiSize
  331. Return Value:
  332. TDI_INVALID_REQUEST
  333. TDI_INVALID_PARAMETER
  334. TDI_BUFFER_TOO_SMALL
  335. TDI_SUCCESS
  336. --*/
  337. {
  338. INT iStatus;
  339. IFEntry *pIFE;
  340. DWORD dwEntity;
  341. DWORD dwInstance;
  342. PADAPTER pAdapter;
  343. pIFE = (IFEntry *)pvBuffer;
  344. dwEntity = pTdiObjId->toi_entity.tei_entity;
  345. dwInstance = pTdiObjId->toi_entity.tei_instance;
  346. pAdapter = (PADAPTER)pvContext;
  347. //
  348. // Might be able to handle this.
  349. //
  350. if((dwEntity isnot IF_ENTITY) or
  351. (dwInstance isnot pAdapter->dwIfInstance))
  352. {
  353. return TDI_INVALID_REQUEST;
  354. }
  355. //
  356. // It's for the I/F level, see if it's for the statistics.
  357. //
  358. if (pTdiObjId->toi_class isnot INFO_CLASS_PROTOCOL)
  359. {
  360. Trace(ADPT, INFO,
  361. ("WanSetInfo: toi_class is wrong 0x%x\n",
  362. pTdiObjId->toi_class));
  363. return TDI_INVALID_PARAMETER;
  364. }
  365. if (pTdiObjId->toi_id isnot IF_MIB_STATS_ID)
  366. {
  367. Trace(ADPT, INFO,
  368. ("WanSetInfo: toi_id 0x%x is not MIB_STATS\n",
  369. pTdiObjId->toi_id));
  370. return TDI_INVALID_PARAMETER;
  371. }
  372. //
  373. // It's for the stats. Make sure it's a valid size.
  374. //
  375. if(uiSize < IFE_FIXED_SIZE)
  376. {
  377. Trace(ADPT, ERROR,
  378. ("WanSetInfo: Buffer size %d too small\n",
  379. uiSize));
  380. return TDI_BUFFER_TOO_SMALL;
  381. }
  382. //
  383. // We dont allow any sets on the adapters.
  384. // The only sets are via interfaces and those need to be done
  385. // using the IOCTLs. We could potentially allow sets on the UMODE_INTERFACE
  386. // that the adapter is mapped too, but that would be just another way
  387. // of achieving what the IOCTLS do
  388. //
  389. return TDI_SUCCESS;
  390. }
  391. INT
  392. WanIpGetEntityList(
  393. IN PVOID pvContext,
  394. IN TDIEntityID *pTdiEntityList,
  395. IN PUINT puiCount
  396. )
  397. /*++
  398. Routine Description:
  399. Called by IP to assign us a TDI entity id
  400. Locks:
  401. Takes the adapter lock.
  402. Arguments:
  403. pvContext,
  404. pTdiEntityList,
  405. puiCount
  406. Return Value:
  407. --*/
  408. {
  409. PADAPTER pAdapter;
  410. UINT uiEntityCount;
  411. UINT uiMyIFBase;
  412. UINT i;
  413. TDIEntityID *pTdiIFEntity;
  414. KIRQL kiIrql;
  415. pAdapter = (PADAPTER)pvContext;
  416. RtAcquireSpinLock(&(pAdapter->rlLock),
  417. &kiIrql);
  418. //
  419. // Walk down the list, looking for existing IF entities, and
  420. // adjust our base instance accordingly.
  421. //
  422. uiMyIFBase = 0;
  423. pTdiIFEntity = NULL;
  424. for(i = 0;
  425. i < *puiCount;
  426. i++, pTdiEntityList++)
  427. {
  428. if(pTdiEntityList->tei_entity is IF_ENTITY)
  429. {
  430. //
  431. // if we are already on the list remember our entity item
  432. // o/w find an instance # for us.
  433. //
  434. if((pTdiEntityList->tei_instance is pAdapter->dwIfInstance) and
  435. (pTdiEntityList->tei_instance isnot INVALID_ENTITY_INSTANCE))
  436. {
  437. //
  438. // Matched our instance
  439. //
  440. pTdiIFEntity = pTdiEntityList;
  441. break;
  442. }
  443. else
  444. {
  445. //
  446. // Take the max of the two
  447. //
  448. uiMyIFBase = uiMyIFBase > (pTdiEntityList->tei_instance + 1)?
  449. uiMyIFBase : (pTdiEntityList->tei_instance + 1);
  450. }
  451. }
  452. }
  453. if(pTdiIFEntity is NULL )
  454. {
  455. //
  456. // we are not on the list.
  457. // make sure we have the room for it.
  458. //
  459. if (*puiCount >= MAX_TDI_ENTITIES)
  460. {
  461. return FALSE;
  462. }
  463. pAdapter->dwIfInstance = uiMyIFBase;
  464. //
  465. // Now fill it in.
  466. //
  467. pTdiEntityList->tei_entity = IF_ENTITY;
  468. pTdiEntityList->tei_instance = uiMyIFBase;
  469. (*puiCount)++;
  470. }
  471. else
  472. {
  473. if(pAdapter->byState is AS_REMOVING)
  474. {
  475. //
  476. // If we are going away, remove our instance
  477. //
  478. pAdapter->dwIfInstance = INVALID_ENTITY_INSTANCE;
  479. pTdiEntityList->tei_instance = INVALID_ENTITY_INSTANCE;
  480. }
  481. }
  482. RtReleaseSpinLock(&(pAdapter->rlLock),
  483. kiIrql);
  484. return TRUE;
  485. }