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.

538 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Implementation of the packet filter control code
  6. Revision History:
  7. Author:
  8. Arnold Miller (ArnoldM) 24-Sept-1997
  9. --*/
  10. #ifndef CHICAGO // don't need this on Memphis
  11. #include "fltapis.hxx"
  12. extern InterfaceContainer icContainer;
  13. //
  14. // The WIN32 APIs. These are wrappers to call the
  15. // appropriate class methods.
  16. //
  17. PFAPIENTRY
  18. PfCreateInterface(
  19. DWORD dwName,
  20. PFFORWARD_ACTION inAction,
  21. PFFORWARD_ACTION outAction,
  22. BOOL bUseLog,
  23. BOOL bMustBeUnique,
  24. INTERFACE_HANDLE *ppInterface)
  25. /*++
  26. Routine Description:
  27. Create a new interface.
  28. dwName -- the interface name. A 0 means a new, unique interface. Any
  29. other value is a potentially shared interface. Note that
  30. the argument bMustBeUnique can turn a shared interface
  31. into a unique one. But by using that, this call can fail.
  32. inAction -- default action for input frame.
  33. outAction -- default action for output frames
  34. bUseLog -- If there is a log, bind it to this interface
  35. bMustBeUnique -- if TRUE, this interface cannot be shared
  36. ppInterface -- if successful, the interface handle to be used
  37. on subsequent operations.
  38. --*/
  39. {
  40. return(icContainer.AddInterface(
  41. dwName,
  42. inAction,
  43. outAction,
  44. bUseLog,
  45. bMustBeUnique,
  46. ppInterface));
  47. }
  48. PFAPIENTRY
  49. PfDeleteInterface(
  50. INTERFACE_HANDLE pInterface)
  51. /*++
  52. Routine Description:
  53. Delete an interface
  54. pInterface -- the interface handle gotten from PfCreateInterface
  55. --*/
  56. {
  57. return(icContainer.DeleteInterface(pInterface));
  58. }
  59. PFAPIENTRY
  60. PfAddFiltersToInterface(INTERFACE_HANDLE pInterface,
  61. DWORD cInFilters, PPF_FILTER_DESCRIPTOR pfiltIn,
  62. DWORD cOutFilters, PPF_FILTER_DESCRIPTOR pfiltOut,
  63. PFILTER_HANDLE pfHandle OPTIONAL)
  64. /*++
  65. Routine Description:
  66. Add the described filters to the interface.
  67. cInFilters -- number of input filters
  68. cOutFilters -- number of output filters
  69. pfiltIn -- array of input filters if any
  70. pfiltOut -- array of output filters if any
  71. pfHandle -- array to return filter handeles.
  72. --*/
  73. {
  74. PacketFilterInterface * pif;
  75. DWORD err;
  76. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  77. if(err == ERROR_SUCCESS)
  78. {
  79. err = pif->AddFilters(cInFilters, pfiltIn,
  80. cOutFilters, pfiltOut,
  81. pfHandle);
  82. icContainer.Deref();
  83. }
  84. return(err);
  85. }
  86. PFAPIENTRY
  87. PfRemoveFiltersFromInterface(INTERFACE_HANDLE pInterface,
  88. DWORD cInFilters, PPF_FILTER_DESCRIPTOR pfiltIn,
  89. DWORD cOutFilters, PPF_FILTER_DESCRIPTOR pfiltOut)
  90. /*++
  91. Routine Description:
  92. Remove the described filters to the interface.
  93. cInFilters -- number of input filters
  94. cOutFilters -- number of output filters
  95. pfiltIn -- array of input filters if any
  96. pfiltOut -- array of output filters if any
  97. --*/
  98. {
  99. PacketFilterInterface * pif;
  100. DWORD err;
  101. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  102. if(err == ERROR_SUCCESS)
  103. {
  104. err = pif->DeleteFiltersByFilter(cInFilters, pfiltIn,
  105. cOutFilters, pfiltOut);
  106. icContainer.Deref();
  107. }
  108. return(err);
  109. }
  110. PFAPIENTRY
  111. PfRemoveFilterHandles( INTERFACE_HANDLE pInterface,
  112. DWORD cFilters, PFILTER_HANDLE pvHandles)
  113. /*++
  114. Routine Description:
  115. Add the described filters to the interface.
  116. cFilters -- number of filter handles provided. These
  117. are obtained from the PfAddFiltersToInterface call
  118. pvHandles -- array of handles
  119. --*/
  120. {
  121. PacketFilterInterface * pif;
  122. DWORD err;
  123. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  124. if(err == ERROR_SUCCESS)
  125. {
  126. err = pif->DeleteFiltersByHandle(cFilters, pvHandles);
  127. icContainer.Deref();
  128. }
  129. return(err);
  130. }
  131. PFAPIENTRY
  132. PfAddGlobalFilterToInterface(INTERFACE_HANDLE pInterface,
  133. GLOBAL_FILTER gfFilter)
  134. /*++
  135. Routine Description:
  136. Put a global filter on the specified interface
  137. --*/
  138. {
  139. PacketFilterInterface * pif;
  140. DWORD err;
  141. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  142. if(err == ERROR_SUCCESS)
  143. {
  144. err = pif->AddGlobalFilter(gfFilter);
  145. icContainer.Deref();
  146. }
  147. return(err);
  148. }
  149. PFAPIENTRY
  150. PfRemoveGlobalFilterFromInterface(INTERFACE_HANDLE pInterface,
  151. GLOBAL_FILTER gfFilter)
  152. /*++
  153. Routine Description:
  154. Remove the specified global filter from the interface
  155. --*/
  156. {
  157. PacketFilterInterface * pif;
  158. DWORD err;
  159. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  160. if(err == ERROR_SUCCESS)
  161. {
  162. err = pif->DeleteGlobalFilter(gfFilter);
  163. icContainer.Deref();
  164. }
  165. return(err);
  166. }
  167. PFAPIENTRY
  168. PfUnBindInterface(INTERFACE_HANDLE pInterface)
  169. /*++
  170. Routine Description:
  171. Unbound a bound interface.
  172. --*/
  173. {
  174. PacketFilterInterface * pif;
  175. DWORD err;
  176. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  177. if(err == ERROR_SUCCESS)
  178. {
  179. err = pif->UnBindInterface();
  180. icContainer.Deref();
  181. }
  182. return(err);
  183. }
  184. PFAPIENTRY
  185. PfBindInterfaceToIndex(INTERFACE_HANDLE pInterface,
  186. DWORD dwIndex,
  187. PFADDRESSTYPE pfatLinkType,
  188. PBYTE LinkIPAddress)
  189. /*++
  190. Routine Description:
  191. Bind an interface to the given IP stack index
  192. --*/
  193. {
  194. PacketFilterInterface * pif;
  195. DWORD err;
  196. DWORD LinkAddress;
  197. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  198. if(err == ERROR_SUCCESS)
  199. {
  200. if (ValidateIndex(dwIndex))
  201. {
  202. __try
  203. {
  204. LinkAddress = *(PDWORD)LinkIPAddress;
  205. }
  206. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  207. {
  208. err = ERROR_INVALID_PARAMETER;
  209. }
  210. if ((err == ERROR_SUCCESS) &&
  211. (LinkAddress && (pfatLinkType != PF_IPV4)))
  212. {
  213. err = ERROR_INVALID_PARAMETER;
  214. }
  215. if (err == ERROR_SUCCESS)
  216. {
  217. err = pif->BindByIndex(dwIndex, LinkAddress);
  218. }
  219. }
  220. else
  221. {
  222. err = ERROR_INVALID_PARAMETER;
  223. }
  224. icContainer.Deref();
  225. }
  226. return(err);
  227. }
  228. PFAPIENTRY
  229. PfBindInterfaceToIPAddress(INTERFACE_HANDLE pInterface,
  230. PFADDRESSTYPE pfatType,
  231. PBYTE IPAddress)
  232. /*++
  233. Routine Description:
  234. Bind an interface to the IP stack index having the given address
  235. --*/
  236. {
  237. PacketFilterInterface * pif;
  238. DWORD err = NO_ERROR;
  239. if(pfatType != PF_IPV4)
  240. {
  241. return(ERROR_INVALID_PARAMETER);
  242. }
  243. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  244. if(err == ERROR_SUCCESS)
  245. {
  246. __try
  247. {
  248. err = pif->BindByAddress(*(PDWORD)IPAddress);
  249. }
  250. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  251. {
  252. err = ERROR_INVALID_PARAMETER;
  253. }
  254. icContainer.Deref();
  255. }
  256. return(err);
  257. }
  258. PFAPIENTRY
  259. PfRebindFilters(INTERFACE_HANDLE pInterface,
  260. PPF_LATEBIND_INFO pLateBindInfo)
  261. /*++
  262. Routine Description:
  263. Rebind the filters on the given interface based on the rebind
  264. values in pfilt. What gets rebound depends on how the filter
  265. was created.
  266. --*/
  267. {
  268. PacketFilterInterface * pif;
  269. DWORD err = NO_ERROR;
  270. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  271. if(err == ERROR_SUCCESS)
  272. {
  273. __try
  274. {
  275. err = pif->RebindFilters(pLateBindInfo);
  276. }
  277. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  278. {
  279. err = ERROR_INVALID_PARAMETER;
  280. }
  281. icContainer.Deref();
  282. }
  283. return(err);
  284. }
  285. PFAPIENTRY
  286. PfMakeLog( HANDLE hEvent )
  287. /*++
  288. Routine Description:
  289. Make a log to be used by the interfaces. Note well that
  290. once an interface exists, a log cannot be retroactively applied.
  291. At most one log may exist.
  292. --*/
  293. {
  294. DWORD err;
  295. err = icContainer.MakeLog( hEvent );
  296. return(err);
  297. }
  298. PFAPIENTRY
  299. PfSetLogBuffer(
  300. PBYTE pbBuffer,
  301. DWORD dwSize,
  302. DWORD dwThreshold,
  303. DWORD dwEntries,
  304. PDWORD pdwLoggedEntries,
  305. PDWORD pdwLostEntries,
  306. PDWORD pdwSizeUsed)
  307. /*++
  308. Routine Description:
  309. Give a new log buffer to the log and get back the old one
  310. pbBuffer -- the new log buffer. Must be quad-word aligned
  311. dwSize -- size of the buffer in bytes
  312. dwThreahold -- number of bytes used before signalling the event
  313. dwEntries -- number of entries that causes the signalling
  314. pdwLoggedEntries -- entires in the old buffer
  315. pdwLostEntries -- entries that could not be put into the old buffer
  316. pdwSizeUsed -- total size used in the old buffer
  317. The last three are returned values. If there is no old buffer, then
  318. what is returned is undefined. Note this does not return
  319. the address of the old buffer. It is up to the caller to
  320. remember this. On success, the provided buffer is locked.
  321. Hence the caller should provide a buffer large enough to capture
  322. the traffic but so large as to be an impediment. A buffer of
  323. 128K, used in a double-buffer scheme with another of that size,
  324. has proven to be quite adequate. In fact, a smaller buffer is
  325. likely to be sufficient.
  326. --*/
  327. {
  328. DWORD err;
  329. err = icContainer.SetLogBuffer(
  330. pbBuffer,
  331. dwSize,
  332. dwThreshold,
  333. dwEntries,
  334. pdwLoggedEntries,
  335. pdwLostEntries,
  336. pdwSizeUsed);
  337. return(err);
  338. }
  339. PFAPIENTRY
  340. PfGetInterfaceStatistics(
  341. INTERFACE_HANDLE pInterface,
  342. PPF_INTERFACE_STATS ppfStats,
  343. PDWORD pdwBufferSize,
  344. BOOL fResetCounters)
  345. /*++
  346. Routine Description:
  347. Get statistics for an interface. There are two characteristic
  348. errors from this:
  349. ERROR_INSUFFICIENT_BUFFER -- the supplied user buffer is too
  350. small for the filters. The correct
  351. size is returned as is the
  352. interface statistics which contains
  353. the filter counts
  354. PFERROR_BUFFER_TOO_SMALL -- the user buffer is too small
  355. for even the interface statistics.
  356. The returned size is the size of
  357. the interface statistics but does
  358. not include space for filters. So the
  359. next call should get the first error.
  360. For now, ppfStatusV6 and pdwBufferSizeV6 MBZ. When IPV6
  361. is implemented, these will be allowed
  362. --*/
  363. {
  364. PacketFilterInterface * pif;
  365. DWORD err;
  366. err = icContainer.FindInterfaceAndRef(pInterface, &pif);
  367. if(err == ERROR_SUCCESS)
  368. {
  369. err = pif->GetStatistics(ppfStats,
  370. pdwBufferSize,
  371. fResetCounters);
  372. icContainer.Deref();
  373. }
  374. return(err);
  375. }
  376. PFAPIENTRY
  377. PfDeleteLog()
  378. /*++
  379. Routine Description:
  380. Delete the log. Will remove it from all of the interfaces and
  381. diable it.
  382. --*/
  383. {
  384. return(icContainer.DeleteLog());
  385. }
  386. PFAPIENTRY
  387. PfTestPacket( INTERFACE_HANDLE pInInterface,
  388. INTERFACE_HANDLE pOutInterface,
  389. DWORD cBytes,
  390. PBYTE pbPacket,
  391. PPFFORWARD_ACTION ppAction)
  392. /*++
  393. Routine Description:
  394. Given a packet and an interface, ask the driver what
  395. action it would take. If successful, return the
  396. action
  397. --*/
  398. {
  399. PacketFilterInterface * pifIn, *pifOut, *pif;
  400. DWORD err;
  401. if(pInInterface)
  402. {
  403. err = icContainer.FindInterfaceAndRef(pInInterface, &pifIn);
  404. }
  405. else
  406. {
  407. pifIn = 0;
  408. err = ERROR_SUCCESS;
  409. }
  410. if(err)
  411. {
  412. return(err);
  413. }
  414. pifOut = 0;
  415. if(pOutInterface)
  416. {
  417. err = icContainer.FindInterfaceAndRef(pOutInterface, &pifOut);
  418. }
  419. else
  420. {
  421. err = ERROR_SUCCESS;
  422. }
  423. if(!err && pifIn && (pifIn == pifOut))
  424. {
  425. //
  426. // the same interface is given for each. Can't be
  427. //
  428. err = ERROR_INVALID_PARAMETER;
  429. }
  430. if(err == ERROR_SUCCESS)
  431. {
  432. if(pifIn)
  433. {
  434. pif = pifIn;
  435. }
  436. else
  437. {
  438. pif = pifOut;
  439. }
  440. if(pif)
  441. {
  442. err = pif->TestPacket(
  443. pifIn,
  444. pifOut,
  445. cBytes,
  446. pbPacket,
  447. ppAction);
  448. }
  449. else
  450. {
  451. *ppAction = PF_ACTION_FORWARD;
  452. }
  453. }
  454. if(pifIn)
  455. {
  456. icContainer.Deref();
  457. }
  458. if(pifOut)
  459. {
  460. icContainer.Deref();
  461. }
  462. return(err);
  463. }
  464. #endif // CHICAGO