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.

1599 lines
39 KiB

  1. /*++
  2. PDWORD * ppdwAddress*++
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. Abstract:
  6. Implementation of the packet filter control code
  7. Revision History:
  8. Author:
  9. Arnold Miller (ArnoldM) 24-Sept-1997
  10. --*/
  11. #ifndef CHICAGO // don't need these on Memphis
  12. #include "fltapis.hxx"
  13. //
  14. // these care called from the DLL entry which is C code, so
  15. // declare the names to be something the C compiler can
  16. // generate
  17. //
  18. extern "C"
  19. {
  20. VOID
  21. InitFilterApis();
  22. VOID
  23. UnInitFilterApis();
  24. DWORD
  25. AllocateAndGetIpAddrTableFromStack(
  26. OUT MIB_IPADDRTABLE **ppIpAddrTable,
  27. IN BOOL bOrder,
  28. IN HANDLE hHeap,
  29. IN DWORD dwFlags
  30. );
  31. }
  32. InterfaceContainer icContainer;
  33. //
  34. // All of the class methods. If you're looking for the WIN32
  35. // APIs, try the file fltapis.cxx
  36. //
  37. VOID
  38. InterfaceContainer::InitInterfaceContainer()
  39. {
  40. if(!_Inited)
  41. {
  42. _InitResource();
  43. __try {
  44. InitializeCriticalSection(&_csDriverLock);
  45. _Log = 0;
  46. _hDriver = 0;
  47. _Inited = TRUE;
  48. }
  49. __except (EXCEPTION_EXECUTE_HANDLER) {
  50. _DestroyResource();
  51. _Inited = FALSE;
  52. }
  53. }
  54. }
  55. DWORD
  56. InterfaceContainer::FindInterfaceAndRef(INTERFACE_HANDLE pInterface,
  57. PacketFilterInterface ** ppif)
  58. /*++
  59. Routine Description:
  60. Verify that an INTERFACE_HANDLE refers to an extant filter interface.
  61. If successful the object resource is held shared and must be
  62. derefenced when done
  63. --*/
  64. {
  65. DWORD err;
  66. PacketFilterInterface * ppfInterface;
  67. PacketFilterInterface * plook = (PacketFilterInterface *)pInterface;
  68. //
  69. // No need for a _DriverReady here. The verification of the
  70. // interface is sufficient.
  71. //
  72. _AcquireShared();
  73. ppfInterface = (PacketFilterInterface *)_hcHandles.FetchHandleValue(
  74. (DWORD)((DWORD_PTR)pInterface));
  75. if(ppfInterface)
  76. {
  77. *ppif = ppfInterface;
  78. err = ERROR_SUCCESS;
  79. }
  80. else
  81. {
  82. err = ERROR_INVALID_HANDLE;
  83. }
  84. if(err != ERROR_SUCCESS)
  85. {
  86. _Release();
  87. }
  88. return(err);
  89. }
  90. DWORD
  91. InterfaceContainer::AddInterface(
  92. DWORD dwName,
  93. PFFORWARD_ACTION inAction,
  94. PFFORWARD_ACTION outAction,
  95. BOOL fUseLog,
  96. BOOL fMustBeUnique,
  97. INTERFACE_HANDLE *ppInterface)
  98. /*++
  99. Routine Description:
  100. Add a new interface. All this does is create the interface in
  101. the driver. It does not bind it to the stack.
  102. --*/
  103. {
  104. PacketFilterInterface *pfi;
  105. DWORD err = NO_ERROR;
  106. err = _DriverReady();
  107. if(err != STATUS_SUCCESS)
  108. {
  109. return(err);
  110. }
  111. _AcquireExclusive();
  112. pfi = new PacketFilterInterface(
  113. _hDriver,
  114. dwName,
  115. fUseLog ? _Log : 0,
  116. fMustBeUnique,
  117. (FORWARD_ACTION)inAction,
  118. (FORWARD_ACTION)outAction);
  119. if(!pfi)
  120. {
  121. err = GetLastError();
  122. }
  123. else if((err = pfi->GetStatus()) != STATUS_SUCCESS)
  124. {
  125. delete pfi;
  126. }
  127. else
  128. {
  129. __try
  130. {
  131. err = _hcHandles.NewHandle((PVOID)pfi,
  132. (PDWORD)ppInterface);
  133. }
  134. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  135. {
  136. err = ERROR_INVALID_PARAMETER;
  137. }
  138. if(err)
  139. {
  140. //
  141. // Could not add the handle so destroy the interface
  142. //
  143. delete pfi;
  144. }
  145. }
  146. _Release();
  147. return(err);
  148. }
  149. DWORD
  150. InterfaceContainer::DeleteInterface(INTERFACE_HANDLE pInterface)
  151. /*++
  152. Routine Description:
  153. Delete a filter interface.
  154. --*/
  155. {
  156. DWORD err;
  157. PacketFilterInterface *pfi;
  158. _AcquireExclusive();
  159. pfi = (PacketFilterInterface *)_hcHandles.FetchHandleValue(
  160. (DWORD)((DWORD_PTR)pInterface));
  161. if(pfi)
  162. {
  163. //
  164. // a valid handle. Destroy the associated
  165. // interface and free the handle
  166. //
  167. delete pfi;
  168. (VOID)_hcHandles.DeleteHandle((DWORD)((DWORD_PTR)pInterface));
  169. err = ERROR_SUCCESS;
  170. }
  171. else
  172. {
  173. err = ERROR_INVALID_HANDLE;
  174. }
  175. _Release();
  176. return(err);
  177. }
  178. DWORD
  179. InterfaceContainer::SetLogBuffer(
  180. PBYTE pbBuffer,
  181. DWORD dwSize,
  182. DWORD dwThreshold,
  183. DWORD dwEntries,
  184. PDWORD pdwLoggedEntries,
  185. PDWORD pdwLostEntries,
  186. PDWORD pdwSizeUsed)
  187. /*++
  188. Routine Description:
  189. Set a new log buffer for the log
  190. --*/
  191. {
  192. NTSTATUS Status;
  193. PFSETBUFFER pfSet;
  194. IO_STATUS_BLOCK IoStatusBlock;
  195. DWORD err;
  196. //
  197. // Buffer size should be atleast as big as one frame. Actually,
  198. // we can't really say what the size of a frame is going to be
  199. // because the frame has IpHeader and the data which is bigger
  200. // than sizeof(PFLOGFRAME), nevertheless this is a good paramter
  201. // check if caller was passing a zero or something for the size.
  202. //
  203. if (dwSize < sizeof(PFLOGFRAME)) {
  204. return(ERROR_INSUFFICIENT_BUFFER);
  205. }
  206. //
  207. // Make sure that the starting address and the offset both are
  208. // quadword alligned.
  209. //
  210. if (!COUNT_IS_ALIGNED((UINT_PTR)pbBuffer, ALIGN_WORST) ||
  211. !COUNT_IS_ALIGNED(dwSize, ALIGN_WORST)
  212. )
  213. {
  214. return(ERROR_MAPPED_ALIGNMENT);
  215. }
  216. //
  217. // Check the upper bounds for threshold values (dwEntries and dwThreshold)
  218. //
  219. if ( dwThreshold > dwSize ||
  220. (dwEntries * sizeof(PFLOGFRAME)) > dwSize)
  221. return (ERROR_INVALID_PARAMETER);
  222. //
  223. // Check the lower bounds for threshold values (dwEntries and dwThreshold)
  224. //
  225. if ( dwThreshold < sizeof(PFLOGFRAME) )
  226. return (ERROR_INVALID_PARAMETER);
  227. //
  228. // Make sure all the writable memory looks good.
  229. //
  230. if (
  231. IsBadWritePtr(pdwLoggedEntries, sizeof(DWORD)) ||
  232. IsBadWritePtr(pdwLostEntries, sizeof(DWORD)) ||
  233. IsBadWritePtr(pdwSizeUsed, sizeof(DWORD)) ||
  234. IsBadWritePtr(pbBuffer, dwSize)
  235. )
  236. {
  237. return(ERROR_INVALID_PARAMETER);
  238. }
  239. //
  240. // no need to call _DriverReady. If the log exists, the
  241. // driver is ready.
  242. //
  243. _AcquireExclusive();
  244. if(!_Log)
  245. {
  246. err = ERROR_INVALID_HANDLE;
  247. goto Error;
  248. }
  249. pfSet.pfLogId = _Log;
  250. pfSet.dwSize = dwSize;
  251. pfSet.dwSizeThreshold = dwThreshold;
  252. pfSet.dwEntriesThreshold = dwEntries;
  253. pfSet.dwFlags = 0;
  254. pfSet.pbBaseOfLog = pbBuffer;
  255. Status = NtDeviceIoControlFile( _hDriver,
  256. NULL,
  257. NULL,
  258. NULL,
  259. &IoStatusBlock,
  260. IOCTL_SET_LOG_BUFFER,
  261. (PVOID)&pfSet,
  262. sizeof(pfSet),
  263. (PVOID)&pfSet,
  264. sizeof(pfSet));
  265. if(NT_SUCCESS(Status))
  266. {
  267. *pdwLoggedEntries = pfSet.dwLoggedEntries;
  268. *pdwLostEntries = pfSet.dwLostEntries;
  269. *pdwSizeUsed = pfSet.dwSize;
  270. err = ERROR_SUCCESS;
  271. }
  272. else
  273. {
  274. err = CoerceDriverError(Status);
  275. }
  276. Error:
  277. _Release();
  278. return(err);
  279. }
  280. DWORD
  281. InterfaceContainer::MakeLog( HANDLE hEvent )
  282. /*++
  283. Routine Description:
  284. Make a log for this
  285. --*/
  286. {
  287. DWORD err;
  288. PFLOG pfSet;
  289. NTSTATUS Status;
  290. IO_STATUS_BLOCK ioStatus;
  291. err = _DriverReady();
  292. if(err != STATUS_SUCCESS)
  293. {
  294. return(err);
  295. }
  296. _AcquireExclusive();
  297. if(_Log)
  298. {
  299. err = ERROR_ALREADY_ASSIGNED;
  300. }
  301. else
  302. {
  303. memset(&pfSet, 0, sizeof(pfSet));
  304. pfSet.hEvent = hEvent;
  305. pfSet.dwFlags = 0;
  306. Status = NtDeviceIoControlFile(
  307. _hDriver,
  308. NULL,
  309. NULL,
  310. NULL,
  311. &ioStatus,
  312. IOCTL_PF_CREATE_LOG,
  313. (PVOID)&pfSet,
  314. sizeof(pfSet),
  315. (PVOID)&pfSet,
  316. sizeof(pfSet));
  317. if(NT_SUCCESS(Status))
  318. {
  319. _Log = pfSet.pfLogId;
  320. }
  321. else
  322. {
  323. err = CoerceDriverError(Status);
  324. }
  325. }
  326. _Release();
  327. return(err);
  328. }
  329. DWORD
  330. InterfaceContainer::DeleteLog( VOID )
  331. /*++
  332. Routine Description:
  333. Delete the log and by implication remove the log from all
  334. of the interfaces
  335. --*/
  336. {
  337. DWORD err = ERROR_SUCCESS;
  338. PFDELETELOG pfSet;
  339. NTSTATUS Status;
  340. IO_STATUS_BLOCK ioStatus;
  341. _AcquireExclusive();
  342. if(!_Log)
  343. {
  344. err = ERROR_INVALID_HANDLE;
  345. }
  346. else
  347. {
  348. pfSet.pfLogId = _Log;
  349. Status = NtDeviceIoControlFile(
  350. _hDriver,
  351. NULL,
  352. NULL,
  353. NULL,
  354. &ioStatus,
  355. IOCTL_PF_DELETE_LOG,
  356. (PVOID)&pfSet,
  357. sizeof(pfSet),
  358. (PVOID)&pfSet,
  359. sizeof(pfSet));
  360. if(NT_SUCCESS(Status))
  361. {
  362. _Log = 0;
  363. }
  364. else
  365. {
  366. err = CoerceDriverError(Status);
  367. }
  368. }
  369. _Release();
  370. return(err);
  371. }
  372. VOID
  373. InterfaceContainer::AddressUpdateNotification()
  374. {
  375. }
  376. //
  377. // The PacketFilterInterface methods.
  378. //
  379. PacketFilterInterface::PacketFilterInterface(
  380. HANDLE hDriver,
  381. DWORD dwName,
  382. PFLOGGER pfLog,
  383. BOOL fMustBeUnique,
  384. FORWARD_ACTION inAction,
  385. FORWARD_ACTION outAction)
  386. /*++
  387. Routine Description:
  388. Constructor for a new interface. If this interface must
  389. be unique, then dwName should be 0. Otherwise pick
  390. a name that can be associated with other uses, such as the
  391. IP address of the interface or some manifest. This assumes
  392. the creater of this will check the status code and destruct
  393. the object if it is not successful. This is important since
  394. the other methods do not check for successful construction.
  395. --*/
  396. {
  397. PFINTERFACEPARAMETERS Parms;
  398. DWORD dwInBufLen = sizeof(Parms);
  399. IO_STATUS_BLOCK IoStatusBlock;
  400. NTSTATUS Status;
  401. InitializeCriticalSection(&_cs);
  402. _hDriver = hDriver;
  403. _dwFlags = 0;
  404. //
  405. // now create the interface.
  406. //
  407. memset(&Parms, 0, sizeof(Parms));
  408. Parms.pfbType = PF_BIND_NAME;
  409. Parms.eaIn = inAction;
  410. Parms.eaOut = outAction;
  411. Parms.dwBindingData = dwName;
  412. Parms.fdInterface.dwIfIndex = dwName;
  413. Parms.fdInterface.pvRtrMgrContext = UlongToPtr(dwName);
  414. Parms.pfLogId = pfLog;
  415. if(fMustBeUnique)
  416. {
  417. //
  418. // this is a non-sharable interface. Mark it as such
  419. //
  420. Parms.dwInterfaceFlags |= PFSET_FLAGS_UNIQUE;
  421. }
  422. Status = NtDeviceIoControlFile(_hDriver,
  423. NULL,
  424. NULL,
  425. NULL,
  426. &IoStatusBlock,
  427. IOCTL_PF_CREATE_AND_SET_INTERFACE_PARAMETERS,
  428. (PVOID)&Parms,
  429. dwInBufLen,
  430. (PVOID)&Parms,
  431. dwInBufLen);
  432. if(NT_SUCCESS(Status))
  433. {
  434. _err = ERROR_SUCCESS;
  435. _pvDriverContext = Parms.fdInterface.pvDriverContext;
  436. }
  437. else
  438. {
  439. _err = icContainer.CoerceDriverError(Status);
  440. }
  441. }
  442. PacketFilterInterface::~PacketFilterInterface()
  443. /*++
  444. Routine Description:
  445. Destructor. Tells the filter driver to forget this interface. Any
  446. filters will be removed by the driver.
  447. --*/
  448. {
  449. if(!_err)
  450. {
  451. IO_STATUS_BLOCK IoStatusBlock;
  452. FILTER_DRIVER_DELETE_INTERFACE di;
  453. di.pvDriverContext = _pvDriverContext;
  454. NtDeviceIoControlFile(_hDriver,
  455. NULL,
  456. NULL,
  457. NULL,
  458. &IoStatusBlock,
  459. IOCTL_DELETE_INTERFACEEX,
  460. (PVOID)&di,
  461. sizeof(di),
  462. (PVOID)&di,
  463. sizeof(di));
  464. }
  465. DeleteCriticalSection(&_cs);
  466. }
  467. DWORD
  468. PacketFilterInterface::_CommonBind(PFBINDINGTYPE dwBindType, DWORD dwData, DWORD LinkData)
  469. /*++
  470. Routine Description:
  471. Common routine to bind an interface. The driver has
  472. been verified.
  473. --*/
  474. {
  475. INTERFACEBINDING2 Bind2;
  476. IO_STATUS_BLOCK IoStatusBlock;
  477. NTSTATUS Status;
  478. DWORD err;
  479. //
  480. // Must serialize this. Even though the shared resource is held,
  481. // this is a "write" operation and therfore needs strict
  482. // serialization.
  483. //
  484. _Lock();
  485. if(_IsBound())
  486. {
  487. _UnLock();
  488. return(ERROR_INVALID_PARAMETER);
  489. }
  490. //
  491. // We're not bound.
  492. // Note that we are using new type of struture for the compitability.
  493. // The old INTERFACEBINDING structure does not have support for
  494. // link addresses. Note also that we are using a new IOCTL here.
  495. //
  496. Bind2.pvDriverContext = _pvDriverContext;
  497. Bind2.pfType = dwBindType;
  498. Bind2.dwAdd = dwData;
  499. Bind2.dwLinkAdd = LinkData;
  500. Status = NtDeviceIoControlFile(_hDriver,
  501. NULL,
  502. NULL,
  503. NULL,
  504. &IoStatusBlock,
  505. IOCTL_SET_INTERFACE_BINDING2,
  506. (PVOID)&Bind2,
  507. sizeof(Bind2),
  508. (PVOID)&Bind2,
  509. sizeof(Bind2));
  510. if(NT_SUCCESS(Status))
  511. {
  512. _SetBound();
  513. err = ERROR_SUCCESS;
  514. _dwEpoch = Bind2.dwEpoch;
  515. }
  516. else
  517. {
  518. err = icContainer.CoerceDriverError(Status);
  519. }
  520. _UnLock();
  521. return(err);
  522. }
  523. DWORD
  524. PacketFilterInterface::UnBindInterface( VOID )
  525. /*++
  526. Routine Description:
  527. Unbind the interface from whatever it is bound to
  528. --*/
  529. {
  530. INTERFACEBINDING Bind;
  531. IO_STATUS_BLOCK IoStatusBlock;
  532. NTSTATUS Status;
  533. DWORD err;
  534. //
  535. // Must serialize this. Even though the shared resource is held,
  536. // this is a "write" operation and therfore needs strict
  537. // serialization.
  538. //
  539. _Lock();
  540. if(!_IsBound())
  541. {
  542. _UnLock();
  543. return(ERROR_INVALID_PARAMETER);
  544. }
  545. //
  546. // We're address bound. So unbind from the stack
  547. //
  548. Bind.pvDriverContext = _pvDriverContext;
  549. Bind.dwEpoch = _dwEpoch;
  550. Status = NtDeviceIoControlFile(_hDriver,
  551. NULL,
  552. NULL,
  553. NULL,
  554. &IoStatusBlock,
  555. IOCTL_CLEAR_INTERFACE_BINDING,
  556. (PVOID)&Bind,
  557. sizeof(Bind),
  558. (PVOID)&Bind,
  559. sizeof(Bind));
  560. if(NT_SUCCESS(Status))
  561. {
  562. _ClearBound();
  563. err = STATUS_SUCCESS;
  564. }
  565. else
  566. {
  567. err = icContainer.CoerceDriverError(Status);
  568. }
  569. _UnLock();
  570. return(err);
  571. }
  572. DWORD
  573. PacketFilterInterface::AddGlobalFilter(GLOBAL_FILTER gf)
  574. /*++
  575. Routine Description:
  576. Add the specified global filter to the interface
  577. --*/
  578. {
  579. PF_FILTER_DESCRIPTOR fd;
  580. DWORD err;
  581. FILTER_HANDLE fh;
  582. memset(&fd, 0, sizeof(fd));
  583. switch(gf)
  584. {
  585. default:
  586. //
  587. // fall through ...
  588. //
  589. case GF_FRAGCACHE:
  590. case GF_FRAGMENTS:
  591. case GF_STRONGHOST:
  592. err = _AddFilters((PFETYPE)gf, 1, &fd, 0, 0, &fh);
  593. break;
  594. }
  595. return(err);
  596. }
  597. DWORD
  598. PacketFilterInterface::DeleteGlobalFilter(GLOBAL_FILTER gf)
  599. /*++
  600. Routine Descriptor:
  601. Remove a global filter from this interface
  602. --*/
  603. {
  604. PF_FILTER_DESCRIPTOR fd;
  605. DWORD err;
  606. FILTER_HANDLE fh;
  607. memset(&fd, 0, sizeof(fd));
  608. switch(gf)
  609. {
  610. default:
  611. //
  612. // fall through ...
  613. //
  614. case GF_FRAGCACHE:
  615. case GF_FRAGMENTS:
  616. case GF_STRONGHOST:
  617. err = _DeleteFiltersByFilter((PFETYPE)gf, 1, &fd, 0, 0);
  618. break;
  619. }
  620. return(err);
  621. }
  622. DWORD
  623. PacketFilterInterface::DeleteFiltersByHandle(DWORD cHandles,
  624. PFILTER_HANDLE pvHandles)
  625. /*++
  626. Routine Description:
  627. Remove filters by handles returned when the filters were created
  628. --*/
  629. {
  630. IO_STATUS_BLOCK IoStatusBlock;
  631. NTSTATUS Status;
  632. DWORD dwSize = sizeof(PFDELETEBYHANDLE) - sizeof(PVOID) +
  633. (sizeof(PVOID) * cHandles);
  634. PPFDELETEBYHANDLE pDelHandle;
  635. DWORD err = NO_ERROR;
  636. pDelHandle = (PPFDELETEBYHANDLE)new PBYTE[dwSize];
  637. if(!pDelHandle)
  638. {
  639. return(GetLastError());
  640. }
  641. pDelHandle->pvDriverContext = _pvDriverContext;
  642. __try
  643. {
  644. memcpy(&pDelHandle->pvHandles[0],
  645. pvHandles,
  646. cHandles * sizeof(PVOID));
  647. }
  648. __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  649. {
  650. err = ERROR_INVALID_PARAMETER;
  651. delete pDelHandle;
  652. return(err);
  653. }
  654. Status = NtDeviceIoControlFile(_hDriver,
  655. NULL,
  656. NULL,
  657. NULL,
  658. &IoStatusBlock,
  659. IOCTL_PF_DELETE_BY_HANDLE,
  660. (PVOID)pDelHandle,
  661. dwSize,
  662. 0,
  663. 0);
  664. delete pDelHandle;
  665. if(NT_SUCCESS(Status))
  666. {
  667. err = ERROR_SUCCESS;
  668. }
  669. else
  670. {
  671. err = icContainer.CoerceDriverError(Status);
  672. }
  673. return(err);
  674. }
  675. PFILTER_DRIVER_SET_FILTERS
  676. PacketFilterInterface::_SetFilterBlock(
  677. PFETYPE pfe,
  678. DWORD cInFilters, PPF_FILTER_DESCRIPTOR pfiltIn,
  679. DWORD cOutFilters, PPF_FILTER_DESCRIPTOR pfiltOut,
  680. PDWORD pdwSize,
  681. PFILTER_DESCRIPTOR2 * ppfdIn,
  682. PFILTER_DESCRIPTOR2 * ppfdOut)
  683. /*++
  684. Routine Description:
  685. Private method to allocate and construct an argument block for
  686. setting or deleting filters. This is the heart of this code
  687. as it forms the data structure used for creating filters
  688. and for removing filters by descriptor.
  689. --*/
  690. {
  691. PFILTER_DRIVER_SET_FILTERS pSet;
  692. DWORD dwSetSize, dwInInfoSize, dwOutInfoSize;
  693. DWORD dwOutFilters, dwInFilters;
  694. PRTR_INFO_BLOCK_HEADER pIo;
  695. PFILTER_DESCRIPTOR2 p2;
  696. DWORD err = ERROR_SUCCESS;
  697. //
  698. // compute the memory size needed.
  699. //
  700. dwSetSize = sizeof(FILTER_DRIVER_SET_FILTERS) +
  701. sizeof(RTR_INFO_BLOCK_HEADER) +
  702. (ALIGN_SIZE - 1) + // worst case alignment padding
  703. (2 * sizeof(FILTER_DESCRIPTOR2));
  704. if(cInFilters)
  705. {
  706. dwInFilters = cInFilters;
  707. dwInInfoSize = sizeof(FILTER_INFOEX) * dwInFilters;
  708. dwSetSize += dwInInfoSize;
  709. dwInInfoSize += sizeof(FILTER_DESCRIPTOR2);
  710. }
  711. else
  712. {
  713. dwInInfoSize = sizeof(FILTER_DESCRIPTOR2);
  714. dwInFilters = 0;
  715. }
  716. if(cOutFilters)
  717. {
  718. dwOutFilters = cOutFilters;
  719. dwOutInfoSize = sizeof(FILTER_INFOEX) * dwOutFilters;
  720. dwSetSize += dwOutInfoSize;
  721. dwOutInfoSize += sizeof(FILTER_DESCRIPTOR2);
  722. }
  723. else
  724. {
  725. dwOutFilters = 0;
  726. dwOutInfoSize = sizeof(FILTER_DESCRIPTOR2);
  727. }
  728. if(dwSetSize == (sizeof(FILTER_DRIVER_SET_FILTERS) +
  729. sizeof(RTR_INFO_BLOCK_HEADER) +
  730. (2 * sizeof(FILTER_DESCRIPTOR2))) )
  731. {
  732. SetLastError(PFERROR_NO_FILTERS_GIVEN);
  733. return(NULL);
  734. }
  735. pSet = (PFILTER_DRIVER_SET_FILTERS)new PBYTE[dwSetSize];
  736. if(pSet)
  737. {
  738. *pdwSize = dwSetSize;
  739. //
  740. // create the argument block
  741. //
  742. pSet->pvDriverContext = _pvDriverContext;
  743. pIo = &pSet->ribhInfoBlock;
  744. pIo->Version = RTR_INFO_BLOCK_VERSION;
  745. pIo->Size = dwSetSize;
  746. pIo->TocEntriesCount = 2; // always two of these.
  747. //
  748. // create the ouput filter TOC first. No particular reason,
  749. // but one of them has to be first
  750. //
  751. pIo->TocEntry[0].InfoType = IP_FILTER_DRIVER_OUT_FILTER_INFO;
  752. pIo->TocEntry[0].InfoSize = dwOutInfoSize;
  753. pIo->TocEntry[0].Count = 1;
  754. //
  755. // the filters go after the header and TOCs
  756. //
  757. pIo->TocEntry[0].Offset = sizeof(RTR_INFO_BLOCK_HEADER) +
  758. sizeof(RTR_TOC_ENTRY);
  759. ALIGN_LENGTH(pIo->TocEntry[0].Offset);
  760. //
  761. // make the FILTER_DESCRIPTOR2 values
  762. //
  763. p2 = (PFILTER_DESCRIPTOR2)((PBYTE)pIo + pIo->TocEntry[0].Offset);
  764. *ppfdOut = p2;
  765. p2->dwVersion = 2;
  766. p2->dwNumFilters = dwOutFilters;
  767. while(cOutFilters--)
  768. {
  769. //
  770. // marshall each filter into the block
  771. //
  772. err = _MarshallFilter(pfe, pfiltOut++, &p2->fiFilter[cOutFilters]);
  773. if(err)
  774. {
  775. goto OuttaHere;
  776. }
  777. }
  778. //
  779. // now the input filters
  780. //
  781. pIo->TocEntry[1].InfoType = IP_FILTER_DRIVER_IN_FILTER_INFO;
  782. pIo->TocEntry[1].InfoSize = dwInInfoSize;
  783. pIo->TocEntry[1].Count = 1;
  784. //
  785. // the filters go after the header and TOCs
  786. //
  787. pIo->TocEntry[1].Offset = pIo->TocEntry[0].Offset +
  788. dwOutInfoSize;
  789. p2 = (PFILTER_DESCRIPTOR2)((PBYTE)pIo + pIo->TocEntry[1].Offset);
  790. *ppfdIn = p2;
  791. p2->dwVersion = 2;
  792. p2->dwNumFilters = dwInFilters;
  793. while(cInFilters--)
  794. {
  795. //
  796. // marshall each filter into the block
  797. //
  798. err = _MarshallFilter(pfe, pfiltIn++, &p2->fiFilter[cInFilters]);
  799. if(err)
  800. {
  801. break;
  802. }
  803. }
  804. }
  805. OuttaHere:
  806. if(err && pSet)
  807. {
  808. delete pSet;
  809. pSet = 0;
  810. SetLastError(err);
  811. }
  812. return(pSet);
  813. }
  814. DWORD
  815. PacketFilterInterface::_MarshallFilter(
  816. PFETYPE pfe,
  817. PPF_FILTER_DESCRIPTOR pFilt,
  818. PFILTER_INFOEX pInfo)
  819. /*++
  820. RoutineDescription:
  821. Converts an API version of a filter into a driver version
  822. --*/
  823. {
  824. DWORD err = NO_ERROR;
  825. __try
  826. {
  827. pInfo->type = pfe;
  828. pInfo->dwFlags = (pFilt->dwFilterFlags & FD_FLAGS_ALLFLAGS) |
  829. FLAGS_INFOEX_ALLOWDUPS |
  830. FLAGS_INFOEX_ALLOWANYREMOTEADDRESS |
  831. FLAGS_INFOEX_ALLOWANYLOCALADDRESS;
  832. pInfo->info.addrType = IPV4;
  833. pInfo->dwFilterRule = pFilt->dwRule;
  834. pInfo->info.dwProtocol = pFilt->dwProtocol;
  835. pInfo->info.fLateBound = pFilt->fLateBound;
  836. pInfo->info.wSrcPort = pFilt->wSrcPort;
  837. pInfo->info.wDstPort = pFilt->wDstPort;
  838. pInfo->info.wSrcPortHigh = pFilt->wSrcPortHighRange;
  839. pInfo->info.wDstPortHigh = pFilt->wDstPortHighRange;
  840. if ((pfe == PFE_SYNORFRAG) || (pfe == PFE_STRONGHOST) || (pfe == PFE_FRAGCACHE)) {
  841. pInfo->info.dwaSrcAddr[0] = 0;
  842. pInfo->info.dwaSrcMask[0] = 0;
  843. pInfo->info.dwaDstAddr[0] = 0;
  844. pInfo->info.dwaDstMask[0] = 0;
  845. return(ERROR_SUCCESS);
  846. }
  847. //
  848. // mow the addresses
  849. //
  850. pInfo->info.dwaSrcAddr[0] = *(PDWORD)pFilt->SrcAddr;
  851. pInfo->info.dwaSrcMask[0] = *(PDWORD)pFilt->SrcMask;
  852. pInfo->info.dwaDstAddr[0] = *(PDWORD)pFilt->DstAddr;
  853. pInfo->info.dwaDstMask[0] = *(PDWORD)pFilt->DstMask;
  854. err = ERROR_SUCCESS;
  855. }
  856. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  857. {
  858. err = ERROR_INVALID_PARAMETER;
  859. }
  860. return(err);
  861. }
  862. DWORD
  863. PacketFilterInterface::_AddFilters(
  864. PFETYPE pfe,
  865. DWORD cInFilters, PPF_FILTER_DESCRIPTOR pfiltIn,
  866. DWORD cOutFilters, PPF_FILTER_DESCRIPTOR pfiltOut,
  867. PFILTER_HANDLE pfHandle)
  868. /*++
  869. Routine Description:
  870. Private member function to add filters to an interface.
  871. --*/
  872. {
  873. PFILTER_DRIVER_SET_FILTERS pSet;
  874. IO_STATUS_BLOCK IoStatusBlock;
  875. NTSTATUS Status;
  876. DWORD dwSize, err;
  877. PFILTER_DESCRIPTOR2 pfdInput, pfdOutput;
  878. //
  879. // Check the handles before using them, if the memory supplied is
  880. // not accessible, we will save the trouble of calling the IOCTL.
  881. //
  882. if (pfHandle) {
  883. if (IsBadWritePtr(
  884. pfHandle,
  885. sizeof(FILTER_HANDLE)*(cInFilters+cOutFilters)
  886. )
  887. ) {
  888. return(ERROR_INVALID_PARAMETER);
  889. }
  890. }
  891. pSet = _SetFilterBlock(pfe,
  892. cInFilters,
  893. pfiltIn,
  894. cOutFilters,
  895. pfiltOut,
  896. &dwSize,
  897. &pfdInput,
  898. &pfdOutput);
  899. if(!pSet)
  900. {
  901. return(GetLastError());
  902. }
  903. //
  904. // ready to apply the filters.
  905. //
  906. Status = NtDeviceIoControlFile(_hDriver,
  907. NULL,
  908. NULL,
  909. NULL,
  910. &IoStatusBlock,
  911. IOCTL_SET_INTERFACE_FILTERS_EX,
  912. (PVOID)pSet,
  913. dwSize,
  914. (PVOID)pSet,
  915. dwSize);
  916. if(NT_SUCCESS(Status))
  917. {
  918. //
  919. // did it. If the caller wants the generated handles
  920. // copy them before freeing the buffer
  921. //
  922. if(pfHandle)
  923. {
  924. _CopyFilterHandles(pfdInput, pfdOutput, pfHandle);
  925. }
  926. err = ERROR_SUCCESS;
  927. }
  928. else
  929. {
  930. err = icContainer.CoerceDriverError(Status);
  931. }
  932. _FreeSetBlock(pSet);
  933. return(err);
  934. }
  935. DWORD
  936. PacketFilterInterface::_DeleteFiltersByFilter(PFETYPE pfe,
  937. DWORD cInFilters, PPF_FILTER_DESCRIPTOR pfiltIn,
  938. DWORD cOutFilters, PPF_FILTER_DESCRIPTOR pfiltOut)
  939. /*++
  940. Routine Description:
  941. Private method to delete filters using filter descriptors
  942. instead of handles. Very slow.
  943. --*/
  944. {
  945. PFILTER_DRIVER_SET_FILTERS pSet;
  946. IO_STATUS_BLOCK IoStatusBlock;
  947. NTSTATUS Status;
  948. DWORD dwSize, err;
  949. PFILTER_DESCRIPTOR2 pfdInput, pfdOutput;
  950. pSet = _SetFilterBlock(pfe,
  951. cInFilters,
  952. pfiltIn,
  953. cOutFilters,
  954. pfiltOut,
  955. &dwSize,
  956. &pfdInput,
  957. &pfdOutput);
  958. if(!pSet)
  959. {
  960. return(GetLastError());
  961. }
  962. //
  963. // ready to apply the filters.
  964. //
  965. Status = NtDeviceIoControlFile(_hDriver,
  966. NULL,
  967. NULL,
  968. NULL,
  969. &IoStatusBlock,
  970. IOCTL_DELETE_INTERFACE_FILTERS_EX,
  971. (PVOID)pSet,
  972. dwSize,
  973. (PVOID)pSet,
  974. dwSize);
  975. if(NT_SUCCESS(Status))
  976. {
  977. err = ERROR_SUCCESS;
  978. }
  979. else
  980. {
  981. err = icContainer.CoerceDriverError(Status);
  982. }
  983. _FreeSetBlock(pSet);
  984. return(err);
  985. }
  986. VOID
  987. PacketFilterInterface::_CopyFilterHandles(PFILTER_DESCRIPTOR2 pfd1,
  988. PFILTER_DESCRIPTOR2 pfd2,
  989. PFILTER_HANDLE pfHandle)
  990. /*++
  991. Routine Description
  992. Copy the generated filter handles from the pSet to the pfHandle.
  993. Called after successfully setting filters.
  994. --*/
  995. {
  996. DWORD dwFilters;
  997. for(dwFilters = pfd1->dwNumFilters; dwFilters;)
  998. {
  999. *pfHandle++ = pfd1->fiFilter[--dwFilters].pvFilterHandle;
  1000. }
  1001. for(dwFilters = pfd2->dwNumFilters; dwFilters;)
  1002. {
  1003. *pfHandle++ = pfd2->fiFilter[--dwFilters].pvFilterHandle;
  1004. }
  1005. }
  1006. DWORD
  1007. PacketFilterInterface::RebindFilters(PPF_LATEBIND_INFO pLateBindInfo)
  1008. /*++
  1009. Routine Description:
  1010. Public method to adjust filter values for switched interface
  1011. --*/
  1012. {
  1013. FILTER_DRIVER_BINDING_INFO Info;
  1014. IO_STATUS_BLOCK IoStatusBlock;
  1015. NTSTATUS Status;
  1016. _Lock(); // serialize this
  1017. Info.pvDriverContext = _pvDriverContext;
  1018. Info.dwLocalAddr = *(PDWORD)pLateBindInfo->SrcAddr;
  1019. Info.dwRemoteAddr = *(PDWORD)pLateBindInfo->DstAddr;
  1020. Info.dwMask = *(PDWORD)pLateBindInfo->Mask;
  1021. Status = NtDeviceIoControlFile(_hDriver,
  1022. NULL,
  1023. NULL,
  1024. NULL,
  1025. &IoStatusBlock,
  1026. IOCTL_SET_LATE_BOUND_FILTERSEX,
  1027. (PVOID)&Info,
  1028. sizeof(Info),
  1029. (PVOID)&Info,
  1030. sizeof(Info));
  1031. _UnLock();
  1032. if(NT_SUCCESS(Status))
  1033. {
  1034. return(ERROR_SUCCESS);
  1035. }
  1036. return(icContainer.CoerceDriverError(Status));
  1037. }
  1038. DWORD
  1039. PacketFilterInterface::TestPacket(
  1040. PacketFilterInterface * pInInterface,
  1041. PacketFilterInterface * pOutInterface,
  1042. DWORD cBytes,
  1043. PBYTE pbPacket,
  1044. PPFFORWARD_ACTION ppAction)
  1045. /*++
  1046. Routine Description:
  1047. Public method to do a test packet operation. Note this is just
  1048. passed to any interface.
  1049. --*/
  1050. {
  1051. PFILTER_DRIVER_TEST_PACKET Packet;
  1052. IO_STATUS_BLOCK IoStatusBlock;
  1053. NTSTATUS Status;
  1054. DWORD err, dwSize;
  1055. if (cBytes > MAXUSHORT)
  1056. {
  1057. return(ERROR_INVALID_PARAMETER);
  1058. }
  1059. //
  1060. // Get some data.
  1061. //
  1062. Packet = (PFILTER_DRIVER_TEST_PACKET) new BYTE[cBytes +
  1063. sizeof(FILTER_DRIVER_TEST_PACKET) - 1];
  1064. if(!Packet)
  1065. {
  1066. return(GetLastError());
  1067. }
  1068. if(pInInterface)
  1069. {
  1070. Packet->pvInInterfaceContext = pInInterface->GetDriverContext();
  1071. }
  1072. else
  1073. {
  1074. Packet->pvInInterfaceContext = 0;
  1075. }
  1076. if(pOutInterface)
  1077. {
  1078. Packet->pvOutInterfaceContext = pOutInterface->GetDriverContext();
  1079. }
  1080. else
  1081. {
  1082. Packet->pvOutInterfaceContext = 0;
  1083. }
  1084. __try
  1085. {
  1086. memcpy(Packet->bIpPacket, pbPacket, cBytes);
  1087. }
  1088. __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  1089. {
  1090. delete Packet;
  1091. return(ERROR_INVALID_PARAMETER);
  1092. }
  1093. dwSize = cBytes + FIELD_OFFSET(FILTER_DRIVER_TEST_PACKET, bIpPacket[0]);
  1094. Status = NtDeviceIoControlFile(_hDriver,
  1095. NULL,
  1096. NULL,
  1097. NULL,
  1098. &IoStatusBlock,
  1099. IOCTL_TEST_PACKET,
  1100. (PVOID)Packet,
  1101. dwSize,
  1102. (PVOID)Packet,
  1103. dwSize);
  1104. if(NT_SUCCESS(Status))
  1105. {
  1106. *ppAction = (PFFORWARD_ACTION)Packet->eaResult;
  1107. err = ERROR_SUCCESS;
  1108. }
  1109. else
  1110. {
  1111. err = icContainer.CoerceDriverError(Status);
  1112. }
  1113. delete Packet;
  1114. return(err);
  1115. }
  1116. DWORD
  1117. PacketFilterInterface::GetStatistics(
  1118. PPF_INTERFACE_STATS ppfStats,
  1119. PDWORD pdwBufferSize,
  1120. BOOL fResetCounters)
  1121. /*++
  1122. Routine Description:
  1123. Get the interface statistics, including information on
  1124. the filters. Because the WIN32 form of this differs
  1125. from the underlying form, this code must allocate
  1126. memory to use to store the driver's version of this and
  1127. then marshall the results in the user's buffer.
  1128. --*/
  1129. {
  1130. PBYTE pbBuffer = NULL;
  1131. PPFGETINTERFACEPARAMETERS pfGetip;
  1132. DWORD dwipSize, err = NO_ERROR;
  1133. NTSTATUS Status;
  1134. IO_STATUS_BLOCK IoStatusBlock;
  1135. __try
  1136. {
  1137. if(*pdwBufferSize < _IfBaseSize())
  1138. {
  1139. //
  1140. // the caller must supply at least this much.
  1141. //
  1142. *pdwBufferSize = _IfBaseSize();
  1143. err = PFERROR_BUFFER_TOO_SMALL;
  1144. }
  1145. }
  1146. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  1147. {
  1148. err = ERROR_INVALID_PARAMETER;
  1149. }
  1150. if (err != NO_ERROR)
  1151. {
  1152. goto Cleanup;
  1153. }
  1154. dwipSize = _IpSizeFromifSize(*pdwBufferSize);
  1155. pbBuffer = new BYTE[dwipSize];
  1156. if(!pbBuffer)
  1157. {
  1158. return(GetLastError());
  1159. }
  1160. //
  1161. // make the arguments
  1162. //
  1163. pfGetip = (PPFGETINTERFACEPARAMETERS)pbBuffer;
  1164. pfGetip->dwReserved = dwipSize;
  1165. pfGetip->pvDriverContext = _pvDriverContext;
  1166. pfGetip->dwFlags = GET_FLAGS_FILTERS;
  1167. if(fResetCounters)
  1168. {
  1169. pfGetip->dwFlags |= GET_FLAGS_RESET;
  1170. }
  1171. Status = NtDeviceIoControlFile(_hDriver,
  1172. NULL,
  1173. NULL,
  1174. NULL,
  1175. &IoStatusBlock,
  1176. IOCTL_PF_GET_INTERFACE_PARAMETERS,
  1177. (PVOID)pfGetip,
  1178. dwipSize,
  1179. (PVOID)pfGetip,
  1180. dwipSize);
  1181. if(!NT_SUCCESS(Status))
  1182. {
  1183. err = icContainer.CoerceDriverError(Status);
  1184. }
  1185. else if(pfGetip->dwReserved != dwipSize)
  1186. {
  1187. //
  1188. // Here when the user buffer is insufficient. Compute
  1189. // the size needed and return the characteristic error.
  1190. // Always return the common statistics
  1191. //
  1192. __try
  1193. {
  1194. _MarshallCommonStats(ppfStats, pfGetip);
  1195. }
  1196. __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  1197. {
  1198. err = ERROR_INVALID_PARAMETER;
  1199. }
  1200. *pdwBufferSize = _IfSizeFromipSize((ULONG)pfGetip->dwReserved);
  1201. err = ERROR_INSUFFICIENT_BUFFER;
  1202. }
  1203. else
  1204. {
  1205. DWORD i, dwFiltersReturned;
  1206. PDWORD pdwAddressOffset;
  1207. //
  1208. // got some data. Need to marshall the result into
  1209. // the user's buffer do the easy part
  1210. //
  1211. __try
  1212. {
  1213. _MarshallCommonStats(ppfStats, pfGetip);
  1214. //
  1215. // Get the number of filters returned
  1216. //
  1217. dwFiltersReturned = pfGetip->dwNumInFilters +
  1218. pfGetip->dwNumOutFilters;
  1219. pdwAddressOffset = (PDWORD)((PBYTE)ppfStats +
  1220. _IfBaseSize() +
  1221. (sizeof(PF_FILTER_STATS) *
  1222. dwFiltersReturned));
  1223. //
  1224. // marshall each filter back to the user.
  1225. //
  1226. for(i = 0; i < dwFiltersReturned; i++)
  1227. {
  1228. _MarshallStatFilter(&pfGetip->FilterInfo[i],
  1229. &ppfStats->FilterInfo[i],
  1230. &pdwAddressOffset);
  1231. }
  1232. }
  1233. __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  1234. {
  1235. err = ERROR_INVALID_PARAMETER;
  1236. }
  1237. }
  1238. Cleanup:
  1239. if (pbBuffer) delete pbBuffer;
  1240. return(err);
  1241. }
  1242. VOID
  1243. PacketFilterInterface::_MarshallStatFilter(PFILTER_STATS_EX pstat,
  1244. PPF_FILTER_STATS pfstats,
  1245. PDWORD * ppdwAddress)
  1246. /*++
  1247. Routine Description:
  1248. Private method to marshall a driver supplied filter stats to
  1249. an API form of it.
  1250. --*/
  1251. {
  1252. PDWORD pdwSpace = *ppdwAddress;
  1253. pfstats->dwNumPacketsFiltered = pstat->dwNumPacketsFiltered;
  1254. pfstats->info.dwFilterFlags = 0;
  1255. pfstats->info.dwRule = pstat->info.dwFilterRule;
  1256. pfstats->info.pfatType = PF_IPV4;
  1257. pfstats->info.dwProtocol = pstat->info.info.dwProtocol;
  1258. pfstats->info.fLateBound = pstat->info.info.fLateBound;
  1259. pfstats->info.wSrcPort = pstat->info.info.wSrcPort;
  1260. pfstats->info.wDstPort = pstat->info.info.wDstPort;
  1261. pfstats->info.wSrcPortHighRange = pstat->info.info.wSrcPortHigh;
  1262. pfstats->info.wDstPortHighRange = pstat->info.info.wDstPortHigh;
  1263. pfstats->info.SrcAddr = (PBYTE)pdwSpace;
  1264. *pdwSpace++ = pstat->info.info.dwaSrcAddr[0];
  1265. pfstats->info.SrcMask = (PBYTE)pdwSpace;
  1266. *pdwSpace++ = pstat->info.info.dwaSrcMask[0];
  1267. pfstats->info.DstAddr = (PBYTE)pdwSpace;
  1268. *pdwSpace++ = pstat->info.info.dwaDstAddr[0];
  1269. pfstats->info.DstMask = (PBYTE)pdwSpace;
  1270. *pdwSpace++ = pstat->info.info.dwaDstMask[0];
  1271. *ppdwAddress = pdwSpace;
  1272. }
  1273. VOID
  1274. InitFilterApis()
  1275. {
  1276. icContainer.InitInterfaceContainer();
  1277. }
  1278. VOID
  1279. UnInitFilterApis()
  1280. {
  1281. icContainer.UnInitInterfaceContainer();
  1282. }
  1283. DWORD StartIpFilterDriver(VOID)
  1284. {
  1285. SC_HANDLE schSCManager;
  1286. SC_HANDLE schService;
  1287. DWORD dwErr = NO_ERROR;
  1288. BOOL bSuccess;
  1289. TCHAR *DriverName = TEXT("IPFILTERDRIVER");
  1290. schSCManager =
  1291. OpenSCManager(
  1292. NULL, // machine (NULL == local)
  1293. NULL, // database (NULL == default)
  1294. SC_MANAGER_ALL_ACCESS // access required
  1295. );
  1296. if (!schSCManager) {
  1297. return(GetLastError());
  1298. }
  1299. schService =
  1300. OpenService(
  1301. schSCManager,
  1302. DriverName,
  1303. SERVICE_ALL_ACCESS
  1304. );
  1305. if (!schService) {
  1306. CloseServiceHandle(schSCManager);
  1307. return(GetLastError());
  1308. }
  1309. bSuccess =
  1310. StartService(
  1311. schService,
  1312. 0,
  1313. NULL
  1314. );
  1315. CloseServiceHandle(schService);
  1316. CloseServiceHandle(schSCManager);
  1317. if (!bSuccess) {
  1318. dwErr = GetLastError();
  1319. if (dwErr == ERROR_SERVICE_ALREADY_RUNNING) {
  1320. return(NO_ERROR);
  1321. }
  1322. }
  1323. return(dwErr);
  1324. }
  1325. BOOL
  1326. ValidateIndex(DWORD dwIndex)
  1327. {
  1328. DWORD i, err;
  1329. PMIB_IPADDRTABLE pTable;
  1330. err = AllocateAndGetIpAddrTableFromStack(&pTable,
  1331. FALSE,
  1332. GetProcessHeap(),
  1333. 0);
  1334. if (err != NO_ERROR) {
  1335. return FALSE;
  1336. }
  1337. for (i = 0; i < pTable->dwNumEntries; i++) {
  1338. if (pTable->table[i].dwIndex == dwIndex) {
  1339. HeapFree(GetProcessHeap(),
  1340. 0,
  1341. pTable);
  1342. return TRUE;
  1343. }
  1344. }
  1345. HeapFree(GetProcessHeap(),
  1346. 0,
  1347. pTable);
  1348. return FALSE;
  1349. }
  1350. #endif // CHICAGO