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

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