Compare commits
128 Commits
v1.1.1
...
flow_layer
| Author | SHA1 | Date | |
|---|---|---|---|
| 29c6fda167 | |||
| 54e627e82b | |||
| 8ff3c86330 | |||
| edbe5ea942 | |||
| 67ad628a1f | |||
| 312050accb | |||
| 0a74b5528c | |||
| 084c78e4af | |||
| 33a461eef6 | |||
| 3e40705178 | |||
| 1ccf486132 | |||
| 4f7ff88664 | |||
| 3966ec1287 | |||
| fc868feb3e | |||
| de4245f95e | |||
| 316765aa92 | |||
| 86db54b400 | |||
| 34e8f96910 | |||
| 5aa4fc3c46 | |||
| fd75e6d42a | |||
| 2ab1ddf1d2 | |||
| f0dd1224b1 | |||
| 6250568974 | |||
| e82552153b | |||
| 822dca9c3f | |||
| 8e44f26b0a | |||
| 6ac22c1650 | |||
| 061535f7a3 | |||
| 4ba359c86f | |||
| ae25f27469 | |||
| be153ac22b | |||
| 1543e958e6 | |||
| a67886e4b4 | |||
| bef2240d9e | |||
| e2106ea2c6 | |||
| 53845fa8a9 | |||
| 21f1e1a71e | |||
| af5cd69883 | |||
| fb68612176 | |||
| bc95ba96ee | |||
| 884622c5c7 | |||
| 347adf04ea | |||
| ba5e893f8f | |||
| dbb6b0fe60 | |||
| 80b31815b2 | |||
| aea3a3a858 | |||
| bbf6a34aa6 | |||
| 60c3a26e1c | |||
| 9ae77eb7a5 | |||
| 4c4f586f4d | |||
| d9fbc813f4 | |||
| b2fd7eb891 | |||
| 4ae5101d56 | |||
| bd4265897a | |||
| 65f366820a | |||
| 4d68983d25 | |||
| b4ee1f5b36 | |||
| 751ed975e3 | |||
| c4575b7059 | |||
| 10b8204ed4 | |||
| f5f3559ae9 | |||
| d778639cbe | |||
| 11b9a74341 | |||
| 2e1bfa8ca5 | |||
| 910a2e3050 | |||
| e69cc09cce | |||
| 7b7d92cd26 | |||
| 200da2fba1 | |||
| c13a27bb4f | |||
| ea95889a30 | |||
| f540e7cc02 | |||
| 504132080a | |||
| 135e084ef7 | |||
| 657f7fc197 | |||
| 3386987f6a | |||
| cd1bfff998 | |||
| 7cfc3e2e72 | |||
| bac03085ee | |||
| eda0a86589 | |||
| 657285bef6 | |||
| 723b0aa8f8 | |||
| f0be301f1d | |||
| 609ab63594 | |||
| 82fb0e704c | |||
| 3fcb692478 | |||
| 3bcf1ae7a0 | |||
| 54f8640b89 | |||
| a15df9b886 | |||
| 7666386af2 | |||
| 130e25c05b | |||
| fdd5825f5d | |||
| e247f01c43 | |||
| e1ea77f1d3 | |||
| 90da7a92c7 | |||
| a3026de69c | |||
| 232459cc11 | |||
| b452e1ce29 | |||
| bf19fdf2f9 | |||
| ecd9ae59d3 | |||
| 5eaf312730 | |||
| 48075e2e5f | |||
| 72d83fcb07 | |||
| 8d98da751c | |||
| 0a70d4120d | |||
| 4edd82f55f | |||
| 7235b687b3 | |||
| 7952724127 | |||
| d46a902c90 | |||
| bbf06c9503 | |||
| d43aa57014 | |||
| 50aecbda75 | |||
| 6b3fd714c0 | |||
| 7bd52aed76 | |||
| 5e706931f0 | |||
| 9a13606030 | |||
| 98c4a51fad | |||
| 874d147b9b | |||
| d5d8e163e3 | |||
| 4b708f0c16 | |||
| 7f0e697092 | |||
| 33f6bec1e5 | |||
| 57934712c6 | |||
| 4f81c315d6 | |||
| 76459ac3fe | |||
| 6ac77a644b | |||
| 08fef993ba | |||
| f21217fdb1 | |||
| 8c2bb01565 |
@@ -18,7 +18,7 @@ WinDivert 1.0.4
|
||||
WinDivert 1.0.5
|
||||
- Fix the DIVERT_NETWORK_FORWARD_LAYER implementation.
|
||||
- Upgrade Visual Studio support to 2012.
|
||||
WinDivert 1.1.0
|
||||
WinDivert 1.1.0-rc
|
||||
- Re-brand "DIVERT" to "WINDIVERT" throughout the code-base.
|
||||
- New flag:
|
||||
* WINDIVERT_FLAG_NO_CHECKSUM: Do not guarantee that diverted packets
|
||||
@@ -36,3 +36,96 @@ WinDivert 1.1.0
|
||||
load.
|
||||
WinDivert 1.1.1
|
||||
- Fixed a BSOD that sometimes occurs when the driver is unloaded.
|
||||
WinDivert 1.1.2-rc
|
||||
- Renamed drivers to "WinDivert32.sys" and "WinDivert64.sys". Both can
|
||||
exist in the same directory, and WinDivert.dll automatically loads the
|
||||
correct version.
|
||||
- Deprecate both the WinDivert.inf and WdfCoInstaller*.dll files.
|
||||
WinDivert 1.1.3
|
||||
- Fixed a bug that causes some outbound TCP packets to be lost.
|
||||
WinDivert 1.1.4
|
||||
- Fixed a BSOD that occurs when NULL is passed as the address parameter to
|
||||
WinDivertRecv(..) or WinDivertSend(..).
|
||||
WinDivert 1.1.5
|
||||
- Insert WinDivert as the highest priority WFP sublayer.
|
||||
WinDivert 1.1.6
|
||||
- WinDivert now searches for the driver files in the application's
|
||||
directory (as opposed to the current directory).
|
||||
WinDivert 1.1.7
|
||||
- Improved IPv6 support:
|
||||
* Fixed incorrect IPV6 TCP/UDP checksum calculation in
|
||||
WinDivertHelperCalcChecksums().
|
||||
* WinDivert driver now calculates checksums for IPV6 packets.
|
||||
* WinDivert can now handle IPV6 extension headers.
|
||||
* Fixed WinDivertHelperParseIPv6Address().
|
||||
WinDivert 1.1.8
|
||||
- Fix ip.TOS handling bug.
|
||||
- Fix IPv6 comparison bug.
|
||||
WinDivert 1.2.0-rc
|
||||
- The WinDivert filter language now supports C-style "(F1? F2: F3)"
|
||||
expressions, where {F1,F2,F3} are themselves filter expressions.
|
||||
- New WinDivert helper functions:
|
||||
* WinDivertHelperCheckFilter() checks if a filter string is valid.
|
||||
* WinDivertHelperEvalFilter() evaluates a filter on a packet.
|
||||
- Some packets (specifically outbound or loopback packets) returned by
|
||||
WinDivertRecv() or WinDivertRecvEx() are no longer required to have
|
||||
correct checksums. Absent checksum fields will be set to zero. If need
|
||||
be the checksums can be recovered by WinDivertHelperCalcChecksums().
|
||||
- The WINDIVERT_FLAG_NO_CHECKSUM flag has been deprecated.
|
||||
- The WinDivertHelperCalcChecksums() function now accepts a new
|
||||
WINDIVERT_HELPER_NO_REPLACE flag, which indicates that non-zero checksum
|
||||
fields should not be replaced.
|
||||
- Support for the old WinDivert1.0 API has been removed.
|
||||
WinDivert 1.2.1
|
||||
- Identical to WinDivert 1.2.0-rc.
|
||||
WinDivert 1.3.0
|
||||
- Fix BSOD that sometimes occurs after abnormal user application exit.
|
||||
- Fix BSOD that sometimes occurs when WinDivert is combined with other
|
||||
callout drivers.
|
||||
- WinDivertSend() has been optimized. However, it may not detect as
|
||||
many packet injection errors as it could before.
|
||||
WinDivert 1.4.0-rc
|
||||
- Add a new WINDIVERT_PARAM_QUEUE_SIZE parameter that can be used to
|
||||
control the maximum number of bytes used by the packet queue.
|
||||
- Add a new WINDIVERT_FLAG_DEBUG flag that causes WinDivertSend() to
|
||||
block until the packet exits the Windows TCP/IP stack. This is slower
|
||||
but provides better error messages, so is useful for debugging.
|
||||
- Internally queued packets are now reinjected when WinDivertClose() is
|
||||
called instead of being dropped.
|
||||
- WINDIVERT_ADDRESS now includes a Timestamp field that indicates when
|
||||
the packet was first captured by WinDivert. The timestamp uses the
|
||||
same clock as QueryPerformanceCounter().
|
||||
- WINDIVERT_ADDRESS now includes a Loopback field that indicates whether
|
||||
the packet is a loopback packet or not.
|
||||
- The filter language has been extended to include a loopback field that
|
||||
matches loopback packets.
|
||||
- Loopback packets are now considered to be outbound-only.
|
||||
- WINDIVERT_ADDRESS now includes an Impostor field which indicates that the
|
||||
packet originated from another driver rather than from the network or
|
||||
TCP/IP stack.
|
||||
- WinDivertRecv() will eventually fail with ERROR_HOST_UNREACHABLE if
|
||||
an impostor packet enters an infinite loop (see #41).
|
||||
- The filter language has been extended to include an impostor field that
|
||||
matches impostor packets.
|
||||
- WINDIVERT_ADDRESS now includes three new flags relating to checksums:
|
||||
* PseudoIPChecksum
|
||||
* PseudoTCPChecksum
|
||||
* PseudoUDPChecksum
|
||||
When set, these flags indicate that the corresponding packet uses
|
||||
"pseudo" IP/TCP/UDP checksums instead of the default full checksums.
|
||||
Pseudo checksums are cheaper to calculate, and can be used when the
|
||||
network hardware supports checksum offloading.
|
||||
- WinDivertHelperCalcChecksums() now takes an optional pointer to a
|
||||
WINDIVERT_ADDRESS structure, and calculates pseudo checksums if the
|
||||
corresponding Pseudo*Checksum flag is set.
|
||||
- The WINDIVERT_HELPER_NO_REPLACE flag for WinDivertHelperCalcChecksums()
|
||||
has been deprecated. It is no longer necessary to calculate checksums
|
||||
for unmodified packets.
|
||||
WinDivert 1.4.1
|
||||
- Dual license WinDivert under LGPLv3 and GPLv2.
|
||||
WinDivert 1.4.2
|
||||
- Add workaround for pseudo checksum issue (see #134).
|
||||
WinDivert 1.4.3
|
||||
- WinDivert.dll no longer depends on MSVCRT*.dll.
|
||||
WinDivert 1.4.4
|
||||
- Optimize pseudo checksum calculation.
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
WinDivert is dual-licensed under your choice of the GNU Lesser General Public
|
||||
License (LGPL) Version 3 or the GNU General Public License (GPL) Version 2.
|
||||
Copies of the LGPLv3, GPLv3 and GPLv2 are provided below.
|
||||
|
||||
==============================================================================
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -164,12 +170,12 @@ apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
==============================================================================
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -785,3 +791,401 @@ reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
==============================================================================
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
|
||||
@@ -1,51 +1,36 @@
|
||||
WinDivert 1.1: Windows Packet Divert
|
||||
WinDivert 2.0: Windows Packet Divert
|
||||
====================================
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
Windows Packet Divert (WinDivert) is a user-mode packet capture-and-divert
|
||||
package for Windows Vista, Windows 2008, Windows 7, and Windows 8.
|
||||
Windows Packet Divert (WinDivert) is a user-mode packet interception library
|
||||
for Windows 7, Windows 8 and Windows 10.
|
||||
|
||||
With WinDivert developers can write user-mode programs that capture and
|
||||
modify or drop network packets sent to/from the Windows network stack.
|
||||
In summary, WinDivert can
|
||||
WinDivert enables user-mode capturing/modifying/dropping of network packets
|
||||
sent to/from the Windows network stack. In summary, WinDivert can:
|
||||
- capture network packets
|
||||
- filter/drop network packets
|
||||
- sniff network packets
|
||||
- (re)inject network packets
|
||||
- modify network packets
|
||||
WinDivert can be used to implement user-mode packet filters, sniffers,
|
||||
firewalls, NATs, VPNs, IDSs, tunneling applications, etc..
|
||||
|
||||
WinDivert can be used to implement user-mode packet filters, packet sniffers,
|
||||
firewalls, NAT, VPNs, tunneling applications, etc., etc.. If you
|
||||
need to intercept and modify packets, then WinDivert is for you.
|
||||
|
||||
The features of WinDivert include:
|
||||
WinDivert supports the following features:
|
||||
- packet interception, sniffing, or dropping modes
|
||||
- support for loopback (localhost) traffic
|
||||
- full IPv6 support
|
||||
- network layer
|
||||
- simple and powerful API
|
||||
- simple yet powerful API
|
||||
- high-level filtering language
|
||||
- filter priorities
|
||||
- freely available under the terms of the GNU Lesser General Public
|
||||
License (LGPL)
|
||||
License (LGPLv3)
|
||||
|
||||
For more information about WinDivert, see doc/divert.html
|
||||
For more information see doc/windivert.html
|
||||
|
||||
2. Similar Packages
|
||||
-------------------
|
||||
|
||||
WinDivert is similar to divert sockets in FreeBSD/MacOS, NETLINK sockets in
|
||||
Linux, and some commercial packet capturing packages such as WinPkFilter for
|
||||
Windows. The design of WinDivert is largely influenced by FreeBSD's divert
|
||||
sockets.
|
||||
|
||||
WinDivert in packet-sniffing mode is similar to Winpcap. Unlike Winpcap,
|
||||
WinDivert fully supports capturing loopback traffic. Furthermore, WinDivert
|
||||
supports packet interception, which is not supported in Winpcap.
|
||||
|
||||
3. Architecture
|
||||
2. Architecture
|
||||
---------------
|
||||
|
||||
The basic architecture of WinDivert is as follows:
|
||||
@@ -70,70 +55,37 @@ The basic architecture of WinDivert is as follows:
|
||||
| |
|
||||
+---------------+
|
||||
|
||||
The WinDivert.sys driver is inserted below the Windows network stack. The
|
||||
following then happens
|
||||
The WinDivert.sys driver is installed below the Windows network stack. The
|
||||
following actions occur:
|
||||
|
||||
(1) a new packet enters the network stack and is intercepted by WinDivert.sys
|
||||
(2a) if the packet matches a PROGRAM-defined filter, it is diverted. The
|
||||
PROGRAM reads the packet with a call to the WinDivertRecv() function.
|
||||
(2b) if the packet does not match the filter, the packet is permitted to
|
||||
continue as normal.
|
||||
(3) PROGRAM either drops, modifies, or re-injects the packet. If the
|
||||
(modified) packet is re-injected, via a call to WinDivertSend(), it is
|
||||
inserted back into the Windows network stack.
|
||||
(1) A new packet enters the network stack and is intercepted by WinDivert.sys
|
||||
(2a) If the packet matches the PROGRAM-defined filter, it is diverted. The
|
||||
PROGRAM can then read the packet using a call to WinDivertRecv().
|
||||
(2b) If the packet does not match the filter, the packet continues as normal.
|
||||
(3) PROGRAM either drops, modifies, or re-injects the packet. PROGRAM can
|
||||
re-inject the (modified) using a call to WinDivertSend().
|
||||
|
||||
4. Building
|
||||
-----------
|
||||
|
||||
(1) In a WinDDK build environment, run the command:
|
||||
|
||||
wddk-build.bat
|
||||
|
||||
(2) [OPTIONAL Visual Studio 2012 support] In a VS2012 command prompt, run the
|
||||
command:
|
||||
|
||||
msvc-build.bat
|
||||
|
||||
(3) [OPTIONAL MinGW support] In Linux with MinGW a cross-compiler, run the
|
||||
command:
|
||||
|
||||
sh mingw-build.sh
|
||||
|
||||
For more detailed build instructions, see doc\windivert.html
|
||||
|
||||
5. License
|
||||
3. License
|
||||
----------
|
||||
|
||||
This package is distributed under the GNU Lesser General Public License
|
||||
(LGPL) Version 3. See LICENSE for more information.
|
||||
WinDivert is dual-licensed under your choice of the GNU Lesser General Public
|
||||
License (LGPL) Version 3 or the GNU General Public License (GPL) Version 2.
|
||||
See the LICENSE file for more information.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
6. About
|
||||
4. About
|
||||
--------
|
||||
|
||||
WinDivert was written by basil.
|
||||
|
||||
For further information, or bug reports, please contact
|
||||
For further information, or bug reports, please contact:
|
||||
|
||||
basil AT reqrypt DOT org
|
||||
basil@reqrypt.org
|
||||
|
||||
The homepage for WinDivert is
|
||||
The homepage for WinDivert is:
|
||||
|
||||
http://reqrypt.org/windivert.html
|
||||
https://reqrypt.org/windivert.html
|
||||
|
||||
The source code for WinDivert is hosted by GitHub at
|
||||
The source code for WinDivert is hosted by GitHub at:
|
||||
|
||||
https://github.com/basil00/Divert
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
TARGETNAME=WinDivert
|
||||
TARGETTYPE=DYNLINK
|
||||
TARGETPATH=..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
$(SDK_LIB_PATH)\advapi32.lib \
|
||||
$(SDK_LIB_PATH)\setupapi.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\kernel32.lib \
|
||||
$(SDK_LIB_PATH)\ws2_32.lib
|
||||
C_DEFINES=/DWIN32 /D_WINDOWS /D_USRDLL /DUSE_STDAFX /DUNICODE /D_UNICODE
|
||||
DLLENTRY=WinDivertDllEntry
|
||||
DLLDEF=windivert.def
|
||||
USE_MSVCRT=1
|
||||
INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\include
|
||||
SOURCES=windivert.c
|
||||
|
||||
+326
-1992
File diff suppressed because it is too large
Load Diff
+15
-10
@@ -6,20 +6,25 @@ EXPORTS
|
||||
WinDivertRecvEx
|
||||
WinDivertSend
|
||||
WinDivertSendEx
|
||||
WinDivertShutdown
|
||||
WinDivertClose
|
||||
WinDivertSetParam
|
||||
WinDivertGetParam
|
||||
WinDivertHelperCalcChecksums
|
||||
WinDivertHelperHashPacket
|
||||
WinDivertHelperParsePacket
|
||||
WinDivertHelperParseIPv4Address
|
||||
WinDivertHelperParseIPv6Address
|
||||
DivertOpen
|
||||
DivertRecv
|
||||
DivertSend
|
||||
DivertClose
|
||||
DivertSetParam
|
||||
DivertGetParam
|
||||
DivertHelperCalcChecksums
|
||||
DivertHelperParsePacket
|
||||
DivertHelperParseIPv4Address
|
||||
DivertHelperParseIPv6Address
|
||||
WinDivertHelperFormatIPv4Address
|
||||
WinDivertHelperFormatIPv6Address
|
||||
WinDivertHelperCompileFilter
|
||||
WinDivertHelperEvalFilter
|
||||
WinDivertHelperFormatFilter
|
||||
WinDivertHelperNtohs
|
||||
WinDivertHelperHtons
|
||||
WinDivertHelperNtohl
|
||||
WinDivertHelperHtonl
|
||||
WinDivertHelperNtohll
|
||||
WinDivertHelperHtonll
|
||||
WinDivertHelperNtohIpv6Address
|
||||
WinDivertHelperHtonIpv6Address
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<TARGETNAME>WinDivert</TARGETNAME>
|
||||
<Configuration>Release</Configuration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>windivert.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="windivert.c"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="windivert.def"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
</Project>
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* windivert_hash.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* xxHash - Fast Hash algorithm
|
||||
* Copyright (C) 2012-2016, Yann Collet
|
||||
*
|
||||
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a modified version of the 64bit xxHash algorithm:
|
||||
* - The algorithm is seeded with packet data rather than the single 64bit
|
||||
* "seed" value.
|
||||
* - The input sized is fixed to 32bytes (excluding the seed), so there is
|
||||
* only ever a single round. As such, the algorithm has been specialized.
|
||||
*/
|
||||
|
||||
#define WINDIVERT_ROTL(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
|
||||
|
||||
static const UINT64 WINDIVERT_PRIME64_1 = 11400714785074694791ull;
|
||||
static const UINT64 WINDIVERT_PRIME64_2 = 14029467366897019727ull;
|
||||
static const UINT64 WINDIVERT_PRIME64_3 = 1609587929392839161ull;
|
||||
static const UINT64 WINDIVERT_PRIME64_4 = 9650029242287828579ull;
|
||||
|
||||
static UINT64 WinDivertXXH64Round(UINT64 acc, UINT64 input)
|
||||
{
|
||||
acc += input * WINDIVERT_PRIME64_2;
|
||||
acc = WINDIVERT_ROTL(acc, 31);
|
||||
acc *= WINDIVERT_PRIME64_1;
|
||||
return acc;
|
||||
}
|
||||
|
||||
static UINT64 WinDivertXXH64MergeRound(UINT64 acc, UINT64 val)
|
||||
{
|
||||
val = WinDivertXXH64Round(0, val);
|
||||
acc ^= val;
|
||||
acc = acc * WINDIVERT_PRIME64_1 + WINDIVERT_PRIME64_4;
|
||||
return acc;
|
||||
}
|
||||
|
||||
static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
|
||||
{
|
||||
h64 ^= h64 >> 33;
|
||||
h64 *= WINDIVERT_PRIME64_2;
|
||||
h64 ^= h64 >> 29;
|
||||
h64 *= WINDIVERT_PRIME64_3;
|
||||
h64 ^= h64 >> 32;
|
||||
return h64;
|
||||
}
|
||||
|
||||
/*
|
||||
* WinDivert packet hash function.
|
||||
*/
|
||||
static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
|
||||
PWINDIVERT_IPV6HDR ipv6_header, PWINDIVERT_ICMPHDR icmp_header,
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header, PWINDIVERT_TCPHDR tcp_header,
|
||||
PWINDIVERT_UDPHDR udp_header)
|
||||
{
|
||||
UINT64 h64, v1, v2, v3, v4, v[4], *data64;
|
||||
UINT32 *data32;
|
||||
UINT i;
|
||||
static const UINT64 padding64[] = // SHA2 IV
|
||||
{
|
||||
0x428A2F9871374491ull, 0xB5C0FBCFE9B5DBA5ull, 0x3956C25B59F111F1ull,
|
||||
0x923F82A4AB1C5ED5ull, 0xD807AA9812835B01ull, 0x243185BE550C7DC3ull,
|
||||
0x72BE5D7480DEB1FEull, 0x9BDC06A7C19BF174ull, 0xE49B69C1EFBE4786ull,
|
||||
};
|
||||
|
||||
// Set-up seed & data
|
||||
v1 = seed ^ padding64[0];
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)ip_header;
|
||||
v2 = data64[0] ^ padding64[1];
|
||||
v3 = data64[1] ^ padding64[2];
|
||||
data32 = (UINT32 *)ip_header;
|
||||
v4 = (UINT64)data32[4] ^ padding64[3];
|
||||
i = 0;
|
||||
}
|
||||
else if (ipv6_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)ipv6_header;
|
||||
v2 = data64[0] ^ padding64[1];
|
||||
v3 = data64[1] ^ padding64[2];
|
||||
v4 = data64[2] ^ padding64[3];
|
||||
v[0] = data64[3] ^ padding64[4];
|
||||
v[1] = data64[4] ^ padding64[5];
|
||||
i = 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (tcp_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)tcp_header;
|
||||
v[i] = data64[0] ^ padding64[i+4]; i++;
|
||||
v[i] = data64[1] ^ padding64[i+4]; i++;
|
||||
data32 = (UINT32 *)tcp_header;
|
||||
if (i <= 3)
|
||||
{
|
||||
v[i] = (UINT64)data32[4] ^ padding64[i+4]; i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
v2 ^= ((UINT64)data32[4] << 32);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (udp_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)udp_header;
|
||||
v[i] = data64[0] ^ padding64[i+4]; i++;
|
||||
}
|
||||
else if (icmp_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)icmp_header;
|
||||
v[i] = data64[0] ^ padding64[i+4]; i++;
|
||||
}
|
||||
else if (icmpv6_header != NULL)
|
||||
{
|
||||
data64 = (UINT64 *)icmpv6_header;
|
||||
v[i] = data64[0] ^ padding64[i+4]; i++;
|
||||
}
|
||||
}
|
||||
|
||||
while (i <= 3)
|
||||
{
|
||||
v[i] = seed ^ padding64[i+4]; i++;
|
||||
}
|
||||
|
||||
// Hash
|
||||
v1 = WinDivertXXH64Round(v[0], v1);
|
||||
v2 = WinDivertXXH64Round(v[1], v2);
|
||||
v3 = WinDivertXXH64Round(v[2], v3);
|
||||
v4 = WinDivertXXH64Round(v[3], v4);
|
||||
h64 = WINDIVERT_ROTL(v1, 1) + WINDIVERT_ROTL(v2, 7) +
|
||||
WINDIVERT_ROTL(v3, 12) + WINDIVERT_ROTL(v4, 18);
|
||||
h64 = WinDivertXXH64MergeRound(h64, v1);
|
||||
h64 = WinDivertXXH64MergeRound(h64, v2);
|
||||
h64 = WinDivertXXH64MergeRound(h64, v3);
|
||||
h64 = WinDivertXXH64MergeRound(h64, v4);
|
||||
h64 += 32; // "length"
|
||||
h64 = WinDivertXXH64Avalanche(h64);
|
||||
|
||||
return h64;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,639 @@
|
||||
/*
|
||||
* windivert_shared.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define WINDIVERT_OBJECT_MAXLEN \
|
||||
(8 + 4 + 2 + WINDIVERT_FILTER_MAXLEN * (1 + 2 + 2 + 4*7 + 2 + 2) + 1)
|
||||
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
|
||||
/*
|
||||
* Definitions to remove (some) external dependencies:
|
||||
*/
|
||||
#define BYTESWAP16(x) \
|
||||
((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
|
||||
#define BYTESWAP32(x) \
|
||||
((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
|
||||
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
|
||||
#define BYTESWAP64(x) \
|
||||
((((x) >> 56) & 0x00000000000000FFull) | \
|
||||
(((x) >> 40) & 0x000000000000FF00ull) | \
|
||||
(((x) >> 24) & 0x0000000000FF0000ull) | \
|
||||
(((x) >> 8) & 0x00000000FF000000ull) | \
|
||||
(((x) << 8) & 0x000000FF00000000ull) | \
|
||||
(((x) << 24) & 0x0000FF0000000000ull) | \
|
||||
(((x) << 40) & 0x00FF000000000000ull) | \
|
||||
(((x) << 56) & 0xFF00000000000000ull))
|
||||
#define ntohs(x) BYTESWAP16(x)
|
||||
#define htons(x) BYTESWAP16(x)
|
||||
#define ntohl(x) BYTESWAP32(x)
|
||||
#define htonl(x) BYTESWAP32(x)
|
||||
|
||||
#include "windivert_hash.c"
|
||||
|
||||
/*
|
||||
* IPv4/IPv6 pseudo headers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
UINT8 Zero;
|
||||
UINT8 Protocol;
|
||||
UINT16 Length;
|
||||
} WINDIVERT_PSEUDOHDR, *PWINDIVERT_PSEUDOHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
UINT32 Length;
|
||||
UINT32 Zero:24;
|
||||
UINT32 NextHdr:8;
|
||||
} WINDIVERT_PSEUDOV6HDR, *PWINDIVERT_PSEUDOV6HDR;
|
||||
|
||||
/*
|
||||
* Streams.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *data;
|
||||
UINT pos;
|
||||
UINT max;
|
||||
BOOL overflow;
|
||||
} WINDIVERT_STREAM, *PWINDIVERT_STREAM;
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
static UINT16 WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
|
||||
PWINDIVERT_IPV6HDR ipv6_header, UINT8 protocol, UINT len,
|
||||
void *pseudo_header);
|
||||
static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
|
||||
UINT16 pseudo_header_len, PVOID data, UINT len);
|
||||
|
||||
/*
|
||||
* Put a char into a stream.
|
||||
*/
|
||||
static void WinDivertPutChar(PWINDIVERT_STREAM stream, char c)
|
||||
{
|
||||
if (stream->pos >= stream->max)
|
||||
{
|
||||
stream->overflow = TRUE;
|
||||
return;
|
||||
}
|
||||
stream->data[stream->pos] = c;
|
||||
stream->pos++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a string into a stream.
|
||||
*/
|
||||
static void WinDivertPutString(PWINDIVERT_STREAM stream, const char *str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
WinDivertPutChar(stream, *str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a NUL character into a stream.
|
||||
*/
|
||||
static void WinDivertPutNul(PWINDIVERT_STREAM stream)
|
||||
{
|
||||
if (stream->pos >= stream->max && stream->max > 0)
|
||||
{
|
||||
stream->data[stream->max-1] = '\0'; // Truncate
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertPutChar(stream, '\0');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a number.
|
||||
*/
|
||||
static void WinDivertSerializeNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
{
|
||||
UINT64 mask = 0x00000007C0000000ull;
|
||||
UINT dig = 6;
|
||||
UINT64 val64 = (UINT64)val;
|
||||
BOOL final;
|
||||
|
||||
while ((mask & val64) == 0 && dig != 0)
|
||||
{
|
||||
mask >>= 5;
|
||||
dig--;
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
final = (dig == 0);
|
||||
WinDivertPutChar(stream, '!' + (char)((mask & val64) >> (5 * dig)) +
|
||||
(final? 32: 0));
|
||||
if (final)
|
||||
{
|
||||
break;
|
||||
}
|
||||
mask >>= 5;
|
||||
dig--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a test.
|
||||
*/
|
||||
static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
|
||||
const WINDIVERT_FILTER *filter)
|
||||
{
|
||||
INT idx;
|
||||
UINT i;
|
||||
|
||||
WinDivertPutChar(stream, '_');
|
||||
WinDivertSerializeNumber(stream, filter->field);
|
||||
WinDivertSerializeNumber(stream, filter->test);
|
||||
WinDivertSerializeNumber(stream, filter->arg[0]);
|
||||
switch (filter->field)
|
||||
{
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR:
|
||||
case WINDIVERT_FILTER_FIELD_LOCALADDR:
|
||||
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
WinDivertSerializeNumber(stream, filter->arg[i]);
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PACKET:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET16:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET32:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32:
|
||||
idx = (INT)filter->arg[1];
|
||||
idx += UINT16_MAX;
|
||||
WinDivertSerializeNumber(stream, (UINT32)idx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
WinDivertSerializeNumber(stream, (UINT8)(filter->success + 2));
|
||||
WinDivertSerializeNumber(stream, (UINT8)(filter->failure + 2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a test.
|
||||
*/
|
||||
static void WinDivertSerializeFilter(PWINDIVERT_STREAM stream,
|
||||
const WINDIVERT_FILTER *filter, UINT8 length)
|
||||
{
|
||||
UINT8 i;
|
||||
WinDivertPutString(stream, "@WinDiv_"); // Magic
|
||||
WinDivertSerializeNumber(stream, 0); // Version
|
||||
WinDivertSerializeNumber(stream, length); // Length
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
WinDivertSerializeTest(stream, filter + i);
|
||||
}
|
||||
WinDivertPutNul(stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip well-known IPv6 extension headers.
|
||||
*/
|
||||
static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len)
|
||||
{
|
||||
UINT hdrlen;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (*len <= 2)
|
||||
{
|
||||
return IPPROTO_NONE;
|
||||
}
|
||||
|
||||
hdrlen = (UINT)*(*header + 1);
|
||||
switch (proto)
|
||||
{
|
||||
case IPPROTO_FRAGMENT:
|
||||
hdrlen = 8;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
hdrlen += 2;
|
||||
hdrlen *= 4;
|
||||
break;
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
hdrlen++;
|
||||
hdrlen *= 8;
|
||||
break;
|
||||
case IPPROTO_NONE:
|
||||
return proto;
|
||||
default:
|
||||
return proto;
|
||||
}
|
||||
|
||||
if (hdrlen >= *len)
|
||||
{
|
||||
return IPPROTO_NONE;
|
||||
}
|
||||
|
||||
proto = **header;
|
||||
*header += hdrlen;
|
||||
*len -= hdrlen;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
|
||||
PWINDIVERT_IPHDR *ppIpHdr, PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
PWINDIVERT_ICMPHDR *ppIcmpHdr, PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
||||
PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, UINT8 *pProto,
|
||||
PVOID *ppData, UINT *pDataLen)
|
||||
{
|
||||
PWINDIVERT_IPHDR ip_header = NULL;
|
||||
PWINDIVERT_IPV6HDR ipv6_header = NULL;
|
||||
PWINDIVERT_ICMPHDR icmp_header = NULL;
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header = NULL;
|
||||
PWINDIVERT_TCPHDR tcp_header = NULL;
|
||||
PWINDIVERT_UDPHDR udp_header = NULL;
|
||||
UINT16 header_len;
|
||||
UINT8 trans_proto = 0;
|
||||
PVOID data = NULL;
|
||||
UINT data_len = 0;
|
||||
BOOL success;
|
||||
|
||||
if (pPacket == NULL || packetLen < sizeof(UINT8))
|
||||
{
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = pPacket;
|
||||
data_len = packetLen;
|
||||
|
||||
ip_header = (PWINDIVERT_IPHDR)data;
|
||||
switch (ip_header->Version)
|
||||
{
|
||||
case 4:
|
||||
if (data_len < sizeof(WINDIVERT_IPHDR) ||
|
||||
ip_header->HdrLength < 5 ||
|
||||
data_len < ip_header->HdrLength*sizeof(UINT32) ||
|
||||
ntohs(ip_header->Length) != data_len)
|
||||
{
|
||||
ip_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
trans_proto = ip_header->Protocol;
|
||||
header_len = ip_header->HdrLength*sizeof(UINT32);
|
||||
data = (PVOID)((UINT8 *)data + header_len);
|
||||
data_len -= header_len;
|
||||
break;
|
||||
case 6:
|
||||
ip_header = NULL;
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_IPV6HDR) ||
|
||||
ntohs(ipv6_header->Length) !=
|
||||
data_len - sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
ipv6_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
trans_proto = ipv6_header->NextHdr;
|
||||
data = (PVOID)((UINT8 *)data + sizeof(WINDIVERT_IPV6HDR));
|
||||
data_len -= sizeof(WINDIVERT_IPV6HDR);
|
||||
trans_proto = WinDivertSkipExtHeaders(trans_proto, (UINT8 **)&data,
|
||||
&data_len);
|
||||
break;
|
||||
default:
|
||||
ip_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
switch (trans_proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
tcp_header = (PWINDIVERT_TCPHDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_TCPHDR) ||
|
||||
tcp_header->HdrLength < 5 ||
|
||||
data_len < tcp_header->HdrLength*sizeof(UINT32))
|
||||
{
|
||||
tcp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
header_len = tcp_header->HdrLength*sizeof(UINT32);
|
||||
data = ((UINT8 *)data + header_len);
|
||||
data_len -= header_len;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
udp_header = (PWINDIVERT_UDPHDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_UDPHDR) ||
|
||||
ntohs(udp_header->Length) != data_len)
|
||||
{
|
||||
udp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_UDPHDR));
|
||||
data_len -= sizeof(WINDIVERT_UDPHDR);
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
icmp_header = (PWINDIVERT_ICMPHDR)data;
|
||||
if (ip_header == NULL ||
|
||||
data_len < sizeof(WINDIVERT_ICMPHDR))
|
||||
{
|
||||
icmp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPHDR));
|
||||
data_len -= sizeof(WINDIVERT_ICMPHDR);
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
icmpv6_header = (PWINDIVERT_ICMPV6HDR)data;
|
||||
if (ipv6_header == NULL ||
|
||||
data_len < sizeof(WINDIVERT_ICMPV6HDR))
|
||||
{
|
||||
icmpv6_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPV6HDR));
|
||||
data_len -= sizeof(WINDIVERT_ICMPV6HDR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_len == 0)
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
WinDivertHelperParsePacketExit:
|
||||
success = TRUE;
|
||||
if (ppIpHdr != NULL)
|
||||
{
|
||||
*ppIpHdr = ip_header;
|
||||
success = success && (ip_header != NULL);
|
||||
}
|
||||
if (ppIpv6Hdr != NULL)
|
||||
{
|
||||
*ppIpv6Hdr = ipv6_header;
|
||||
success = success && (ipv6_header != NULL);
|
||||
}
|
||||
if (ppIcmpHdr != NULL)
|
||||
{
|
||||
*ppIcmpHdr = icmp_header;
|
||||
success = success && (icmp_header != NULL);
|
||||
}
|
||||
if (ppIcmpv6Hdr != NULL)
|
||||
{
|
||||
*ppIcmpv6Hdr = icmpv6_header;
|
||||
success = success && (icmpv6_header != NULL);
|
||||
}
|
||||
if (ppTcpHdr != NULL)
|
||||
{
|
||||
*ppTcpHdr = tcp_header;
|
||||
success = success && (tcp_header != NULL);
|
||||
}
|
||||
if (ppUdpHdr != NULL)
|
||||
{
|
||||
*ppUdpHdr = udp_header;
|
||||
success = success && (udp_header != NULL);
|
||||
}
|
||||
if (pProto != NULL)
|
||||
{
|
||||
*pProto = trans_proto;
|
||||
}
|
||||
if (ppData != NULL)
|
||||
{
|
||||
*ppData = data;
|
||||
success = success && (data != NULL);
|
||||
}
|
||||
if (pDataLen != NULL)
|
||||
{
|
||||
*pDataLen = data_len;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
|
||||
const WINDIVERT_ADDRESS *pAddr, UINT64 flags)
|
||||
{
|
||||
UINT8 pseudo_header[
|
||||
MAX(sizeof(WINDIVERT_PSEUDOHDR), sizeof(WINDIVERT_PSEUDOV6HDR))];
|
||||
UINT16 pseudo_header_len;
|
||||
PWINDIVERT_IPHDR ip_header;
|
||||
PWINDIVERT_IPV6HDR ipv6_header;
|
||||
PWINDIVERT_ICMPHDR icmp_header;
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
UINT payload_len, checksum_len;
|
||||
UINT count = 0;
|
||||
|
||||
WinDivertParsePacket(pPacket, packetLen, &ip_header, &ipv6_header,
|
||||
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, NULL,
|
||||
&payload_len);
|
||||
|
||||
if (ip_header != NULL && !(flags & WINDIVERT_HELPER_NO_IP_CHECKSUM))
|
||||
{
|
||||
ip_header->Checksum = 0;
|
||||
if (pAddr == NULL || pAddr->PseudoIPChecksum == 0)
|
||||
{
|
||||
ip_header->Checksum = WinDivertCalcChecksum(NULL, 0,
|
||||
ip_header, ip_header->HdrLength*sizeof(UINT32));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (icmp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_ICMP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
icmp_header->Checksum = 0;
|
||||
icmp_header->Checksum = WinDivertCalcChecksum(NULL, 0,
|
||||
icmp_header, payload_len + sizeof(WINDIVERT_ICMPHDR));
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (icmpv6_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
checksum_len = payload_len + sizeof(WINDIVERT_ICMPV6HDR);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(NULL, ipv6_header,
|
||||
IPPROTO_ICMPV6, checksum_len, pseudo_header);
|
||||
icmpv6_header->Checksum = 0;
|
||||
icmpv6_header->Checksum = WinDivertCalcChecksum(pseudo_header,
|
||||
pseudo_header_len, icmpv6_header, checksum_len);
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (tcp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_TCP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
if (pAddr == NULL || pAddr->PseudoTCPChecksum == 0)
|
||||
{
|
||||
// Full TCP checksum
|
||||
checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
|
||||
ipv6_header, IPPROTO_TCP, checksum_len, pseudo_header);
|
||||
tcp_header->Checksum = 0;
|
||||
tcp_header->Checksum = WinDivertCalcChecksum(
|
||||
pseudo_header, pseudo_header_len, tcp_header, checksum_len);
|
||||
}
|
||||
else if (pAddr->Outbound)
|
||||
{
|
||||
// Pseudo TCP checksum
|
||||
tcp_header->Checksum = 0;
|
||||
}
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (udp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_UDP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
if (pAddr == NULL || pAddr->PseudoUDPChecksum == 0)
|
||||
{
|
||||
// Full UDP checksum
|
||||
checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
|
||||
ipv6_header, IPPROTO_UDP, checksum_len, pseudo_header);
|
||||
udp_header->Checksum = 0;
|
||||
udp_header->Checksum = WinDivertCalcChecksum(
|
||||
pseudo_header, pseudo_header_len, udp_header, checksum_len);
|
||||
if (udp_header->Checksum == 0)
|
||||
{
|
||||
udp_header->Checksum = 0xFFFF;
|
||||
}
|
||||
}
|
||||
else if (pAddr->Outbound)
|
||||
{
|
||||
// Pseudo UDP checksum
|
||||
udp_header->Checksum = 0;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the IP/IPv6 pseudo header.
|
||||
*/
|
||||
static UINT16 WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
|
||||
PWINDIVERT_IPV6HDR ipv6_header, UINT8 protocol, UINT len,
|
||||
void *pseudo_header)
|
||||
{
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
PWINDIVERT_PSEUDOHDR pseudo_header_v4 =
|
||||
(PWINDIVERT_PSEUDOHDR)pseudo_header;
|
||||
pseudo_header_v4->SrcAddr = ip_header->SrcAddr;
|
||||
pseudo_header_v4->DstAddr = ip_header->DstAddr;
|
||||
pseudo_header_v4->Zero = 0;
|
||||
pseudo_header_v4->Protocol = protocol;
|
||||
pseudo_header_v4->Length = htons((UINT16)len);
|
||||
return sizeof(WINDIVERT_PSEUDOHDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINDIVERT_PSEUDOV6HDR pseudo_header_v6 =
|
||||
(PWINDIVERT_PSEUDOV6HDR)pseudo_header;
|
||||
memcpy(pseudo_header_v6->SrcAddr, ipv6_header->SrcAddr,
|
||||
sizeof(pseudo_header_v6->SrcAddr));
|
||||
memcpy(pseudo_header_v6->DstAddr, ipv6_header->DstAddr,
|
||||
sizeof(pseudo_header_v6->DstAddr));
|
||||
pseudo_header_v6->Length = htonl((UINT32)len);
|
||||
pseudo_header_v6->NextHdr = protocol;
|
||||
pseudo_header_v6->Zero = 0;
|
||||
return sizeof(WINDIVERT_PSEUDOV6HDR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic checksum computation.
|
||||
*/
|
||||
static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
|
||||
UINT16 pseudo_header_len, PVOID data, UINT len)
|
||||
{
|
||||
register const UINT16 *data16 = (const UINT16 *)pseudo_header;
|
||||
register size_t len16 = pseudo_header_len >> 1;
|
||||
register UINT32 sum = 0;
|
||||
size_t i;
|
||||
|
||||
// Pseudo header:
|
||||
for (i = 0; i < len16; i++)
|
||||
{
|
||||
sum += (UINT32)data16[i];
|
||||
}
|
||||
|
||||
// Main data:
|
||||
data16 = (const UINT16 *)data;
|
||||
len16 = len >> 1;
|
||||
for (i = 0; i < len16; i++)
|
||||
{
|
||||
sum += (UINT32)data16[i];
|
||||
}
|
||||
|
||||
if (len & 0x1)
|
||||
{
|
||||
const UINT8 *data8 = (const UINT8 *)data;
|
||||
sum += (UINT16)data8[len-1];
|
||||
}
|
||||
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
sum += (sum >> 16);
|
||||
sum = ~sum;
|
||||
return (UINT16)sum;
|
||||
}
|
||||
|
||||
+489
-132
@@ -1,18 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WinDivert 1.1 Documentation</title>
|
||||
<title>WinDivert 2.0 Documentation</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WinDivert 1.1: Windows Packet Divert</h1>
|
||||
<h1>WinDivert 2.0: Windows Packet Divert</h1>
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#introduction">1. Introduction</a></li>
|
||||
<li><a href="#building">2. Building</a></li>
|
||||
<ul>
|
||||
<li><a href="#driver_signing">2.1 Driver Signing</a></li>
|
||||
<li><a href="#visual_studio_2012_support">2.2 Visual Studio 2012 Support</a></li>
|
||||
<li><a href="#mingw_support">2.3 MinGW Support</a></li>
|
||||
</ul>
|
||||
<li><a href="#installing">3. Installing</a></li>
|
||||
<li><a href="#uninstalling">4. Uninstalling</a></li>
|
||||
@@ -40,6 +38,8 @@
|
||||
<li><a href="#divert_help_parse_ipv4_address">6.8 WinDivertHelperParseIPv4Address</li>
|
||||
<li><a href="#divert_help_parse_ipv6_address">6.9 WinDivertHelperParseIPv6Address</li>
|
||||
<li><a href="#divert_helper_calc_checksums">6.10 WinDivertHelperCalcChecksums</a></li>
|
||||
<li><a href="#divert_helper_check_filter">6.11 WinDivertHelperCheckFilter</a></li>
|
||||
<li><a href="#divert_helper_eval_filter">6.12 WinDivertHelperEvalFilter</a></li>
|
||||
</ul>
|
||||
<li><a href="#filter_language">7. Filter Language</a></li>
|
||||
<ul>
|
||||
@@ -85,109 +85,143 @@ WinDivert also supports passive packet sniffing similar to <tt>Winpcap</tt>.
|
||||
<hr>
|
||||
<a name="building"><h2>2. Building</h2></a>
|
||||
<p>
|
||||
Note that pre-built WinDivert binary distributions are available from the
|
||||
<a href="https://reqrypt.org/windivert.html">WinDivert website</a>.
|
||||
Most users do not need to build their own version of WinDivert from source.
|
||||
</p>
|
||||
<p>
|
||||
The source code for WinDivert is available for download at
|
||||
<blockquote>
|
||||
<a href="https://github.com/basil00/Divert">
|
||||
https://github.com/basil00/Divert</a>
|
||||
</blockquote>
|
||||
To build the WinDivert package from source:
|
||||
To build the WinDivert drivers from source:
|
||||
<ol>
|
||||
<li> Download and install <a href="http://www.microsoft.com/whdc/devtools/wdk/default.mspx">
|
||||
Windows Driver Kit 7.1.0</a>.</li>
|
||||
<li> Open a <i>Free Build Environment</i> console (or
|
||||
<i>Checked Build Environment</i> for debugging).</li>
|
||||
<li> Open a <i>x86 Free Build Environment</i> console.</li>
|
||||
<li> In the WinDivert package root directory, run the command:
|
||||
<pre>
|
||||
wddk-build.bat
|
||||
</pre>
|
||||
This will build the following files and place them in the
|
||||
<tt>install\WDDK</tt> subdirectory:
|
||||
<ul>
|
||||
<li> <tt>WinDivert.dll</tt>: User-mode library.</li>
|
||||
<li> <tt>WinDivert.sys</tt>: Kernel-mode WDF/WFP call-out driver.</li>
|
||||
<li> <tt>WinDivert.inf</tt>: INF file for <tt>WinDivert.sys</tt>.</li>
|
||||
<li> <tt>WdfCoInstaller*.dll</tt>: Microsoft WDF co-installer for
|
||||
<tt>WinDivert.sys</tt>.</li>
|
||||
<li> <tt>*.exe</tt>: Sample applications from the <tt>divert\examples</tt>
|
||||
directory.</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
<i>NOTE:</i> The <tt>WinDivert.dll</tt> and <tt>WinDivert.lib</tt> files
|
||||
are only compatible with programs compiled with the WDDK compiler.
|
||||
See below for Visual Studio 2012 and MinGW support.
|
||||
</p>
|
||||
|
||||
<a name="driver_signing"><h3>2.1 Driver Signing</h3></a>
|
||||
<p>
|
||||
Before the WinDivert package can be used, the <tt>WinDivert.sys</tt> driver
|
||||
must contain a valid digital signature.
|
||||
This is Microsoft policy for all kernel drivers in recent versions of
|
||||
Windows.
|
||||
See <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg487317.aspx">Driver Signing Requirements for Windows</a>
|
||||
for more information.
|
||||
</p>
|
||||
|
||||
<a name="visual_studio_2012_support"><h3>2.2 Visual Studio 2012 Support</h3></a>
|
||||
<p>
|
||||
To build the WinDivert package for Visual Studio 2012:
|
||||
<ol>
|
||||
<li> First build the driver by running <tt>wddk-build.bat</tt> as per the
|
||||
instructions above.</li>
|
||||
<li> Open a <i>Visual Studio Command Prompt</i> environment.</li>
|
||||
<li> In the WinDivert package root directory, run the command:
|
||||
<pre>
|
||||
msvc-build.bat
|
||||
</pre>
|
||||
This will build Visual Studio 2012 compatible files and place them in the
|
||||
<tt>install\MSVC</tt> subdirectory.</li>
|
||||
This will build the <tt>install\WDDK\i386\WinDivert32.sys</tt> driver.</li>
|
||||
<li> Next, open a <i>x64 Free Build Environment</i> console.</li>
|
||||
<li> Re-run the <tt>wddk-build.bat</tt> command to build the
|
||||
<tt>install\WDDK\amd64\WinDivert64.sys</tt> driver.</li>
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<a name="mingw_support"><h3>2.3 MinGW Support</h3></a>
|
||||
<p>
|
||||
To build the WinDivert package for MinGW:
|
||||
To build the WinDivert user-mode library (<tt>WinDivert.dll</tt>) and sample
|
||||
programs:
|
||||
<ol>
|
||||
<li> First build the driver by running <tt>wddk-build.bat</tt> as per
|
||||
the instructions above.</li>
|
||||
<li> First, build the WinDivert drivers by running the
|
||||
<tt>wddk-build.bat</tt> command described above.</li>
|
||||
<li> In Linux (with the MinGW cross-compilers installed) and in the
|
||||
WinDivert package root directory, run the command:
|
||||
<pre>
|
||||
sh mingw-build.sh
|
||||
</pre>
|
||||
This will build MinGW compatible files and place them in the
|
||||
<tt>install\MINGW</tt> subdirectory.</li>
|
||||
This will the user-mode library and sample programs which will be placed
|
||||
in the <tt>install\MINGW</tt> subdirectory.</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>
|
||||
The generated <tt>WinDivert.dll</tt>/<tt>WinDivert.lib</tt> files
|
||||
should be compatible with all major compilers, including both MinGW and
|
||||
Visual Studio.
|
||||
</p>
|
||||
|
||||
<a name="driver_signing"><h3>2.1 Driver Signing</h3></a>
|
||||
<p>
|
||||
If you built your own
|
||||
<tt>WinDivert32.sys</tt>/<tt>WinDivert64.sys</tt> drivers,
|
||||
they must be digitally signed before they can be used.
|
||||
See <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg487317.aspx">Driver Signing Requirements for Windows</a>
|
||||
for more information.
|
||||
</p>
|
||||
<p>
|
||||
Note that the pre-built <tt>WinDivert32.sys</tt>/<tt>WinDivert64.sys</tt>
|
||||
drivers from the official WinDivert distribution are already digitally signed.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name="installing"><h2>3. Installing</h2></a>
|
||||
<p>
|
||||
WinDivert does not require any special installation.
|
||||
Simply place the <tt>WinDivert.dll</tt>, <tt>WinDivert.sys</tt>,
|
||||
<tt>WinDivert.inf</tt>, and <tt>WdfCoInstaller*.dll</tt> files in the
|
||||
application's home directory.
|
||||
Depending on your target configuration, simply place the following files in
|
||||
your application's home directory:
|
||||
</p>
|
||||
<center>
|
||||
<table border="1" cellpadding="5" width="75%">
|
||||
<tr>
|
||||
<th>
|
||||
Application Type
|
||||
</th>
|
||||
<th>
|
||||
Target Windows Type
|
||||
</th>
|
||||
<th>
|
||||
Files Required
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
32-bit
|
||||
</td>
|
||||
<td>
|
||||
32-bit Windows only
|
||||
</td>
|
||||
<td>
|
||||
<tt>WinDivert.dll</tt> (32-bit version) and <tt>WinDivert32.sys</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
64-bit
|
||||
</td>
|
||||
<td>
|
||||
64-bit Windows only
|
||||
</td>
|
||||
<td>
|
||||
<tt>WinDivert.dll</tt> (64-bit version) and <tt>WinDivert64.sys</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
32-bit
|
||||
</td>
|
||||
<td>
|
||||
Both 32-bit and 64-bit Windows
|
||||
</td>
|
||||
<td>
|
||||
<tt>WinDivert.dll</tt> (32-bit version), <tt>WinDivert32.sys</tt>,
|
||||
and <tt>WinDivert64.sys</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<p>
|
||||
The WinDivert driver is automatically installed on demand whenever your
|
||||
application calls <a href="#divert_open"><tt>WinDivertOpen()</tt></a>.
|
||||
The driver installation is also silent.
|
||||
The calling application must be running with Administrator privileges.
|
||||
The WinDivert driver is automatically (and silently) installed on demand
|
||||
whenever your application calls
|
||||
<a href="#divert_open"><tt>WinDivertOpen()</tt></a>.
|
||||
The calling application must have Administrator privileges.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name="uninstalling"><h2>4. Uninstalling</h2></a>
|
||||
<p>
|
||||
To uninstall, simply delete the <tt>WinDivert.dll</tt>, <tt>WinDivert.sys</tt>,
|
||||
<tt>WinDivert.inf</tt>, and <tt>WdfCoInstaller*.dll</tt> files.
|
||||
The WinDivert driver is silently uninstalled when the calling application
|
||||
terminates or unloads the <tt>WinDivert.dll</tt> library.
|
||||
The WinDivert driver can also be removed manually by issuing the following
|
||||
To uninstall, simply delete the <tt>WinDivert.dll</tt>,
|
||||
<tt>WinDivert32.sys</tt>, and <tt>WinDivert64.sys</tt> files.
|
||||
If already running, the WinDivert driver will be automatically
|
||||
uninstalled during the next machine reboot.
|
||||
The WinDivert driver can also be manually removed by issuing the following
|
||||
commands at the command prompt
|
||||
<pre>
|
||||
sc stop WinDivert1.1
|
||||
sc delete WinDivert1.1
|
||||
sc stop WinDivert2.0
|
||||
sc delete WinDivert2.0
|
||||
</pre>
|
||||
Note that this is not recommended as it will interfere with other
|
||||
applications that depend on WinDivert.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
@@ -208,9 +242,15 @@ library.</li>
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp;
|
||||
UINT32 IfIdx;
|
||||
UINT32 SubIfIdx;
|
||||
UINT8 Direction;
|
||||
UINT8 Direction:1;
|
||||
UINT8 Loopback:1;
|
||||
UINT8 Impostor:1;
|
||||
UINT8 PseudoIPChecksum:1;
|
||||
UINT8 PseudoTCPChecksum:1;
|
||||
UINT8 PseudoUDPChecksum:1;
|
||||
} <b>WINDIVERT_ADDRESS</b>, *<b>PWINDIVERT_ADDRESS</b>;
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -218,6 +258,8 @@ typedef struct
|
||||
<p>
|
||||
<b>Fields</b>
|
||||
<ul>
|
||||
<li> <tt>Timestamp</tt>: A timestamp indicating when WinDivert first captured
|
||||
the packet.</li>
|
||||
<li> <tt>IfIdx</tt>: The interface index on which the packet arrived
|
||||
(for inbound packets), or is to be sent (for outbound packets).</li>
|
||||
<li> <tt>SubIfIdx</tt>: The sub-interface index for <tt>IfIdx</tt>.</li>
|
||||
@@ -229,12 +271,63 @@ packets.</li>
|
||||
<li> <tt>WINDIVERT_DIRECTION_INBOUND</tt> with value 1 for <i>inbound</i>
|
||||
packets.</li>
|
||||
</ul></li>
|
||||
<li> <tt>Loopback</tt>: Set to <tt>1</tt> for loopback packets, <tt>0</tt>
|
||||
otherwise</li>
|
||||
<li> <tt>Impostor</tt>: Set to <tt>1</tt> for <q>impostor</q> packets,
|
||||
<tt>0</tt> otherwise.</li>
|
||||
<li> <tt>PseudoIPChecksum</tt>: Set to <tt>1</tt> for packets with a
|
||||
<i>pseudo</i> IPv4 checksum, <tt>0</tt> otherwise.</li>
|
||||
<li> <tt>PseudoTCPChecksum</tt>: Set to <tt>1</tt> for packets with a
|
||||
<i>pseudo</i> TCP checksum, <tt>0</tt> otherwise.</li>
|
||||
<li> <tt>PseudoTCPChecksum</tt>: Set to <tt>1</tt> for packets with a
|
||||
<i>pseudo</i> UDP checksum, <tt>0</tt> otherwise.</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
The <tt>WINDIVERT_ADDRESS</tt> structure represents the "address" of a captured
|
||||
or injected packet.
|
||||
The address includes the packet's network interfaces and the packet direction.
|
||||
The <a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> structure
|
||||
represents the "address" of a captured or injected packet.
|
||||
The address includes the packet's timestamp, network interfaces, direction
|
||||
and other information.
|
||||
</p><p>
|
||||
The <tt>Timestamp</tt> indicates when the packet was first
|
||||
captured by WinDivert.
|
||||
It uses the same clock as
|
||||
<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx"><tt>QueryPerformanceCounter()</tt></a>.
|
||||
The <tt>Timestamp</tt> value is ignored by
|
||||
<a href="#divert_send"><tt>WinDivertSend()</tt></a>.
|
||||
</p><p>
|
||||
The <tt>IfIdx</tt>/<tt>SubIfIdx</tt> indicate the packet's network adapter
|
||||
(a.k.a. interface) index.
|
||||
These values are ignored for <i>outbound</i> packets.
|
||||
</p><p>
|
||||
The <tt>Direction</tt> field is set to <tt>WINDIVERT_DIRECTION_OUTBOUND</tt>
|
||||
(<tt>0</tt>) for outbound packets, and
|
||||
<tt>WINDIVERT_DIRECTION_INBOUND</tt> (<tt>1</tt>) for inbound packets.
|
||||
This field is ignored for <i>forward</i> packets.
|
||||
</p><p>
|
||||
The <tt>Loopback</tt> flag is set for <i>loopback</i> packets.
|
||||
Note that Windows considers any packet originating from, and destined to, the
|
||||
current machine to be a loopback packet, so loopback packets are not
|
||||
limited to localhost addresses.
|
||||
Note that WinDivert considers loopback packets to be
|
||||
<i>outbound only</i>, and will not capture loopback packets on the
|
||||
inbound path.
|
||||
</p><p>
|
||||
The <tt>Impostor</tt> flag is set for <i>impostor</i> packets.
|
||||
An impostor packet is any packet injected by another driver rather than
|
||||
originating from the network or Windows TCP/IP stack.
|
||||
Impostor packets are problematic since they can cause infinite loops,
|
||||
where a packet injected by <a href="#divert_send"><tt>WinDivertSend()</tt></a>
|
||||
is captured again by <a href="#divert_recv"><tt>WinDivertRecv()</tt></a>.
|
||||
For more information, see <a href="#divert_send"><tt>WinDivertSend()</tt></a>.
|
||||
</p><p>
|
||||
The <tt>Pseudo*Checksum</tt> flags indicate whether the packet uses
|
||||
<i>full</i> or <i>pseudo</i> checksums.
|
||||
Pseudo checksums are used when
|
||||
<i>IP/TCP/UDP checksum offloading</i> is enabled, meaning that the network
|
||||
hardware calculates/validates checksums rather than the Windows TCP/IP stack.
|
||||
Pseudo checksums may be arbitrary values.
|
||||
Typically, modified packets should preserve the <tt>Pseudo*Checksum</tt> flags.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
@@ -286,9 +379,9 @@ Description
|
||||
2
|
||||
</td>
|
||||
<td>
|
||||
One or more of the <tt>WinDivert.sys</tt>,
|
||||
<tt>WinDivert.inf</tt>, or <tt>WdfCoInstaller*.dll</tt> files were not
|
||||
found.
|
||||
The driver files
|
||||
<tt>WinDivert32.sys</tt> or <tt>WinDivert64.sys</tt>
|
||||
were not found.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -321,7 +414,8 @@ This indicates an invalid packet filter string, layer, priority, or flags.
|
||||
577
|
||||
</td>
|
||||
<td>
|
||||
The <tt>WinDivert.sys</tt> driver does not have a valid digital signature
|
||||
The <tt>WinDivert32.sys</tt> or <tt>WinDivert64.sys</tt> driver does not
|
||||
have a valid digital signature
|
||||
(see the <a href="#driver_signing">driver signing requirements</a> above).
|
||||
</td>
|
||||
</tr>
|
||||
@@ -335,14 +429,24 @@ The <tt>WinDivert.sys</tt> driver does not have a valid digital signature
|
||||
<td>
|
||||
This error occurs for various reasons, including:
|
||||
<ol>
|
||||
<li> attempting to load the 32-bit <tt>WinDivert.sys</tt> driver on a 64-bit
|
||||
system (or vice versa);</li>
|
||||
<li> the <tt>WinDivert.sys</tt> driver is blocked by security software; or
|
||||
<li> the WinDivert driver is blocked by security software; or</li>
|
||||
<li> you are using a virtualization environment that does not support
|
||||
drivers.</li>
|
||||
</ol>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<tt>EPT_S_NOT_REGISTERED</tt>
|
||||
</td>
|
||||
<td>
|
||||
1753
|
||||
</td>
|
||||
<td>
|
||||
This error occurs when the <i>Base Filtering Engine</i> service has been
|
||||
disabled.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
</p><p>
|
||||
@@ -448,13 +552,18 @@ WinDivert <a href="#filter_language">filter language</a>.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<tt>WINDIVERT_FLAG_NO_CHECKSUM</tt>
|
||||
<tt>WINDIVERT_FLAG_DEBUG</tt>
|
||||
</td>
|
||||
<td>
|
||||
By default WinDivert ensures that each diverted packet has a valid checksum.
|
||||
If the checksum is missing (e.g. with TCP checksum offloading), WinDivert
|
||||
will calculate it before passing the packet to the user application.
|
||||
This flag disables this behavior.
|
||||
This flag causes <a href="#divert_send"><tt>WinDivertSend()</tt></a> to block
|
||||
until the injected packet <i>exits</i> the Windows TCP/IP stack.
|
||||
By default, <a href="#divert_send"><tt>WinDivertSend()</tt></a> does not
|
||||
block and returns immediately after the packet <i>enters</i> the
|
||||
TCP/IP stack.
|
||||
The default mode is faster, but will not return an error code if the
|
||||
packet is lost or rejected for any reason; making debugging difficult.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
Note that only one of <tt>WINDIVERT_FLAG_SNIFF</tt> or
|
||||
@@ -482,7 +591,9 @@ BOOL <b>WinDivertRecv</b>(
|
||||
<a href="#divert_open"><tt>WinDivertOpen()</tt></a>.</li>
|
||||
<li> <tt>pPacket</tt>: A buffer for the captured packet.</li>
|
||||
<li> <tt>packetLen</tt>: The length of the buffer <tt>pPacket</tt>.</li>
|
||||
<li> <tt>pAddr</tt>: The <tt>WINDIVERT_ADDRESS</tt> of the captured packet.</li>
|
||||
<li> <tt>pAddr</tt>: The
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> of the captured
|
||||
packet.</li>
|
||||
<li> <tt>recvLen</tt>: The total number of bytes written to <tt>pPacket</tt>.
|
||||
Can be <tt>NULL</tt> if this information is not required.</li>
|
||||
</ul>
|
||||
@@ -515,8 +626,11 @@ Packets are not queued indefinitely, and if not handled in a timely manner,
|
||||
any captured packet may be dropped.
|
||||
The amount of time a packet is queued can be controlled with the
|
||||
<a href="#divert_set_param"><tt>WinDivertSetParam()</tt></a> function.
|
||||
</p>
|
||||
<p>
|
||||
</p><p>
|
||||
Captured packets are guaranteed to have correct checksums, or
|
||||
pseudo checksums, as indicated by the <tt>Pseudo*Checksum</tt> flags
|
||||
from the <a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a>.
|
||||
</p><p>
|
||||
<a href="#divert_recv"><tt>WinDivertRecv()</tt></a> should not be used on any
|
||||
WinDivert handle created with the <tt>WINDIVERT_FLAG_DROP</tt> set.
|
||||
</p>
|
||||
@@ -545,7 +659,9 @@ BOOL <b>WinDivertRecvEx</b>(
|
||||
<li> <tt>pPacket</tt>: A buffer for the captured packet.</li>
|
||||
<li> <tt>packetLen</tt>: The length of the buffer <tt>pPacket</tt>.</li>
|
||||
<li> <tt>flags</tt>: Reserved, set to zero.</li>
|
||||
<li> <tt>pAddr</tt>: The <tt>WINDIVERT_ADDRESS</tt> of the captured packet.</li>
|
||||
<li> <tt>pAddr</tt>: The
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> of the captured
|
||||
packet.</li>
|
||||
<li> <tt>recvLen</tt>: The total number of bytes written to <tt>pPacket</tt>.
|
||||
Can be <tt>NULL</tt> if this information is not required.</li>
|
||||
<li> <tt>lpOverlapped</tt>: An optional pointer to a <tt>OVERLAPPED</tt>
|
||||
@@ -588,7 +704,9 @@ BOOL <b>WinDivertSend</b>(
|
||||
<a href="#divert_open"><tt>WinDivertOpen()</tt></a>.</li>
|
||||
<li> <tt>pPacket</tt>: A buffer containing the packet to be injected.</li>
|
||||
<li> <tt>packetLen</tt>: The total length of the buffer <tt>pPacket</tt>.</li>
|
||||
<li> <tt>pAddr</tt>: The <tt>WINDIVERT_ADDRESS</tt> for the injected packet.</li>
|
||||
<li> <tt>pAddr</tt>: The
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> for the injected
|
||||
packet.</li>
|
||||
<li> <tt>sendLen</tt>: The total number of bytes injected.
|
||||
Can be <tt>NULL</tt> if this information is not required.</li>
|
||||
</ul>
|
||||
@@ -598,6 +716,44 @@ BOOL <b>WinDivertSend</b>(
|
||||
an error occurred.
|
||||
Use <tt>GetLastError()</tt> to get the reason for the error.
|
||||
</p><p>
|
||||
Common errors include:
|
||||
<center>
|
||||
<table border="1" cellpadding="5" width="75%">
|
||||
<tr>
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
Code
|
||||
</th>
|
||||
<th>
|
||||
Description
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<tt>ERROR_HOST_UNREACHABLE</tt>
|
||||
</td>
|
||||
<td>
|
||||
1232
|
||||
</td>
|
||||
<td>
|
||||
This error occurs when an <i>impostor</i> packet (with
|
||||
<tt>pAddr->Impostor</tt> set to <tt>1</tt>) is injected and the
|
||||
<tt>ip.TTL</tt> or <tt>ipv6.HopLimit</tt> field goes to zero.
|
||||
This is a defense of <q>last resort</q> against infinite loops caused by
|
||||
impostor packets.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
</p><p>
|
||||
Note that a return value of <tt>TRUE</tt> does not necessarily mean the
|
||||
packet was accepted by the Windows TCP/IP stack.
|
||||
For better error messages (at the cost of performance), pass the
|
||||
<tt>WINDIVERT_FLAG_DEBUG</tt> flag to <a
|
||||
href="#divert_open"><tt>WinDivertOpen()</tt></a>.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Injects a packet into the network stack.
|
||||
The injected packet may be one received from
|
||||
@@ -627,6 +783,29 @@ fields are currently ignored and may be arbitrary values.
|
||||
Injecting an inbound packet on the outbound path <i>may</i> work (for some
|
||||
types of packets), however this should be considered "undocumented" behavior,
|
||||
and may be changed in the future.
|
||||
</p><p>
|
||||
For <i>impostor</i> packets (where the <tt>Impostor</tt> field of
|
||||
<tt>pAddr</tt> set to <tt>1</tt>) WinDivert will automatically decrement the
|
||||
<tt>ip.TTL</tt> or <tt>ipv6.HopLimit</tt> fields for the injected packet.
|
||||
This is to mitigate infinite loops since WinDivert cannot prevent
|
||||
impostor packets from being captured again by
|
||||
<a href="#divert_recv"><tt>WinDivertRecv()</tt></a>.
|
||||
</p><p>
|
||||
Injected packets must have the correct checksums.
|
||||
Correct checksums can be calculated using the
|
||||
<a
|
||||
href="#divert_helper_calc_checksums"><tt>WinDivertHelperCalcChecksums()</tt></a>
|
||||
function.
|
||||
Note that packets returned by
|
||||
<a href="#divert_recv"><tt>WinDivertRecv()</tt></a> are
|
||||
guaranteed to have correct checksums.
|
||||
</p>
|
||||
<p>
|
||||
When pseudo checksums are used,
|
||||
the <a href="#divert_send"><tt>WinDivertSend()</tt></a> function may
|
||||
modify the contents of the memory pointed to by the <tt>pPacket</tt> and
|
||||
<tt>pAddr</tt> parameters.
|
||||
Thus, it is important that this memory is not read-only.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
@@ -653,7 +832,9 @@ BOOL <b>WinDivertSendEx</b>(
|
||||
<li> <tt>pPacket</tt>: A buffer containing the packet to be injected.</li>
|
||||
<li> <tt>packetLen</tt>: The total length of the buffer <tt>pPacket</tt>.</li>
|
||||
<li> <tt>flags</tt>: Reserved, set to zero.</li>
|
||||
<li> <tt>pAddr</tt>: The <tt>WINDIVERT_ADDRESS</tt> for the injected packet.</li>
|
||||
<li> <tt>pAddr</tt>: The
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> for the injected
|
||||
packet.</li>
|
||||
<li> <tt>sendLen</tt>: The total number of bytes injected.
|
||||
Can be <tt>NULL</tt> if this information is not required.</li>
|
||||
<li> <tt>lpOverlapped</tt>: An optional pointer to a <tt>OVERLAPPED</tt>
|
||||
@@ -745,8 +926,8 @@ Description
|
||||
<td>
|
||||
Sets the maximum length of the packet queue for
|
||||
<a href="#divert_recv"><tt>WinDivertRecv()</tt></a>.
|
||||
Currently the default value is 512, the minimum is 1, and the maximum
|
||||
is 8192.
|
||||
Currently the default value is 2048, the minimum is 16, and the maximum
|
||||
is 16384.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -761,8 +942,19 @@ processed by the application as soon as is possible.
|
||||
Note that this sets the <i>minimum</i> time a packet can be queued before
|
||||
it can be dropped.
|
||||
The actual time may be exceed this value.
|
||||
Currently the default value is 512, the minimum is 128, and the maximum is
|
||||
2048.
|
||||
Currently the default value is 1000 (1s), the minimum is 20 (20ms), and the
|
||||
maximum is 8000 (8s).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<tt>WINDIVERT_PARAM_QUEUE_SIZE</tt>
|
||||
</td>
|
||||
<td>
|
||||
Sets the maximum number of bytes that can be stored in the packet queue for
|
||||
<a href="#divert_recv"><tt>WinDivertRecv()</tt></a>.
|
||||
Currently the default value is 4194304 (4MB), the minimum is 65535 (64KB),
|
||||
and the maximum is 33554432 (32MB).
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -1068,7 +1260,9 @@ Use <tt>GetLastError()</tt> to get the reason for the error.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Parses an IPv4 address stored in <tt>addrStr</tt>.
|
||||
If non-<tt>NULL</tt>, the result is stored in <tt>pAddr</tt>.
|
||||
If <tt>pAddr</tt> is non-<tt>NULL</tt>, the is be stored in
|
||||
host-byte-order.
|
||||
Use <tt>htonl()</tt> to convert the result into network-byte-order.
|
||||
</p>
|
||||
<dd></dl>
|
||||
|
||||
@@ -1095,9 +1289,22 @@ Use <tt>GetLastError()</tt> to get the reason for the error.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Parses an IPv6 address stored in <tt>addrStr</tt>.
|
||||
If non-<tt>NULL</tt>, the result is stored in <tt>pAddr</tt>.
|
||||
The <tt>pAddr</tt> parameter is assumed to point to a buffer large enough
|
||||
to hold a 16-byte IPv6 address.
|
||||
If <tt>pAddr</tt> is non-<tt>NULL</tt>, the buffer assumed
|
||||
to be large enough to hold a 16-byte IPv6 address.
|
||||
The result is stored in host-byte-order.
|
||||
For example, given an IPv6 address of the form
|
||||
<tt>0011:2233:4455:6677:8899:aabb:ccdd:eeff</tt>, then
|
||||
the result is ordered as follows:
|
||||
<pre>
|
||||
pAddr[0] = 0xccddeeff
|
||||
pAddr[1] = 0x8899aabb
|
||||
pAddr[2] = 0x44556677
|
||||
pAddr[3] = 0x00112233
|
||||
</pre>
|
||||
where each <tt>pAddr[i]</tt> is in host-byte-order.
|
||||
The result can be converted into network-byte-order by setting
|
||||
<tt>pAddr[i] = htonl(pAddr[i])</tt> for each <tt>i</tt> and
|
||||
swapping the array indexes.
|
||||
</p>
|
||||
<dd></dl>
|
||||
|
||||
@@ -1107,6 +1314,7 @@ to hold a 16-byte IPv6 address.
|
||||
UINT <b>WinDivertHelperCalcChecksums</b>(
|
||||
__inout PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__in_opt PWINDIVERT_ADDRESS pAddr,
|
||||
__in UINT64 flags
|
||||
);
|
||||
</pre>
|
||||
@@ -1117,6 +1325,8 @@ UINT <b>WinDivertHelperCalcChecksums</b>(
|
||||
<ul>
|
||||
<li> <tt>pPacket</tt>: The packet to be modified.</li>
|
||||
<li> <tt>packetLen</tt>: The total length of the packet <tt>pPacket</tt>.</li>
|
||||
<li> <tt>pAddr</tt>: Optional pointer to a
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> structure.</li>
|
||||
<li> <tt>flags</tt>: One or more of the following flags:
|
||||
<ul>
|
||||
<li> <tt>WINDIVERT_HELPER_NO_IP_CHECKSUM</tt>: Do not calculate the IPv4
|
||||
@@ -1142,11 +1352,99 @@ Individual checksum calculations may be disabled via the appropriate flag.
|
||||
Typically this function should be invoked on a modified packet before it is
|
||||
injected with <a href="#divert_send"><tt>WinDivertSend()</tt></a>.
|
||||
</p><p>
|
||||
This function will calculate each checksum from scratch, even if the existing
|
||||
checksum is correct.
|
||||
By default this function will calculate each checksum from scratch, even if
|
||||
the existing checksum is correct.
|
||||
This may be inefficient for some applications.
|
||||
For better performance, incremental checksum calculations should be used
|
||||
instead (not provided by this API).
|
||||
</p><p>
|
||||
If <tt>pAddr</tt> is non-<tt>NULL</tt>, this function will avoid calculating
|
||||
the full checksum if the <tt>Pseudo*Checksum</tt> flag is
|
||||
set in the corresponding
|
||||
<a href="#divert_address"><tt>WINDIVERT_ADDRESS</tt></a> structure.
|
||||
The address structure should be the same as
|
||||
the one passed to <a href="#divert_send"><tt>WinDivertSend()</tt></a> in
|
||||
order to (re)inject the packet.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_check_filter"><h3>6.11 WinDivertHelperCheckFilter</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperCheckFilter</b>(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt const char **errorStr,
|
||||
__out_opt UINT *errorPos
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<dl><dd>
|
||||
<p>
|
||||
<b>Parameters</b><br>
|
||||
<ul>
|
||||
<li> <tt>filter</tt>: The packet filter string to be checked.</li>
|
||||
<li> <tt>layer</tt>: The layer.
|
||||
<li> <tt>errorStr</tt>: The error description.</li>
|
||||
<li> <tt>errorPos</tt>: The error position.</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
<b>Return Value</b><br>
|
||||
<tt>TRUE</tt> if the packet filter string is valid, <tt>FALSE</tt> otherwise.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Checks if the given packet filter string is valid with respect to the
|
||||
<a href="#filter_language">filter language</a>.
|
||||
If the filter is invalid, then a human readable description of the error is
|
||||
returned by <tt>errorStr</tt> (if non-<tt>NULL</tt>), and the error's
|
||||
position is returned by <tt>errorPos</tt> (if non-<tt>NULL</tt>).
|
||||
</p><p>
|
||||
Note that all strings returned through <tt>errorStr</tt> are global static
|
||||
objects, and therefore do not need to be deallocated.
|
||||
<p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_eval_filter"><h3>6.12 WinDivertHelperEvalFilter</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperEvalFilter</b>(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__in PWINDIVERT_ADDRESS pAddr
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<dl><dd>
|
||||
<p>
|
||||
<b>Parameters</b><br>
|
||||
<ul>
|
||||
<li> <tt>filter</tt>: The packet filter string to be evaluated.</li>
|
||||
<li> <tt>layer</tt>: The layer.
|
||||
<li> <tt>pPacket</tt>: The packet.</li>
|
||||
<li> <tt>packetLen</tt>: The total length of the packet <tt>pPacket</tt>.</li>
|
||||
<li> <tt>pAddr</tt>: The <tt>WINDIVERT_ADDRESS</tt> of the packet
|
||||
<tt>pPacket</tt>.</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
<b>Return Value</b><br>
|
||||
<tt>TRUE</tt> if the packet matches the filter string,
|
||||
<tt>FALSE</tt> otherwise.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Evaluates the given packet against the given packet filter string.
|
||||
This function returns <tt>TRUE</tt> if the packet matches, and
|
||||
returns <tt>FALSE</tt> otherwise.
|
||||
</p><p>
|
||||
This function also returns <tt>FALSE</tt> if an error occurs, in which
|
||||
case <tt>GetLastError()</tt> can be used to get the reason for the error.
|
||||
Otherwise, if no error occurred, <tt>GetLastError()</tt> will return
|
||||
<tt>0</tt>.
|
||||
</p><p>
|
||||
Note that this function is relatively slow since the packet filter string
|
||||
will be (re)compiled for each call.
|
||||
This function is mainly intended for debugging or testing purposes.
|
||||
<p>
|
||||
</dd></dl>
|
||||
|
||||
@@ -1179,10 +1477,16 @@ This filter specifies that we should only divert traffic that is
|
||||
</p><p>
|
||||
A <i>filter</i> is a Boolean expression of the form:
|
||||
<pre>
|
||||
<i>FILTER</i> := true | false | <i>FILTER</i> and <i>FILTER</i> | <i>FILTER</i> or <i>FILTER</i> | (<i>FILTER</i>) | <i>TEST</i>
|
||||
<i>FILTER</i> := true | false | <i>FILTER</i> and <i>FILTER</i> | <i>FILTER</i> or <i>FILTER</i> | (<i>FILTER</i>) | (<i>FILTER</i>? <i>FILTER</i>: <i>FILTER</i>) | <i>TEST</i>
|
||||
</pre>
|
||||
C-style syntax <tt>&&</tt>, <tt>||</tt>, and <tt>!</tt> may also
|
||||
be used instead of <tt>and</tt>, <tt>or</tt>, and <tt>not</tt>, respectively.
|
||||
C-style <i>conditional operators</i> are also supported,
|
||||
where the expression <tt>(A? B: C)</tt> evaluates to:
|
||||
<ul>
|
||||
<li> <tt>B</tt> if <tt>A</tt> evaluates to <tt>true</tt>; or</li>
|
||||
<li> <tt>C</tt> if <tt>A</tt> evaluates to <tt>false</tt>.
|
||||
</ul>
|
||||
A <i>test</i> is of the following form:
|
||||
<pre>
|
||||
<i>TEST</i> := <i>TEST0</i> | not <i>TEST0</i>
|
||||
@@ -1213,10 +1517,12 @@ The possible fields are:
|
||||
<center>
|
||||
<table border="1" cellpadding="5">
|
||||
<tr><th>Field</th><th>Description</th></tr>
|
||||
<tr><td><tt>outbound</tt></td><td>Is outbound?</td></tr>
|
||||
<tr><td><tt>inbound</tt></td><td>Is inbound?</td></tr>
|
||||
<tr><td><tt>outbound</tt></td><td>Is outbound? (only valid for <tt>WINDIVERT_LAYER_NETWORK</tt>)</td></tr>
|
||||
<tr><td><tt>inbound</tt></td><td>Is inbound? (only valid for <tt>WINDIVERT_LAYER_NETWORK</tt>)</td></tr>
|
||||
<tr><td><tt>ifIdx</tt></td><td>Interface index</td></tr>
|
||||
<tr><td><tt>subIfIdx</tt></td><td>Sub-interface index</td></tr>
|
||||
<tr><td><tt>loopback</tt></td><td>Is loopback packet?</td></tr>
|
||||
<tr><td><tt>impostor</tt></td><td>Is impostor packet?</td></tr>
|
||||
<tr><td><tt>ip</tt></td><td>Is IPv4?</td></tr>
|
||||
<tr><td><tt>ipv6</tt></td><td>Is IPv6?</td></tr>
|
||||
<tr><td><tt>icmp</tt></td><td>Is ICMP?</td></tr>
|
||||
@@ -1244,10 +1550,10 @@ contain a TCP header.
|
||||
<p>
|
||||
<ol>
|
||||
<li>
|
||||
Divert all outbound web traffic:
|
||||
Divert all outbound (non-local) web traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"outbound and "
|
||||
"outbound and !loopback and "
|
||||
"(tcp.DstPort == 80 or udp.DstPort == 53)",
|
||||
0, 0, 0
|
||||
);
|
||||
@@ -1264,17 +1570,6 @@ HANDLE handle = WinDivertOpen(
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert only (inbound) local traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"inbound and ("
|
||||
"(ip.DstAddr >= 127.0.0.1 and ip.DstAddr <= 127.255.255.255) or"
|
||||
"ipv6.DstAddr == ::1)",
|
||||
0, 0, 0
|
||||
);
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert all traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen("true", 0, 0, 0);
|
||||
@@ -1340,6 +1635,13 @@ The sample programs are:
|
||||
packets from a single handle.
|
||||
This example is useful for performance testing, and as a starting point
|
||||
for more interesting applications.</li>
|
||||
<li><tt>streamdump.exe</tt>: A simple program that demonstrates how to
|
||||
handle streams using WinDivert.
|
||||
The basic idea is to divert outbound TCP connections to a local proxy
|
||||
server which can capture or manipulate the stream.
|
||||
The <tt>streamdump</tt> sample program also demonstrates usage of the
|
||||
<a href="#divert_recv_ex"><tt>WinDivertRecvEx()</tt></a> and
|
||||
<a href="#divert_send_ex"><tt>WinDivertSendEx()</tt></a> functions.</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
The samples are intended for educational purposes only, and are not
|
||||
@@ -1372,6 +1674,7 @@ capture-modify-reinject loop:
|
||||
|
||||
// Modify packet.
|
||||
|
||||
WinDivertHelperCalcChecksums(packet, packetLen, &addr, 0);
|
||||
if (!WinDivertSend(handle, packet, packetLen, &addr, NULL))
|
||||
{
|
||||
// Handle send error
|
||||
@@ -1394,28 +1697,67 @@ There are some limitations to the WinDivert package.
|
||||
They are
|
||||
<ul>
|
||||
<li><i>Injecting inbound ICMP/ICMPv6 messages</i>:
|
||||
For some ICMP/ICMPv6 messages, inbound injection does not work.
|
||||
An error will be returned and the packet will be lost.
|
||||
It is suspected that this is an issue with the WFP framework on which
|
||||
WinDivert is built.
|
||||
The work-around is to inject inbound ICMP messages as <tt>outbound</tt>.
|
||||
Calling <a href="#divert_send"><tt>WinDivertSend()</tt></a> will fail with
|
||||
an error for certain types of inbound ICMP/ICMPv6 messages.
|
||||
This is probably because the Windows TCP/IP stack does not handle
|
||||
such messages.
|
||||
Such errors are harmless and can be ignored.
|
||||
</li>
|
||||
<li><i>The forward layer does not interact well with the Windows NAT</i>:
|
||||
It is not possible to block packets pre-NAT with WinDivert.
|
||||
As a general principle, you should not try and mix WinDivert at the
|
||||
forward layer with the Windows NAT implementation.
|
||||
</li>
|
||||
<li><i>Re-injecting unmodified packets can lead to infinite loops</i>:
|
||||
If two or more Windows Filtering Platform (WFP) callout drivers
|
||||
(including WinDivert applications) block and inject unmodified copies of
|
||||
packets then this can lead to an infinite loop.
|
||||
If such a loop occurs,
|
||||
<a href="#divert_send"><tt>WinDivertSend()</tt></a> will eventually fail
|
||||
with error <tt>ERROR_HOST_UNREACHABLE</tt>.
|
||||
Unfortunately, such errors are not easy to fix.
|
||||
Some crude solutions include: (1) removing the incompatible driver, or
|
||||
(2) ignoring all packets with <tt>ip.TTL</tt> or
|
||||
<tt>ipv6.HopLimit</tt> less than the Windows <tt>DefaultTTL</tt>
|
||||
registry value.
|
||||
See <a href="https://github.com/basil00/Divert/issues/41">
|
||||
GitHub issue #41</a> for more information.
|
||||
</li>
|
||||
<li><i>WinDivert can cause the MSVC x86_64 debugger to deadlock</i>:
|
||||
The deadlock occurs because the debugger uses local sockets.
|
||||
Thus: the debugger pauses the WinDivert
|
||||
application, which stops packets from being processed, which
|
||||
causes the debugger wait forever on input from a socket.
|
||||
The deadlock can be avoided by ignoring loopback traffic.
|
||||
See <a href="https://github.com/basil00/Divert/issues/26">
|
||||
GitHub issue #26</a> for more information.
|
||||
</li>
|
||||
<li><i>WinDivert can cause packets to be out-of-order</i>:
|
||||
Simply running the <tt>passthru.exe</tt> sample program can cause
|
||||
packets to become out-of-order.
|
||||
This is not a bug, since there is no requirement for packets to
|
||||
remain in-order.
|
||||
However, this may affect other buggy software
|
||||
(e.g. some buggy NAT implementations)
|
||||
that incorrectly assume packets to be in-order.
|
||||
</li>
|
||||
<li><i>No IPv6 extension header support</i>:
|
||||
Currently there is no filter support for IPv6 packets with extension
|
||||
headers.
|
||||
The work around is to capture all IPv6 traffic.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name="license"><h2>10. License</h2></a>
|
||||
<p>
|
||||
This package is distributed <i>strictly</i> under the
|
||||
WinDivert is dual-licensed, and is available under the
|
||||
<a href="http://www.gnu.org/licenses/lgpl-3.0.txt">GNU Lesser General
|
||||
Public License (GPL) Version 3</a>.
|
||||
Please note the following:
|
||||
Public License (LGPL) Version 3</a> or the
|
||||
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">
|
||||
GNU General Public License (GPL) Version 2</a>.
|
||||
Please see the notices below:
|
||||
</p>
|
||||
<p>
|
||||
<b>LGPL version 3</b>:
|
||||
<pre>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
WinDivert is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
@@ -1429,8 +1771,23 @@ You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</pre>
|
||||
</p>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<p>
|
||||
<b>GPL version 2</b>:
|
||||
<pre>
|
||||
WinDivert is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
</pre>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
DIRS= \
|
||||
netdump \
|
||||
netfilter \
|
||||
passthru \
|
||||
webfilter
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* flowtrack.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* usage: flowtrack.exe [filter]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAX_FLOWS 256
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Flow tracking.
|
||||
*/
|
||||
typedef struct FLOW
|
||||
{
|
||||
WINDIVERT_ADDRESS addr;
|
||||
struct FLOW *next;
|
||||
} FLOW, *PFLOW;
|
||||
|
||||
static HANDLE lock;
|
||||
static PFLOW flows = NULL;
|
||||
|
||||
/*
|
||||
* Draw flows to console in a delayed loop.
|
||||
*
|
||||
* This function does minimal error checking.
|
||||
*/
|
||||
static DWORD draw(LPVOID arg)
|
||||
{
|
||||
const COORD top_left = {0, 0};
|
||||
HANDLE process, console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO screen;
|
||||
char path[MAX_PATH+1];
|
||||
char addr_str[INET6_ADDRSTRLEN+1];
|
||||
char *filename;
|
||||
const char header[] = "PID PROGRAM PROT FLOW";
|
||||
DWORD rows, columns, written, fill_len, path_len, i;
|
||||
PFLOW flow;
|
||||
WINDIVERT_ADDRESS addrs[MAX_FLOWS], *addr;
|
||||
UINT num_addrs;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GetConsoleScreenBufferInfo(console, &screen);
|
||||
SetConsoleCursorPosition(console, top_left);
|
||||
|
||||
rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
|
||||
columns = screen.srWindow.Right - screen.srWindow.Left + 1;
|
||||
|
||||
// Copy a snapshot of the current flows:
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
flow = flows;
|
||||
num_addrs = 0;
|
||||
for (i = 0; flow != NULL && i < rows && i < MAX_FLOWS; i++)
|
||||
{
|
||||
memcpy(&addrs[i], &flow->addr, sizeof(addrs[i]));
|
||||
num_addrs++;
|
||||
flow = flow->next;
|
||||
}
|
||||
ReleaseMutex(lock);
|
||||
|
||||
// Print the flows:
|
||||
SetConsoleTextAttribute(console, BACKGROUND_RED | BACKGROUND_GREEN |
|
||||
BACKGROUND_BLUE);
|
||||
WriteConsole(console, header, sizeof(header)-1, &written, NULL);
|
||||
fill_len = columns - (sizeof(header)-1);
|
||||
if (fill_len > 0)
|
||||
{
|
||||
COORD pos = {sizeof(header)-1, 0};
|
||||
FillConsoleOutputCharacterA(console, ' ', fill_len, pos,
|
||||
&written);
|
||||
FillConsoleOutputAttribute(console,
|
||||
BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
|
||||
fill_len, pos, &written);
|
||||
}
|
||||
putchar('\n');
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
for (i = 0; i < num_addrs && i < rows-1; i++)
|
||||
{
|
||||
COORD pos = {0, i+1};
|
||||
addr = &addrs[i];
|
||||
FillConsoleOutputCharacterA(console, ' ', columns, pos, &written);
|
||||
FillConsoleOutputAttribute(console,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
|
||||
columns, pos, &written);
|
||||
SetConsoleCursorPosition(console, pos);
|
||||
if (i == rows-2 && (i+1) < num_addrs)
|
||||
{
|
||||
fputs("...", stdout);
|
||||
fflush(stdout);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%-10d ", addr->Flow.ProcessId);
|
||||
|
||||
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
|
||||
addr->Flow.ProcessId);
|
||||
path_len = 0;
|
||||
if (process != NULL)
|
||||
{
|
||||
path_len = GetProcessImageFileName(process, path, sizeof(path));
|
||||
CloseHandle(process);
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
if (path_len != 0)
|
||||
{
|
||||
filename = PathFindFileName(path);
|
||||
printf("%-20.20s ", filename);
|
||||
}
|
||||
else if (addr->Flow.ProcessId == 4)
|
||||
{
|
||||
fputs("Windows ", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs("??? ", stdout);
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
switch (addr->Flow.Protocol)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("TCP ");
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("UDP ");
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("ICMP ");
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("ICMPV6 ");
|
||||
break;
|
||||
default:
|
||||
printf("%-6u ", addr->Flow.Protocol);
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
WinDivertHelperFormatIPv6Address(addr->Flow.LocalAddr, addr_str,
|
||||
sizeof(addr_str));
|
||||
printf("%s:%u %s ", addr_str, addr->Flow.LocalPort,
|
||||
(addr->Outbound? "---->": "<----"));
|
||||
WinDivertHelperFormatIPv6Address(addr->Flow.RemoteAddr, addr_str,
|
||||
sizeof(addr_str));
|
||||
printf("%s:%u", addr_str, addr->Flow.RemotePort);
|
||||
fflush(stdout);
|
||||
}
|
||||
for (; i < rows-1; i++)
|
||||
{
|
||||
COORD pos = {0, i+1};
|
||||
FillConsoleOutputCharacterA(console, ' ', columns, pos, &written);
|
||||
FillConsoleOutputAttribute(console,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
|
||||
columns, pos, &written);
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, thread;
|
||||
INT16 priority = 776; // Arbitrary.
|
||||
const char *filter = "true", *err_str;
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
PFLOW flow, prev;
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
filter = argv[1];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [filter]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Open WinDivert FLOW handle:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_FLOW, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_FLOW,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Spawn the draw() thread.
|
||||
lock = CreateMutex(NULL, FALSE, NULL);
|
||||
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)draw, NULL, 0,
|
||||
NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to create thread (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
CloseHandle(thread);
|
||||
|
||||
// Main loop:
|
||||
while (TRUE)
|
||||
{
|
||||
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
|
||||
{
|
||||
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (addr.Event)
|
||||
{
|
||||
case WINDIVERT_EVENT_FLOW_ESTABLISHED:
|
||||
|
||||
// Flow established:
|
||||
flow = (PFLOW)malloc(sizeof(FLOW));
|
||||
if (flow == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to allocate memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memcpy(&flow->addr, &addr, sizeof(flow->addr));
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
flow->next = flows;
|
||||
flows = flow;
|
||||
ReleaseMutex(lock);
|
||||
break;
|
||||
|
||||
case WINDIVERT_EVENT_FLOW_DELETED:
|
||||
|
||||
// Flow deleted:
|
||||
prev = NULL;
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
flow = flows;
|
||||
while (flow != NULL)
|
||||
{
|
||||
if (memcmp(&addr.Flow, &flow->addr.Flow,
|
||||
sizeof(addr.Flow)) == 0)
|
||||
{
|
||||
if (prev != NULL)
|
||||
{
|
||||
prev->next = flow->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
flows = flow->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = flow;
|
||||
flow = flow->next;
|
||||
}
|
||||
ReleaseMutex(lock);
|
||||
free(flow);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
+69
-41
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* netdump.c
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -25,7 +41,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -33,7 +48,11 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define ntohs(x) WinDivertHelperNtohs(x)
|
||||
#define ntohl(x) WinDivertHelperNtohl(x)
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
@@ -52,6 +71,12 @@ int __cdecl main(int argc, char **argv)
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
UINT32 src_addr[4], dst_addr[4];
|
||||
UINT64 hash;
|
||||
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
|
||||
const char *err_str;
|
||||
LARGE_INTEGER base, freq;
|
||||
double time_passed;
|
||||
|
||||
// Check arguments.
|
||||
switch (argc)
|
||||
@@ -68,7 +93,7 @@ int __cdecl main(int argc, char **argv)
|
||||
fprintf(stderr, "\t%s true\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -4000\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -80,9 +105,11 @@ int __cdecl main(int argc, char **argv)
|
||||
WINDIVERT_FLAG_SNIFF);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: filter syntax error\n");
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
@@ -104,6 +131,10 @@ int __cdecl main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set up timing:
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&base);
|
||||
|
||||
// Main loop:
|
||||
while (TRUE)
|
||||
{
|
||||
@@ -114,7 +145,7 @@ int __cdecl main(int argc, char **argv)
|
||||
GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Print info about the matching packet.
|
||||
WinDivertHelperParsePacket(packet, packet_len, &ip_header,
|
||||
&ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
|
||||
@@ -127,54 +158,51 @@ int __cdecl main(int argc, char **argv)
|
||||
// Dump packet info:
|
||||
putchar('\n');
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("Packet [Direction=%u IfIdx=%u SubIfIdx=%u]\n",
|
||||
addr.Direction, addr.IfIdx, addr.SubIfIdx);
|
||||
time_passed = (double)(addr.Timestamp - base.QuadPart) /
|
||||
(double)freq.QuadPart;
|
||||
hash = WinDivertHelperHashPacket(packet, packet_len, 0);
|
||||
printf("Packet [Timestamp=%.8g, Direction=%s IfIdx=%u SubIfIdx=%u "
|
||||
"Loopback=%u Hash=0x%.16llX]\n",
|
||||
time_passed, (addr.Outbound? "outbound": "inbound"),
|
||||
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback, hash);
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
|
||||
UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
|
||||
src_str, sizeof(src_str));
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->DstAddr),
|
||||
dst_str, sizeof(dst_str));
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED);
|
||||
printf("IPv4 [Version=%u HdrLength=%u TOS=%u Length=%u Id=0x%.4X "
|
||||
"Reserved=%u DF=%u MF=%u FragOff=%u TTL=%u Protocol=%u "
|
||||
"Checksum=0x%.4X SrcAddr=%u.%u.%u.%u DstAddr=%u.%u.%u.%u]\n",
|
||||
"Checksum=0x%.4X SrcAddr=%s DstAddr=%s]\n",
|
||||
ip_header->Version, ip_header->HdrLength,
|
||||
ntohs(ip_header->TOS), ntohs(ip_header->Length),
|
||||
ntohs(ip_header->Id), WINDIVERT_IPHDR_GET_RESERVED(ip_header),
|
||||
WINDIVERT_IPHDR_GET_DF(ip_header),
|
||||
WINDIVERT_IPHDR_GET_MF(ip_header),
|
||||
ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL,
|
||||
ip_header->Protocol, ntohs(ip_header->Checksum),
|
||||
src_addr[0], src_addr[1], src_addr[2], src_addr[3],
|
||||
dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
|
||||
ip_header->Protocol, ntohs(ip_header->Checksum), src_str,
|
||||
dst_str);
|
||||
|
||||
}
|
||||
if (ipv6_header != NULL)
|
||||
{
|
||||
UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
|
||||
UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
|
||||
WinDivertHelperNtohIpv6Address(ipv6_header->SrcAddr, src_addr);
|
||||
WinDivertHelperNtohIpv6Address(ipv6_header->DstAddr, dst_addr);
|
||||
WinDivertHelperFormatIPv6Address(src_addr, src_str,
|
||||
sizeof(src_str));
|
||||
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
|
||||
sizeof(dst_str));
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED);
|
||||
printf("IPv6 [Version=%u TrafficClass=%u FlowLabel=%u Length=%u "
|
||||
"NextHdr=%u HopLimit=%u SrcAddr=",
|
||||
"NextHdr=%u HopLimit=%u SrcAddr=%s DstAddr=%s]\n",
|
||||
ipv6_header->Version,
|
||||
WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header),
|
||||
ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
|
||||
ntohs(ipv6_header->Length), ipv6_header->NextHdr,
|
||||
ipv6_header->HopLimit);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
printf("%x%c", ntohs(src_addr[i]), (i == 7? ' ': ':'));
|
||||
}
|
||||
fputs("DstAddr=", stdout);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
printf("%x", ntohs(dst_addr[i]));
|
||||
if (i != 7)
|
||||
{
|
||||
putchar(':');
|
||||
}
|
||||
}
|
||||
fputs("]\n", stdout);
|
||||
ipv6_header->HopLimit, src_str, dst_str);
|
||||
}
|
||||
if (icmp_header != NULL)
|
||||
{
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<TARGETNAME>netdump</TARGETNAME>
|
||||
<Configuration>Release</Configuration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\install\MSVC\WinDivert.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="netdump.c"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
!IF "$(_BUILDARCH)" == "x86"
|
||||
CPU=i386
|
||||
!ELSE
|
||||
CPU=$(_BUILDARCH)
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=netdump
|
||||
TARGETTYPE=PROGRAM
|
||||
TARGETPATH=..\..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
$(SDK_LIB_PATH)\setupapi.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\ws2_32.lib \
|
||||
$(TARGETPATH)\$(CPU)\WinDivert.lib
|
||||
UMTYPE=console
|
||||
UMENTRY=main
|
||||
USE_MSVCRT=1
|
||||
INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\..\include
|
||||
SOURCES=netdump.c
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* netfilter.c
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -31,7 +47,6 @@
|
||||
* This program is similar to Linux's iptables with the "-j REJECT" target.
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -39,7 +54,14 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define ntohs(x) WinDivertHelperNtohs(x)
|
||||
#define ntohl(x) WinDivertHelperNtohl(x)
|
||||
#define htons(x) WinDivertHelperHtons(x)
|
||||
#define htonl(x) WinDivertHelperHtonl(x)
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
#define IPPROTO_ICMPV6 58
|
||||
|
||||
/*
|
||||
* Pre-fabricated packets.
|
||||
@@ -97,7 +119,10 @@ int __cdecl main(int argc, char **argv)
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
UINT32 src_addr[4], dst_addr[4];
|
||||
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
|
||||
UINT payload_len;
|
||||
const char *err_str;
|
||||
|
||||
TCPPACKET reset0;
|
||||
PTCPPACKET reset = &reset0;
|
||||
@@ -125,7 +150,7 @@ int __cdecl main(int argc, char **argv)
|
||||
fprintf(stderr, "\t%s true\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -4000\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -152,9 +177,11 @@ int __cdecl main(int argc, char **argv)
|
||||
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: filter syntax error\n");
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
@@ -189,28 +216,21 @@ int __cdecl main(int argc, char **argv)
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
|
||||
UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
|
||||
printf("ip.SrcAddr=%u.%u.%u.%u ip.DstAddr=%u.%u.%u.%u ",
|
||||
src_addr[0], src_addr[1], src_addr[2], src_addr[3],
|
||||
dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
|
||||
src_str, sizeof(src_str));
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->DstAddr),
|
||||
dst_str, sizeof(dst_str));
|
||||
}
|
||||
if (ipv6_header != NULL)
|
||||
{
|
||||
UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
|
||||
UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
|
||||
fputs("ipv6.SrcAddr=", stdout);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
printf("%x%c", ntohs(src_addr[i]), (i == 7? ' ': ':'));
|
||||
}
|
||||
fputs(" ipv6.DstAddr=", stdout);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
printf("%x%c", ntohs(dst_addr[i]), (i == 7? ' ': ':'));
|
||||
}
|
||||
putchar(' ');
|
||||
WinDivertHelperNtohIpv6Address(ipv6_header->SrcAddr, src_addr);
|
||||
WinDivertHelperNtohIpv6Address(ipv6_header->DstAddr, dst_addr);
|
||||
WinDivertHelperFormatIPv6Address(src_addr, src_str,
|
||||
sizeof(src_str));
|
||||
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
|
||||
sizeof(dst_str));
|
||||
}
|
||||
printf("ip.SrcAddr=%s ip.DstAddr=%s ", src_str, dst_str);
|
||||
if (icmp_header != NULL)
|
||||
{
|
||||
printf("icmp.Type=%u icmp.Code=%u ",
|
||||
@@ -254,7 +274,7 @@ int __cdecl main(int argc, char **argv)
|
||||
putchar(' ');
|
||||
|
||||
|
||||
if (ip_header != NULL)
|
||||
if (ip_header != NULL && !tcp_header->Rst && !tcp_header->Fin)
|
||||
{
|
||||
reset->ip.SrcAddr = ip_header->DstAddr;
|
||||
reset->ip.DstAddr = ip_header->SrcAddr;
|
||||
@@ -267,11 +287,10 @@ int __cdecl main(int argc, char **argv)
|
||||
htonl(ntohl(tcp_header->SeqNum) + 1):
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len));
|
||||
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
|
||||
0);
|
||||
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Direction = !recv_addr.Direction;
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
|
||||
&send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
|
||||
&send_addr, NULL))
|
||||
{
|
||||
@@ -280,7 +299,7 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (ipv6_header != NULL)
|
||||
if (ipv6_header != NULL && !tcp_header->Rst && !tcp_header->Fin)
|
||||
{
|
||||
memcpy(resetv6->ipv6.SrcAddr, ipv6_header->DstAddr,
|
||||
sizeof(resetv6->ipv6.SrcAddr));
|
||||
@@ -295,11 +314,10 @@ int __cdecl main(int argc, char **argv)
|
||||
htonl(ntohl(tcp_header->SeqNum) + 1):
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len));
|
||||
|
||||
WinDivertHelperCalcChecksums((PVOID)resetv6,
|
||||
sizeof(TCPV6PACKET), 0);
|
||||
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Direction = !recv_addr.Direction;
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)resetv6,
|
||||
sizeof(TCPV6PACKET), &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
|
||||
&send_addr, NULL))
|
||||
{
|
||||
@@ -315,9 +333,6 @@ int __cdecl main(int argc, char **argv)
|
||||
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
// NOTE: For some ICMP error messages, WFP does not seem to
|
||||
// support INBOUND injection. As a work-around, we
|
||||
// always inject OUTBOUND.
|
||||
UINT icmp_length = ip_header->HdrLength*sizeof(UINT32) + 8;
|
||||
memcpy(dnr->data, ip_header, icmp_length);
|
||||
icmp_length += sizeof(ICMPPACKET);
|
||||
@@ -325,10 +340,10 @@ int __cdecl main(int argc, char **argv)
|
||||
dnr->ip.SrcAddr = ip_header->DstAddr;
|
||||
dnr->ip.DstAddr = ip_header->SrcAddr;
|
||||
|
||||
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length, 0);
|
||||
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Direction = WINDIVERT_DIRECTION_OUTBOUND;
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
|
||||
&send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
|
||||
NULL))
|
||||
{
|
||||
@@ -348,10 +363,10 @@ int __cdecl main(int argc, char **argv)
|
||||
memcpy(dnrv6->ipv6.DstAddr, ipv6_header->SrcAddr,
|
||||
sizeof(dnrv6->ipv6.DstAddr));
|
||||
|
||||
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length, 0);
|
||||
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Direction = WINDIVERT_DIRECTION_OUTBOUND;
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
|
||||
&send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
|
||||
&send_addr, NULL))
|
||||
{
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<TARGETNAME>netfilter</TARGETNAME>
|
||||
<Configuration>Release</Configuration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\install\MSVC\WinDivert.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="netfilter.c"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
!IF "$(_BUILDARCH)" == "x86"
|
||||
CPU=i386
|
||||
!ELSE
|
||||
CPU=$(_BUILDARCH)
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=netfilter
|
||||
TARGETTYPE=PROGRAM
|
||||
TARGETPATH=..\..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
$(SDK_LIB_PATH)\setupapi.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\ws2_32.lib \
|
||||
$(TARGETPATH)\$(CPU)\WinDivert.lib
|
||||
UMTYPE=console
|
||||
UMENTRY=main
|
||||
USE_MSVCRT=1
|
||||
INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\..\include
|
||||
SOURCES=netfilter.c
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* passthru.c
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -31,7 +47,10 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define MAXBUF 400000
|
||||
#define MAXBATCH 0xFF
|
||||
|
||||
static int batch = 1;
|
||||
|
||||
static DWORD passthru(LPVOID arg);
|
||||
|
||||
@@ -40,12 +59,13 @@ static DWORD passthru(LPVOID arg);
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
int num_threads, i;
|
||||
int num_threads, priority = 0, i;
|
||||
HANDLE handle, thread;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc < 3 || argc > 5)
|
||||
{
|
||||
fprintf(stderr, "usage: %s filter num-threads\n", argv[0]);
|
||||
fprintf(stderr, "usage: %s filter num-threads [batch] [priority]\n",
|
||||
argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
num_threads = atoi(argv[2]);
|
||||
@@ -54,9 +74,23 @@ int __cdecl main(int argc, char **argv)
|
||||
fprintf(stderr, "error: invalid number of threads\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 4)
|
||||
{
|
||||
batch = atoi(argv[3]);
|
||||
}
|
||||
if (batch <= 0 || batch > MAXBATCH)
|
||||
{
|
||||
fprintf(stderr, "error: invalid batch size\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 5)
|
||||
{
|
||||
priority = atoi(argv[4]);
|
||||
}
|
||||
|
||||
// Divert traffic matching the filter:
|
||||
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, 0, 0);
|
||||
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, (INT16)priority,
|
||||
0);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
@@ -91,24 +125,27 @@ int __cdecl main(int argc, char **argv)
|
||||
// Passthru thread.
|
||||
static DWORD passthru(LPVOID arg)
|
||||
{
|
||||
unsigned char packet[MAXBUF];
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
UINT8 packet[MAXBUF];
|
||||
UINT packet_len, addr_len;
|
||||
WINDIVERT_ADDRESS addr[MAXBATCH];
|
||||
HANDLE handle = (HANDLE)arg;
|
||||
|
||||
// Main loop:
|
||||
while (TRUE)
|
||||
{
|
||||
// Read a matching packet.
|
||||
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
|
||||
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
|
||||
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
|
||||
addr, &addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to read packet (%d)\n",
|
||||
GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Re-inject the matching packet.
|
||||
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
|
||||
if (!WinDivertSendEx(handle, packet, packet_len, NULL, 0, addr,
|
||||
addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
|
||||
GetLastError());
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<TARGETNAME>passthru</TARGETNAME>
|
||||
<Configuration>Release</Configuration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\install\MSVC\WinDivert.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="passthru.c"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
!IF "$(_BUILDARCH)" == "x86"
|
||||
CPU=i386
|
||||
!ELSE
|
||||
CPU=$(_BUILDARCH)
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=passthru
|
||||
TARGETTYPE=PROGRAM
|
||||
TARGETPATH=..\..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
$(SDK_LIB_PATH)\setupapi.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\ws2_32.lib \
|
||||
$(TARGETPATH)\$(CPU)\WinDivert.lib
|
||||
UMTYPE=console
|
||||
UMENTRY=main
|
||||
USE_MSVCRT=1
|
||||
INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\..\include
|
||||
SOURCES=passthru.c
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* socketdump.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* usage: socketdump.exe [filter]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, process, console;
|
||||
INT16 priority = 1121; // Arbitrary.
|
||||
const char *filter = "true", *err_str;
|
||||
char path[MAX_PATH+1];
|
||||
char local_str[INET6_ADDRSTRLEN+1], remote_str[INET6_ADDRSTRLEN+1];
|
||||
char *filename;
|
||||
DWORD path_len;
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
filter = argv[1];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [filter]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Open WinDivert SOCKET handle:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_SOCKET, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_SOCKET,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Main loop:
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
while (TRUE)
|
||||
{
|
||||
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
|
||||
{
|
||||
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
switch (addr.Event)
|
||||
{
|
||||
case WINDIVERT_EVENT_SOCKET_BIND:
|
||||
printf("BIND");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_LISTEN:
|
||||
printf("LISTEN");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_CONNECT:
|
||||
printf("CONNECT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_ACCEPT:
|
||||
printf("ACCEPT");
|
||||
break;
|
||||
default:
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" pid=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%u", addr.Socket.ProcessId);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" program=");
|
||||
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
|
||||
addr.Socket.ProcessId);
|
||||
path_len = 0;
|
||||
if (process != NULL)
|
||||
{
|
||||
path_len = GetProcessImageFileName(process, path, sizeof(path));
|
||||
CloseHandle(process);
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
if (path_len != 0)
|
||||
{
|
||||
filename = PathFindFileName(path);
|
||||
printf("%s", filename);
|
||||
}
|
||||
else if (addr.Socket.ProcessId == 4)
|
||||
{
|
||||
printf("Windows");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("???");
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" protocol=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
switch (addr.Socket.Protocol)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
printf("TCP");
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
printf("UDP");
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
printf("ICMP");
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
printf("ICMPV6");
|
||||
break;
|
||||
default:
|
||||
printf("%u", addr.Socket.Protocol);
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
WinDivertHelperFormatIPv6Address(addr.Socket.LocalAddr, local_str,
|
||||
sizeof(local_str));
|
||||
if (addr.Socket.LocalPort != 0 || strcmp(local_str, "::") != 0)
|
||||
{
|
||||
printf(" local=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("[%s]:%u", local_str, addr.Socket.LocalPort);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
WinDivertHelperFormatIPv6Address(addr.Socket.RemoteAddr, remote_str,
|
||||
sizeof(remote_str));
|
||||
if (addr.Socket.RemotePort != 0 || strcmp(remote_str, "::") != 0)
|
||||
{
|
||||
printf(" remote=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("[%s]:%u", remote_str, addr.Socket.RemotePort);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
/*
|
||||
* streamdump.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This program demonstrates how to handle streams using WinDivert.
|
||||
*
|
||||
* The program works by "reflecting" outbound TCP connections into inbound
|
||||
* TCP connections that are handled by a simple proxy server.
|
||||
*
|
||||
* This program also demonstrates WinDivert asynchronous I/O.
|
||||
*
|
||||
* usage: streamdump.exe port
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define PROXY_PORT 34010
|
||||
#define ALT_PORT 43010
|
||||
#define MAX_LINE 65
|
||||
|
||||
/*
|
||||
* Proxy server configuration.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT16 proxy_port;
|
||||
UINT16 alt_port;
|
||||
} PROXY_CONFIG, *PPROXY_CONFIG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SOCKET s;
|
||||
UINT16 alt_port;
|
||||
struct in_addr dest;
|
||||
} PROXY_CONNECTION_CONFIG, *PPROXY_CONNECTION_CONFIG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL inbound;
|
||||
SOCKET s;
|
||||
SOCKET t;
|
||||
} PROXY_TRANSFER_CONFIG, *PPROXY_TRANSFER_CONFIG;
|
||||
|
||||
/*
|
||||
* Lock to sync output.
|
||||
*/
|
||||
static HANDLE lock;
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
static DWORD proxy(LPVOID arg);
|
||||
static DWORD proxy_connection_handler(LPVOID arg);
|
||||
static DWORD proxy_transfer_handler(LPVOID arg);
|
||||
|
||||
/*
|
||||
* Error handling.
|
||||
*/
|
||||
static void message(const char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
vfprintf(stderr, msg, args);
|
||||
putc('\n', stderr);
|
||||
ReleaseMutex(lock);
|
||||
va_end(args);
|
||||
}
|
||||
#define error(msg, ...) \
|
||||
do { \
|
||||
message("error: " msg, ## __VA_ARGS__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} while (FALSE)
|
||||
#define warning(msg, ...) \
|
||||
message("warning: " msg, ## __VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Cleanup completed I/O requests.
|
||||
*/
|
||||
static void cleanup(HANDLE ioport, OVERLAPPED *ignore)
|
||||
{
|
||||
OVERLAPPED *overlapped;
|
||||
DWORD iolen;
|
||||
ULONG_PTR iokey = 0;
|
||||
|
||||
while (GetQueuedCompletionStatus(ioport, &iolen, &iokey, &overlapped, 0))
|
||||
{
|
||||
if (overlapped != ignore)
|
||||
{
|
||||
free(overlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, thread;
|
||||
UINT16 port, proxy_port, alt_port;
|
||||
int r;
|
||||
char filter[256];
|
||||
INT16 priority = 123; // Arbitrary.
|
||||
PPROXY_CONFIG config;
|
||||
unsigned char packet[MAXBUF];
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
PWINDIVERT_IPHDR ip_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
OVERLAPPED *poverlapped;
|
||||
OVERLAPPED overlapped;
|
||||
HANDLE ioport, event;
|
||||
DWORD len;
|
||||
|
||||
// Init.
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "usage: %s dest-port\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
port = (UINT16)atoi(argv[1]);
|
||||
if (port < 0 || port > 0xFFFF)
|
||||
{
|
||||
fprintf(stderr, "error: invalid port number (%d)\n", port);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
proxy_port = (port == PROXY_PORT? PROXY_PORT+1: PROXY_PORT);
|
||||
alt_port = (port == ALT_PORT? ALT_PORT+1: ALT_PORT);
|
||||
lock = CreateMutex(NULL, FALSE, NULL);
|
||||
if (lock == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to create mutex (%d)\n",
|
||||
GetLastError());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ioport = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
|
||||
if (ioport == NULL)
|
||||
{
|
||||
error("failed to create I/O completion port (%d)", GetLastError());
|
||||
}
|
||||
event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (event == NULL)
|
||||
{
|
||||
error("failed to create event (%d)", GetLastError());
|
||||
}
|
||||
|
||||
// Divert all traffic to/from `port', `proxy_port' and `alt_port'.
|
||||
r = snprintf(filter, sizeof(filter),
|
||||
"tcp and "
|
||||
"(tcp.DstPort == %d or tcp.DstPort == %d or tcp.DstPort == %d or "
|
||||
"tcp.SrcPort == %d or tcp.SrcPort == %d or tcp.SrcPort == %d)",
|
||||
port, proxy_port, alt_port, port, proxy_port, alt_port);
|
||||
if (r < 0 || r >= sizeof(filter))
|
||||
{
|
||||
error("failed to create filter string");
|
||||
}
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, priority, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
error("failed to open the WinDivert device (%d)", GetLastError());
|
||||
}
|
||||
if (CreateIoCompletionPort(handle, ioport, 0, 0) == NULL)
|
||||
{
|
||||
error("failed to associate I/O completion port (%d)", GetLastError());
|
||||
}
|
||||
|
||||
// Spawn proxy thread,
|
||||
config = (PPROXY_CONFIG)malloc(sizeof(PROXY_CONFIG));
|
||||
if (config == NULL)
|
||||
{
|
||||
error("failed to allocate memory");
|
||||
}
|
||||
config->proxy_port = proxy_port;
|
||||
config->alt_port = alt_port;
|
||||
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)proxy,
|
||||
(LPVOID)config, 0, NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
error("failed to create thread (%d)", GetLastError());
|
||||
}
|
||||
CloseHandle(thread);
|
||||
|
||||
// Main loop:
|
||||
while (TRUE)
|
||||
{
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
ResetEvent(event);
|
||||
overlapped.hEvent = event;
|
||||
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
|
||||
&addr, NULL, &overlapped))
|
||||
{
|
||||
if (GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
read_failed:
|
||||
warning("failed to read packet (%d)", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Timeout = 1s
|
||||
while (WaitForSingleObject(event, 1000) == WAIT_TIMEOUT)
|
||||
{
|
||||
cleanup(ioport, &overlapped);
|
||||
}
|
||||
if (!GetOverlappedResult(handle, &overlapped, &len, FALSE))
|
||||
{
|
||||
goto read_failed;
|
||||
}
|
||||
packet_len = len;
|
||||
}
|
||||
cleanup(ioport, &overlapped);
|
||||
|
||||
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
|
||||
NULL, NULL, &tcp_header, NULL, NULL, NULL))
|
||||
{
|
||||
warning("failed to parse packet (%d)", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr.Outbound)
|
||||
{
|
||||
if (tcp_header->DstPort == htons(port))
|
||||
{
|
||||
// Reflect: PORT ---> PROXY
|
||||
UINT32 dst_addr = ip_header->DstAddr;
|
||||
tcp_header->DstPort = htons(proxy_port);
|
||||
ip_header->DstAddr = ip_header->SrcAddr;
|
||||
ip_header->SrcAddr = dst_addr;
|
||||
addr.Outbound = FALSE;
|
||||
}
|
||||
else if (tcp_header->SrcPort == htons(proxy_port))
|
||||
{
|
||||
// Reflect: PROXY ---> PORT
|
||||
UINT32 dst_addr = ip_header->DstAddr;
|
||||
tcp_header->SrcPort = htons(port);
|
||||
ip_header->DstAddr = ip_header->SrcAddr;
|
||||
ip_header->SrcAddr = dst_addr;
|
||||
addr.Outbound = FALSE;
|
||||
}
|
||||
else if (tcp_header->DstPort == htons(alt_port))
|
||||
{
|
||||
// Redirect: ALT ---> PORT
|
||||
tcp_header->DstPort = htons(port);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcp_header->SrcPort == htons(port))
|
||||
{
|
||||
// Redirect: PORT ---> ALT
|
||||
tcp_header->SrcPort = htons(alt_port);
|
||||
}
|
||||
}
|
||||
|
||||
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
|
||||
poverlapped = (OVERLAPPED *)malloc(sizeof(OVERLAPPED));
|
||||
if (poverlapped == NULL)
|
||||
{
|
||||
error("failed to allocate memory");
|
||||
}
|
||||
memset(poverlapped, 0, sizeof(OVERLAPPED));
|
||||
if (WinDivertSendEx(handle, packet, packet_len, NULL, 0, &addr,
|
||||
sizeof(WINDIVERT_ADDRESS), poverlapped))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
warning("failed to send packet (%d)", GetLastError());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Proxy server thread.
|
||||
*/
|
||||
static DWORD proxy(LPVOID arg)
|
||||
{
|
||||
PPROXY_CONFIG config = (PPROXY_CONFIG)arg;
|
||||
UINT16 proxy_port = config->proxy_port;
|
||||
UINT16 alt_port = config->alt_port;
|
||||
int on = 1;
|
||||
WSADATA wsa_data;
|
||||
WORD wsa_version = MAKEWORD(2, 2);
|
||||
struct sockaddr_in addr;
|
||||
SOCKET s;
|
||||
HANDLE thread;
|
||||
|
||||
free(config);
|
||||
|
||||
if (WSAStartup(wsa_version, &wsa_data) != 0)
|
||||
{
|
||||
error("failed to start WSA (%d)", GetLastError());
|
||||
}
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == INVALID_SOCKET)
|
||||
{
|
||||
error("failed to create socket (%d)", WSAGetLastError());
|
||||
}
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(int))
|
||||
== SOCKET_ERROR)
|
||||
{
|
||||
error("failed to re-use address (%d)", GetLastError());
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(proxy_port);
|
||||
if (bind(s, (SOCKADDR *)&addr, sizeof(addr)) == SOCKET_ERROR)
|
||||
{
|
||||
error("failed to bind socket (%d)", WSAGetLastError());
|
||||
}
|
||||
|
||||
if (listen(s, 16) == SOCKET_ERROR)
|
||||
{
|
||||
error("failed to listen socket (%d)", WSAGetLastError());
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
// Wait for a new connection.
|
||||
PPROXY_CONNECTION_CONFIG config;
|
||||
int size = sizeof(addr);
|
||||
SOCKET t = accept(s, (SOCKADDR *)&addr, &size);
|
||||
if (t == INVALID_SOCKET)
|
||||
{
|
||||
warning("failed to accept socket (%d)", WSAGetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Spawn proxy connection handler thread.
|
||||
config = (PPROXY_CONNECTION_CONFIG)
|
||||
malloc(sizeof(PROXY_CONNECTION_CONFIG));
|
||||
if (config == NULL)
|
||||
{
|
||||
error("failed to allocate memory");
|
||||
}
|
||||
config->s = t;
|
||||
config->alt_port = alt_port;
|
||||
config->dest = addr.sin_addr;
|
||||
thread = CreateThread(NULL, 1,
|
||||
(LPTHREAD_START_ROUTINE)proxy_connection_handler,
|
||||
(LPVOID)config, 0, NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
warning("failed to create thread (%d)", GetLastError());
|
||||
closesocket(t);
|
||||
free(config);
|
||||
continue;
|
||||
}
|
||||
CloseHandle(thread);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Proxy connection handler thread.
|
||||
*/
|
||||
static DWORD proxy_connection_handler(LPVOID arg)
|
||||
{
|
||||
PPROXY_TRANSFER_CONFIG config1, config2;
|
||||
HANDLE thread;
|
||||
PPROXY_CONNECTION_CONFIG config = (PPROXY_CONNECTION_CONFIG)arg;
|
||||
SOCKET s = config->s, t;
|
||||
UINT16 alt_port = config->alt_port;
|
||||
struct in_addr dest = config->dest;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
free(config);
|
||||
|
||||
t = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (t == INVALID_SOCKET)
|
||||
{
|
||||
warning("failed to create socket (%d)", WSAGetLastError());
|
||||
closesocket(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(alt_port);
|
||||
addr.sin_addr = dest;
|
||||
if (connect(t, (SOCKADDR *)&addr, sizeof(addr)) == SOCKET_ERROR)
|
||||
{
|
||||
warning("failed to connect socket (%d)", WSAGetLastError());
|
||||
closesocket(s);
|
||||
closesocket(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
config1 = (PPROXY_TRANSFER_CONFIG)malloc(sizeof(PROXY_TRANSFER_CONFIG));
|
||||
config2 = (PPROXY_TRANSFER_CONFIG)malloc(sizeof(PROXY_TRANSFER_CONFIG));
|
||||
if (config1 == NULL || config2 == NULL)
|
||||
{
|
||||
error("failed to allocate memory");
|
||||
}
|
||||
config1->inbound = FALSE;
|
||||
config2->inbound = TRUE;
|
||||
config2->t = config1->s = s;
|
||||
config2->s = config1->t = t;
|
||||
thread = CreateThread(NULL, 1,
|
||||
(LPTHREAD_START_ROUTINE)proxy_transfer_handler, (LPVOID)config1, 0,
|
||||
NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
warning("failed to create thread (%d)", GetLastError());
|
||||
closesocket(s);
|
||||
closesocket(t);
|
||||
free(config1);
|
||||
free(config2);
|
||||
return 0;
|
||||
}
|
||||
proxy_transfer_handler((LPVOID)config2);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
closesocket(s);
|
||||
closesocket(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the transfer of data from one socket to another.
|
||||
*/
|
||||
static DWORD proxy_transfer_handler(LPVOID arg)
|
||||
{
|
||||
PPROXY_TRANSFER_CONFIG config = (PPROXY_TRANSFER_CONFIG)arg;
|
||||
BOOL inbound = config->inbound;
|
||||
SOCKET s = config->s, t = config->t;
|
||||
char buf[8192];
|
||||
int len, len2, i;
|
||||
HANDLE console;
|
||||
|
||||
free(config);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
// Read data from s.
|
||||
len = recv(s, buf, sizeof(buf), 0);
|
||||
if (len == SOCKET_ERROR)
|
||||
{
|
||||
warning("failed to recv from socket (%d)", WSAGetLastError());
|
||||
shutdown(s, SD_BOTH);
|
||||
shutdown(t, SD_BOTH);
|
||||
return 0;
|
||||
}
|
||||
if (len == 0)
|
||||
{
|
||||
shutdown(s, SD_RECEIVE);
|
||||
shutdown(t, SD_SEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Dump stream information to the screen.
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
WaitForSingleObject(lock, INFINITE);
|
||||
printf("[%.4d] ", len);
|
||||
SetConsoleTextAttribute(console,
|
||||
(inbound? FOREGROUND_RED: FOREGROUND_GREEN));
|
||||
for (i = 0; i < len && i < MAX_LINE; i++)
|
||||
{
|
||||
putchar((isprint(buf[i])? buf[i]: '.'));
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
printf("%s\n", (len > MAX_LINE? "...": ""));
|
||||
ReleaseMutex(lock);
|
||||
|
||||
// Send data to t.
|
||||
for (i = 0; i < len; )
|
||||
{
|
||||
len2 = send(t, buf+i, len-i, 0);
|
||||
if (len2 == SOCKET_ERROR)
|
||||
{
|
||||
warning("failed to send to socket (%d)", WSAGetLastError());
|
||||
shutdown(s, SD_BOTH);
|
||||
shutdown(t, SD_BOTH);
|
||||
return 0;
|
||||
}
|
||||
i += len2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
@@ -1,36 +0,0 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
!IF "$(_BUILDARCH)" == "x86"
|
||||
CPU=i386
|
||||
!ELSE
|
||||
CPU=$(_BUILDARCH)
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=webfilter
|
||||
TARGETTYPE=PROGRAM
|
||||
TARGETPATH=..\..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
$(SDK_LIB_PATH)\setupapi.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\ws2_32.lib \
|
||||
$(TARGETPATH)\$(CPU)\WinDivert.lib
|
||||
UMTYPE=console
|
||||
UMENTRY=main
|
||||
USE_MSVCRT=1
|
||||
INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\..\include
|
||||
SOURCES=webfilter.c
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* webfilter.c
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -26,13 +42,17 @@
|
||||
* blockpage to the browser.
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define ntohs(x) WinDivertHelperNtohs(x)
|
||||
#define ntohl(x) WinDivertHelperNtohl(x)
|
||||
#define htons(x) WinDivertHelperHtons(x)
|
||||
#define htonl(x) WinDivertHelperHtonl(x)
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define MAXURL 4096
|
||||
|
||||
@@ -160,6 +180,7 @@ int __cdecl main(int argc, char **argv)
|
||||
// Open the Divert device:
|
||||
handle = WinDivertOpen(
|
||||
"outbound && " // Outbound traffic only
|
||||
"!loopback && " // No loopback traffic
|
||||
"ip && " // Only IPv4 supported
|
||||
"tcp.DstPort == 80 && " // HTTP (port 80) only
|
||||
"tcp.PayloadLength > 0", // TCP data packets only
|
||||
@@ -207,7 +228,7 @@ int __cdecl main(int argc, char **argv)
|
||||
reset->tcp.DstPort = htons(80);
|
||||
reset->tcp.SeqNum = tcp_header->SeqNum;
|
||||
reset->tcp.AckNum = tcp_header->AckNum;
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
|
||||
@@ -221,8 +242,8 @@ int __cdecl main(int argc, char **argv)
|
||||
blockpage->header.tcp.SeqNum = tcp_header->AckNum;
|
||||
blockpage->header.tcp.AckNum =
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len);
|
||||
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0);
|
||||
addr.Direction = !addr.Direction; // Reverse direction.
|
||||
addr.Outbound = !addr.Outbound; // Reverse direction.
|
||||
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
|
||||
NULL))
|
||||
{
|
||||
@@ -240,7 +261,7 @@ int __cdecl main(int argc, char **argv)
|
||||
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
|
||||
finish->tcp.AckNum =
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len);
|
||||
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<TARGETNAME>webfilter</TARGETNAME>
|
||||
<Configuration>Release</Configuration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\install\MSVC\WinDivert.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="webfilter.c"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
</Project>
|
||||
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* windivertctl.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* usage: windivertctl.exe list
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAX_PACKET 0xFFFF
|
||||
#define MAX_FILTER_LEN 30000
|
||||
|
||||
/*
|
||||
* Process info.
|
||||
*/
|
||||
typedef struct INFO
|
||||
{
|
||||
UINT32 process_id;
|
||||
UINT32 ref_count;
|
||||
HANDLE process;
|
||||
struct INFO *next;
|
||||
} INFO, *PINFO;
|
||||
|
||||
static INFO *open = NULL; // All open handles
|
||||
|
||||
/*
|
||||
* Modes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LIST,
|
||||
WATCH,
|
||||
KILLALL
|
||||
} MODE;
|
||||
|
||||
/*
|
||||
* Add a new process.
|
||||
*/
|
||||
static HANDLE add_process(UINT32 process_id)
|
||||
{
|
||||
PINFO info = open;
|
||||
HANDLE process;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
if (info->process_id == process_id)
|
||||
{
|
||||
info->ref_count++;
|
||||
return info->process;
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
|
||||
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE,
|
||||
FALSE, process_id);
|
||||
info = (INFO *)malloc(sizeof(INFO));
|
||||
if (info == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to allocate memory (%d)\n",
|
||||
GetLastError());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
info->process_id = process_id;
|
||||
info->process = process;
|
||||
info->ref_count = 1;
|
||||
info->next = open;
|
||||
open = info;
|
||||
return process;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup a process.
|
||||
*/
|
||||
static HANDLE lookup_process(UINT32 process_id)
|
||||
{
|
||||
PINFO info = open;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
if (info->process_id == process_id)
|
||||
{
|
||||
return info->process;
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an old process.
|
||||
*/
|
||||
static void remove_process(UINT32 process_id)
|
||||
{
|
||||
PINFO info = open, prev = NULL;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
if (info->process_id == process_id)
|
||||
{
|
||||
info->ref_count--;
|
||||
if (info->ref_count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = info;
|
||||
info = info->next;
|
||||
}
|
||||
|
||||
if (info->process != NULL)
|
||||
{
|
||||
CloseHandle(info->process);
|
||||
}
|
||||
if (prev != NULL)
|
||||
{
|
||||
prev->next = info->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
open = info->next;
|
||||
}
|
||||
free(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, process, console;
|
||||
INT16 priority = -333; // Arbitrary.
|
||||
UINT packet_len;
|
||||
static UINT8 packet[MAX_PACKET];
|
||||
static char path[MAX_PATH+1];
|
||||
static char filter_str[MAX_FILTER_LEN];
|
||||
PVOID object;
|
||||
DWORD path_len;
|
||||
BOOL or;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
ULONGLONG freq, start_count;
|
||||
LARGE_INTEGER li;
|
||||
MODE mode;
|
||||
const char *filter = "true";
|
||||
const char *err_str = NULL;
|
||||
|
||||
if (argc != 2 && argc != 3)
|
||||
{
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s (list|watch|killall) [filter]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (strcmp(argv[1], "list") == 0)
|
||||
{
|
||||
mode = LIST;
|
||||
}
|
||||
else if (strcmp(argv[1], "watch") == 0)
|
||||
{
|
||||
mode = WATCH;
|
||||
}
|
||||
else if (strcmp(argv[1], "killall") == 0)
|
||||
{
|
||||
mode = KILLALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto usage;
|
||||
}
|
||||
if (argc == 3)
|
||||
{
|
||||
filter = argv[2];
|
||||
}
|
||||
|
||||
// Time management
|
||||
QueryPerformanceFrequency(&li);
|
||||
freq = li.QuadPart;
|
||||
QueryPerformanceCounter(&li);
|
||||
start_count = li.QuadPart;
|
||||
|
||||
// Open WinDivert REFLECT handle:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_REFLECT, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY |
|
||||
(mode == WATCH? 0: WINDIVERT_FLAG_NO_INSTALL));
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (mode != WATCH && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
|
||||
{
|
||||
// WinDivert driver is not running, so no open handles.
|
||||
return 0;
|
||||
}
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_FLOW,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (mode != WATCH && !WinDivertShutdown(handle, WINDIVERT_SHUTDOWN_BOTH))
|
||||
{
|
||||
fprintf(stderr, "error: failed to shutdown WinDivert handle (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Main loop:
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
while (TRUE)
|
||||
{
|
||||
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
|
||||
{
|
||||
if (mode != WATCH && GetLastError() == ERROR_NO_DATA)
|
||||
{
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "failed to event (%d)\n", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (addr.Event)
|
||||
{
|
||||
case WINDIVERT_EVENT_REFLECT_OPEN:
|
||||
// Open handle:
|
||||
process = add_process(addr.Reflect.ProcessId);
|
||||
if (mode == KILLALL)
|
||||
{
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
fputs("KILL", stdout);
|
||||
TerminateProcess(process, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
fputs("OPEN", stdout);
|
||||
}
|
||||
break;
|
||||
|
||||
case WINDIVERT_EVENT_REFLECT_CLOSE:
|
||||
// Close handle:
|
||||
if (mode != WATCH)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
process = lookup_process(addr.Reflect.ProcessId);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
fputs("CLOSE", stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
fputs("???", stdout);
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" time=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%.3fs", (double)(addr.Reflect.Timestamp - (INT64)start_count) /
|
||||
(double)freq);
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" pid=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%u", addr.Reflect.ProcessId);
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" exe=", stdout);
|
||||
path_len = 0;
|
||||
if (process != NULL)
|
||||
{
|
||||
path_len = GetProcessImageFileName(process, path, sizeof(path));
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%s", (path_len != 0? path: "???"));
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" layer=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
switch (addr.Reflect.Layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
fputs("NETWORK", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
fputs("NETWORK_FORWARD", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
fputs("FLOW", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
fputs("SOCKET", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
fputs("REFLECT", stdout);
|
||||
break;
|
||||
default:
|
||||
fputs("???", stdout);
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" flags=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
if (addr.Reflect.Flags == 0)
|
||||
{
|
||||
fputs("0", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
or = FALSE;
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_SNIFF) != 0)
|
||||
{
|
||||
fputs("SNIFF", stdout);
|
||||
or = TRUE;
|
||||
}
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_DROP) != 0)
|
||||
{
|
||||
printf("%sDROP", (or? "|": ""));
|
||||
or = TRUE;
|
||||
}
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_RECV_ONLY) != 0)
|
||||
{
|
||||
printf("%sRECV_ONLY", (or? "|": ""));
|
||||
or = TRUE;
|
||||
}
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_SEND_ONLY) != 0)
|
||||
{
|
||||
printf("%sSEND_ONLY", (or? "|": ""));
|
||||
or = TRUE;
|
||||
}
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_RECV_PARTIAL) != 0)
|
||||
{
|
||||
printf("%sRECV_PARTIAL", (or? "|": ""));
|
||||
or = TRUE;
|
||||
}
|
||||
if ((addr.Reflect.Flags & WINDIVERT_FLAG_NO_INSTALL) != 0)
|
||||
{
|
||||
printf("%sNO_INSTALL", (or? "|": ""));
|
||||
or = TRUE;
|
||||
}
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" priority=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%d", addr.Reflect.Priority);
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
fputs(" filter=", stdout);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
WinDivertHelperParsePacket(packet, packet_len, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &object, NULL);
|
||||
if (WinDivertHelperFormatFilter((char *)object, addr.Reflect.Layer,
|
||||
filter_str, sizeof(filter_str)))
|
||||
{
|
||||
printf("\"%s\"", filter_str);
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
putchar('\n');
|
||||
|
||||
if (addr.Event == WINDIVERT_EVENT_REFLECT_CLOSE)
|
||||
{
|
||||
remove_process(addr.Reflect.ProcessId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!WinDivertClose(handle))
|
||||
{
|
||||
fprintf(stderr, "error: failed to close WinDivert handle (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+241
-120
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* windivert.h
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __WINDIVERT_H
|
||||
@@ -29,6 +45,7 @@
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define __in
|
||||
#define __in_opt
|
||||
#define __out
|
||||
#define __out_opt
|
||||
#define __inout
|
||||
@@ -53,43 +70,139 @@ extern "C" {
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Divert address.
|
||||
* WinDivert layers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD = 1,/* Network layer (forwarded packets) */
|
||||
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
|
||||
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
|
||||
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
|
||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
||||
|
||||
/*
|
||||
* WinDivert NETWORK and NETWORK_FORWARD layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 IfIdx; /* Packet's interface index. */
|
||||
UINT32 SubIfIdx; /* Packet's sub-interface index. */
|
||||
UINT8 Direction; /* Packet's direction. */
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
|
||||
#define WINDIVERT_DIRECTION_OUTBOUND 0
|
||||
#define WINDIVERT_DIRECTION_INBOUND 1
|
||||
} WINDIVERT_DATA_NETWORK, *PWINDIVERT_DATA_NETWORK;
|
||||
|
||||
/*
|
||||
* Divert layers.
|
||||
* WinDivert FLOW layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
UINT16 LocalPort; /* Local port. */
|
||||
UINT16 RemotePort; /* Remote port. */
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_DATA_FLOW, *PWINDIVERT_DATA_FLOW;
|
||||
|
||||
/*
|
||||
* WinDivert SOCKET layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
UINT16 LocalPort; /* Local port. */
|
||||
UINT16 RemotePort; /* Remote port. */
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_DATA_SOCKET, *PWINDIVERT_DATA_SOCKET;
|
||||
|
||||
/*
|
||||
* WinDivert REFLECTION layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp; /* Handle open time. */
|
||||
UINT32 ProcessId; /* Handle process ID. */
|
||||
WINDIVERT_LAYER Layer; /* Handle layer. */
|
||||
UINT64 Flags; /* Handle flags. */
|
||||
INT16 Priority; /* Handle priority. */
|
||||
} WINDIVERT_DATA_REFLECT, *PWINDIVERT_DATA_REFLECT;
|
||||
|
||||
/*
|
||||
* WinDivert address.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp; /* Packet's timestamp. */
|
||||
UINT64 Layer:8; /* Packet's layer. */
|
||||
UINT64 Event:8; /* Packet event. */
|
||||
UINT64 Outbound:1; /* Packet is outound? */
|
||||
UINT64 Loopback:1; /* Packet is loopback? */
|
||||
UINT64 Impostor:1; /* Packet is impostor? */
|
||||
UINT64 IPv6:1; /* Packet is IPv6? */
|
||||
UINT64 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
|
||||
UINT64 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
|
||||
UINT64 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
|
||||
UINT64 Reserved:41;
|
||||
union
|
||||
{
|
||||
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
|
||||
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
|
||||
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
|
||||
WINDIVERT_DATA_REFLECT Reflect; /* Reflect layer data. */
|
||||
};
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
|
||||
/*
|
||||
* WinDivert events.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */
|
||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
||||
WINDIVERT_EVENT_NETWORK_PACKET = 0, /* Network packet. */
|
||||
WINDIVERT_EVENT_FLOW_ESTABLISHED = 1,
|
||||
/* Flow established. */
|
||||
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
|
||||
WINDIVERT_EVENT_SOCKET_BIND = 3, /* Socket bind. */
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN = 4, /* Socket listen. */
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT = 5, /* Socket connect. */
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT = 6, /* Socket accept. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 7, /* WinDivert handle opened. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 8, /* WinDivert handle closed. */
|
||||
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
|
||||
|
||||
/*
|
||||
* Divert flags.
|
||||
* WinDivert flags.
|
||||
*/
|
||||
#define WINDIVERT_FLAG_SNIFF 1
|
||||
#define WINDIVERT_FLAG_DROP 2
|
||||
#define WINDIVERT_FLAG_NO_CHECKSUM 1024
|
||||
#define WINDIVERT_FLAG_SNIFF 0x0001
|
||||
#define WINDIVERT_FLAG_DROP 0x0002
|
||||
#define WINDIVERT_FLAG_RECV_ONLY 0x0004
|
||||
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
|
||||
#define WINDIVERT_FLAG_SEND_ONLY 0x0008
|
||||
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
|
||||
#define WINDIVERT_FLAG_RECV_PARTIAL 0x0010
|
||||
#define WINDIVERT_FLAG_NO_INSTALL 0x0020
|
||||
|
||||
/*
|
||||
* Divert parameters.
|
||||
* WinDivert parameters.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_PARAM_QUEUE_LEN = 0, /* Packet queue length. */
|
||||
WINDIVERT_PARAM_QUEUE_TIME = 1 /* Packet queue time. */
|
||||
WINDIVERT_PARAM_QUEUE_TIME = 1, /* Packet queue time. */
|
||||
WINDIVERT_PARAM_QUEUE_SIZE = 2, /* Packet queue size. */
|
||||
} WINDIVERT_PARAM, *PWINDIVERT_PARAM;
|
||||
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_QUEUE_TIME
|
||||
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_QUEUE_SIZE
|
||||
|
||||
/*
|
||||
* WinDivert shutdown parameter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_SHUTDOWN_RECV = 0x1, /* Shutdown recv. */
|
||||
WINDIVERT_SHUTDOWN_SEND = 0x2, /* Shutdown send. */
|
||||
WINDIVERT_SHUTDOWN_BOTH = 0x3, /* Shutdown recv and send. */
|
||||
} WINDIVERT_SHUTDOWN, *PWINDIVERT_SHUTDOWN;
|
||||
#define WINDIVERT_SHUTDOWN_MAX WINDIVERT_SHUTDOWN_BOTH
|
||||
|
||||
#ifndef WINDIVERT_KERNEL
|
||||
|
||||
@@ -107,10 +220,10 @@ extern WINDIVERTEXPORT HANDLE WinDivertOpen(
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertRecv(
|
||||
__in HANDLE handle,
|
||||
__out PVOID pPacket,
|
||||
__out VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PWINDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *readLen);
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr,
|
||||
__out_opt UINT *pReadLen);
|
||||
|
||||
/*
|
||||
* Receive (read) a packet from a WinDivert handle.
|
||||
@@ -119,9 +232,10 @@ extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
|
||||
__in HANDLE handle,
|
||||
__out PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pReadLen,
|
||||
__in UINT64 flags,
|
||||
__out_opt PWINDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *readLen,
|
||||
__out WINDIVERT_ADDRESS *pAddr,
|
||||
__inout_opt UINT *pAddrLen,
|
||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
||||
|
||||
/*
|
||||
@@ -129,23 +243,31 @@ extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertSend(
|
||||
__in HANDLE handle,
|
||||
__in PVOID pPacket,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in PWINDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *writeLen);
|
||||
__in const WINDIVERT_ADDRESS *pAddr,
|
||||
__out_opt UINT *pWriteLen);
|
||||
|
||||
/*
|
||||
* Send (write/inject) a packet to a WinDivert handle.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertSendEx(
|
||||
__in HANDLE handle,
|
||||
__in PVOID pPacket,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pWriteLen,
|
||||
__in UINT64 flags,
|
||||
__in PWINDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *writeLen,
|
||||
__in const WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT addrLen,
|
||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
||||
|
||||
/*
|
||||
* Shutdown a WinDivert handle.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertShutdown(
|
||||
__in HANDLE handle,
|
||||
__in WINDIVERT_SHUTDOWN how);
|
||||
|
||||
/*
|
||||
* Close a WinDivert handle.
|
||||
*/
|
||||
@@ -168,6 +290,8 @@ extern WINDIVERTEXPORT BOOL WinDivertGetParam(
|
||||
__in WINDIVERT_PARAM param,
|
||||
__out UINT64 *pValue);
|
||||
|
||||
#endif /* WINDIVERT_KERNEL */
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT HELPER API */
|
||||
/****************************************************************************/
|
||||
@@ -307,7 +431,7 @@ typedef struct
|
||||
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
|
||||
|
||||
/*
|
||||
* Flags for DivertHelperCalcChecksums()
|
||||
* Flags for WinDivertHelperCalcChecksums()
|
||||
*/
|
||||
#define WINDIVERT_HELPER_NO_IP_CHECKSUM 1
|
||||
#define WINDIVERT_HELPER_NO_ICMP_CHECKSUM 2
|
||||
@@ -315,11 +439,25 @@ typedef struct
|
||||
#define WINDIVERT_HELPER_NO_TCP_CHECKSUM 8
|
||||
#define WINDIVERT_HELPER_NO_UDP_CHECKSUM 16
|
||||
|
||||
#ifndef WINDIVERT_KERNEL
|
||||
|
||||
/*
|
||||
* Hash a packet.
|
||||
*/
|
||||
extern WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in UINT64 seed
|
||||
#ifdef __cplusplus
|
||||
= 0
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
||||
__in PVOID pPacket,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
@@ -344,98 +482,81 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
|
||||
__in UINT32 addr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Format an IPv6 address.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
|
||||
__in const UINT32 *pAddr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
extern WINDIVERTEXPORT UINT WinDivertHelperCalcChecksums(
|
||||
__inout PVOID pPacket,
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in_opt const WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT64 flags);
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT LEGACY API */
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Deprecated API:
|
||||
* Compile the given filter string.
|
||||
*/
|
||||
typedef WINDIVERT_ADDRESS DIVERT_ADDRESS;
|
||||
typedef PWINDIVERT_ADDRESS PDIVERT_ADDRESS;
|
||||
#define DIVERT_DIRECTION_OUTBOUND WINDIVERT_DIRECTION_OUTBOUND
|
||||
#define DIVERT_DIRECTION_INBOUND WINDIVERT_DIRECTION_INBOUND
|
||||
typedef WINDIVERT_LAYER DIVERT_LAYER;
|
||||
typedef PWINDIVERT_LAYER PDIVERT_LAYER;
|
||||
#define DIVERT_FLAG_SNIFF WINDIVERT_FLAG_SNIFF
|
||||
#define DIVERT_FLAG_DROP WINDIVERT_FLAG_DROP
|
||||
typedef WINDIVERT_PARAM DIVERT_PARAM;
|
||||
typedef PWINDIVERT_PARAM PDIVERT_PARAM;
|
||||
typedef WINDIVERT_IPHDR DIVERT_IPHDR;
|
||||
typedef PWINDIVERT_IPHDR PDIVERT_IPHDR;
|
||||
typedef WINDIVERT_IPV6HDR DIVERT_IPV6HDR;
|
||||
typedef PWINDIVERT_IPV6HDR PDIVERT_IPV6HDR;
|
||||
typedef WINDIVERT_ICMPHDR DIVERT_ICMPHDR;
|
||||
typedef PWINDIVERT_ICMPHDR PDIVERT_ICMPHDR;
|
||||
typedef WINDIVERT_ICMPV6HDR DIVERT_ICMPV6HDR;
|
||||
typedef PWINDIVERT_ICMPV6HDR PDIVERT_ICMPV6HDR;
|
||||
typedef WINDIVERT_TCPHDR DIVERT_TCPHDR;
|
||||
typedef PWINDIVERT_TCPHDR PDIVERT_TCPHDR;
|
||||
typedef WINDIVERT_UDPHDR DIVERT_UDPHDR;
|
||||
typedef PWINDIVERT_UDPHDR PDIVERT_UDPHDR;
|
||||
#define DIVERT_HELPER_NO_IP_CHECKSUM WINDIVERT_HELPER_NO_IP_CHECKSUM
|
||||
#define DIVERT_HELPER_NO_ICMP_CHECKSUM WINDIVERT_HELPER_NO_ICMP_CHECKSUM
|
||||
#define DIVERT_HELPER_NO_ICMPV6_CHECKSUM WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM
|
||||
#define DIVERT_HELPER_NO_TCP_CHECKSUM WINDIVERT_HELPER_NO_TCP_CHECKSUM
|
||||
#define DIVERT_HELPER_NO_UDP_CHECKSUM WINDIVERT_HELPER_NO_UDP_CHECKSUM
|
||||
|
||||
extern WINDIVERTEXPORT HANDLE DivertOpen(
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
|
||||
__in const char *filter,
|
||||
__in DIVERT_LAYER layer,
|
||||
__in INT16 priority,
|
||||
__in UINT64 flags);
|
||||
extern WINDIVERTEXPORT BOOL DivertRecv(
|
||||
__in HANDLE handle,
|
||||
__out PVOID pPacket,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt char *object,
|
||||
__in UINT objLen,
|
||||
__out_opt const char **errorStr,
|
||||
__out_opt UINT *errorPos);
|
||||
|
||||
/*
|
||||
* Evaluate the given filter string.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
|
||||
__in const char *filter,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *readLen);
|
||||
extern WINDIVERTEXPORT BOOL DivertSend(
|
||||
__in HANDLE handle,
|
||||
__in PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__in PDIVERT_ADDRESS pAddr,
|
||||
__out_opt UINT *writeLen);
|
||||
extern WINDIVERTEXPORT BOOL DivertClose(
|
||||
__in HANDLE handle);
|
||||
extern WINDIVERTEXPORT BOOL DivertSetParam(
|
||||
__in HANDLE handle,
|
||||
__in DIVERT_PARAM param,
|
||||
__in UINT64 value);
|
||||
extern WINDIVERTEXPORT BOOL DivertGetParam(
|
||||
__in HANDLE handle,
|
||||
__in DIVERT_PARAM param,
|
||||
__out UINT64 *pValue);
|
||||
extern WINDIVERTEXPORT BOOL DivertHelperParsePacket(
|
||||
__in PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
__out_opt PDIVERT_ICMPHDR *ppIcmpHdr,
|
||||
__out_opt PDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
||||
__out_opt PDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen);
|
||||
extern WINDIVERTEXPORT BOOL DivertHelperParseIPv4Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
extern WINDIVERTEXPORT BOOL DivertHelperParseIPv6Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
extern WINDIVERTEXPORT UINT DivertHelperCalcChecksums(
|
||||
__inout PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__in UINT64 flags);
|
||||
__in const WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
* Format the given filter string.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Byte ordering.
|
||||
*/
|
||||
extern WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
|
||||
__in UINT16 x);
|
||||
extern WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
|
||||
__in UINT16 x);
|
||||
extern WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
|
||||
__in UINT32 x);
|
||||
extern WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
|
||||
__in UINT32 x);
|
||||
extern WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
|
||||
__in UINT64 x);
|
||||
extern WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
|
||||
__in UINT64 x);
|
||||
extern WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
extern WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
|
||||
#endif /* WINDIVERT_KERNEL */
|
||||
|
||||
|
||||
+133
-53
@@ -1,26 +1,42 @@
|
||||
/*
|
||||
* windivert_device.h
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __WINDIVERT_DEVICE_H
|
||||
#define __WINDIVERT_DEVICE_H
|
||||
|
||||
/*
|
||||
* NOTE: This is the low-level interface to the divert device driver.
|
||||
* NOTE: This is the low-level interface to the WinDivert device driver.
|
||||
* This interface should not be used directly, instead use the high-level
|
||||
* interface provided by the divert API.
|
||||
*/
|
||||
@@ -28,8 +44,8 @@
|
||||
#define WINDIVERT_KERNEL
|
||||
#include "windivert.h"
|
||||
|
||||
#define WINDIVERT_VERSION 1
|
||||
#define WINDIVERT_VERSION_MINOR 1
|
||||
#define WINDIVERT_VERSION 2
|
||||
#define WINDIVERT_VERSION_MINOR 0
|
||||
|
||||
#define WINDIVERT_STR2(s) #s
|
||||
#define WINDIVERT_STR(s) WINDIVERT_STR2(s)
|
||||
@@ -43,9 +59,6 @@
|
||||
#define WINDIVERT_DEVICE_NAME \
|
||||
L"WinDivert" WINDIVERT_VERSION_LSTR
|
||||
|
||||
#define WINDIVERT_IOCTL_VERSION 3
|
||||
#define WINDIVERT_IOCTL_MAGIC 0xE8D3
|
||||
|
||||
#define WINDIVERT_FILTER_FIELD_ZERO 0
|
||||
#define WINDIVERT_FILTER_FIELD_INBOUND 1
|
||||
#define WINDIVERT_FILTER_FIELD_OUTBOUND 2
|
||||
@@ -104,8 +117,30 @@
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_LENGTH 55
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_CHECKSUM 56
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57
|
||||
#define WINDIVERT_FILTER_FIELD_LOOPBACK 58
|
||||
#define WINDIVERT_FILTER_FIELD_IMPOSTOR 59
|
||||
#define WINDIVERT_FILTER_FIELD_PROCESSID 60
|
||||
#define WINDIVERT_FILTER_FIELD_LOCALADDR 61
|
||||
#define WINDIVERT_FILTER_FIELD_REMOTEADDR 62
|
||||
#define WINDIVERT_FILTER_FIELD_LOCALPORT 63
|
||||
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
|
||||
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
|
||||
#define WINDIVERT_FILTER_FIELD_LAYER 66
|
||||
#define WINDIVERT_FILTER_FIELD_EVENT 67
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET 68
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET16 69
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET32 70
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 71
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 72
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 73
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 74
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 75
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 76
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM8 77
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM16 78
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM32 79
|
||||
#define WINDIVERT_FILTER_FIELD_MAX \
|
||||
WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH
|
||||
WINDIVERT_FILTER_FIELD_RANDOM32
|
||||
|
||||
#define WINDIVERT_FILTER_TEST_EQ 0
|
||||
#define WINDIVERT_FILTER_TEST_NEQ 1
|
||||
@@ -115,7 +150,7 @@
|
||||
#define WINDIVERT_FILTER_TEST_GEQ 5
|
||||
#define WINDIVERT_FILTER_TEST_MAX WINDIVERT_FILTER_TEST_GEQ
|
||||
|
||||
#define WINDIVERT_FILTER_MAXLEN 128
|
||||
#define WINDIVERT_FILTER_MAXLEN (0xFF-2)
|
||||
|
||||
#define WINDIVERT_FILTER_RESULT_ACCEPT (WINDIVERT_FILTER_MAXLEN+1)
|
||||
#define WINDIVERT_FILTER_RESULT_REJECT (WINDIVERT_FILTER_MAXLEN+2)
|
||||
@@ -124,84 +159,129 @@
|
||||
* WinDivert layers.
|
||||
*/
|
||||
#define WINDIVERT_LAYER_DEFAULT WINDIVERT_LAYER_NETWORK
|
||||
#define WINDIVERT_LAYER_MAX \
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD
|
||||
#define WINDIVERT_LAYER_MAX WINDIVERT_LAYER_REFLECT
|
||||
|
||||
/*
|
||||
* WinDivert events.
|
||||
*/
|
||||
#define WINDIVERT_EVENT_MAX \
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE
|
||||
|
||||
/*
|
||||
* WinDivert flags.
|
||||
*/
|
||||
#define WINDIVERT_FLAGS_ALL \
|
||||
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | \
|
||||
WINDIVERT_FLAG_NO_CHECKSUM)
|
||||
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\
|
||||
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_RECV_PARTIAL | \
|
||||
WINDIVERT_FLAG_NO_INSTALL)
|
||||
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
|
||||
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
|
||||
#define WINDIVERT_FLAGS_VALID(flags) \
|
||||
((((flags) & ~WINDIVERT_FLAGS_ALL) == 0) && \
|
||||
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \
|
||||
WINDIVERT_FLAG_DROP))
|
||||
WINDIVERT_FLAG_DROP) && \
|
||||
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_ONLY, \
|
||||
WINDIVERT_FLAG_SEND_ONLY) && \
|
||||
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_PARTIAL, \
|
||||
WINDIVERT_FLAG_SEND_ONLY))
|
||||
|
||||
/*
|
||||
* WinDivert filter flags.
|
||||
*/
|
||||
#define WINDIVERT_FILTER_FLAG_INBOUND 0x0000000000000001ull
|
||||
#define WINDIVERT_FILTER_FLAG_OUTBOUND 0x0000000000000002ull
|
||||
#define WINDIVERT_FILTER_FLAG_IP 0x0000000000000004ull
|
||||
#define WINDIVERT_FILTER_FLAG_IPV6 0x0000000000000008ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED 0x0000000000000010ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND 0x0000000000000020ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT 0x0000000000000040ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN 0x0000000000000080ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT 0x0000000000000100ull
|
||||
|
||||
#define WINDIVERT_FILTER_FLAGS_ALL \
|
||||
(WINDIVERT_FILTER_FLAG_INBOUND | WINDIVERT_FILTER_FLAG_OUTBOUND | \
|
||||
WINDIVERT_FILTER_FLAG_IP | WINDIVERT_FILTER_FLAG_IPV6 | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT)
|
||||
|
||||
/*
|
||||
* WinDivert priorities.
|
||||
*/
|
||||
#define WINDIVERT_PRIORITY(priority16) \
|
||||
((UINT32)((INT32)(priority16) + 0x7FFF + 1))
|
||||
#define WINDIVERT_PRIORITY_DEFAULT WINDIVERT_PRIORITY(0)
|
||||
#define WINDIVERT_PRIORITY_MAX WINDIVERT_PRIORITY(1000)
|
||||
#define WINDIVERT_PRIORITY_DEFAULT 0
|
||||
#define WINDIVERT_PRIORITY_MAX 30000
|
||||
#define WINDIVERT_PRIORITY_MIN -WINDIVERT_PRIORITY_MAX
|
||||
|
||||
/*
|
||||
* WinDivert parameters.
|
||||
*/
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_DEFAULT 1024
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_MIN 1
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_MAX 8192
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 512
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MIN 128
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MAX 2048
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_DEFAULT 2048
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_MIN 16
|
||||
#define WINDIVERT_PARAM_QUEUE_LEN_MAX 16384
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 1000 // 1s
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MIN 20 // 20ms
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MAX 8000 // 8s
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MIN 65535 // 64KB
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MAX 33554432 // 32MB
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT 4194304 // 4MB
|
||||
|
||||
/*
|
||||
* WinDivert batch limits.
|
||||
*/
|
||||
#define WINDIVERT_BATCH_MAX 0xFF
|
||||
|
||||
/*
|
||||
* WinDivert message definitions.
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
struct windivert_ioctl_s
|
||||
typedef struct
|
||||
{
|
||||
UINT16 magic; // WINDIVERT_IOCTL_MAGIC
|
||||
UINT8 version; // WINDIVERT_IOCTL_VERSION
|
||||
UINT8 arg8; // 8-bit argument
|
||||
UINT64 arg; // 64-bit argument
|
||||
};
|
||||
typedef struct windivert_ioctl_s *windivert_ioctl_t;
|
||||
UINT64 arg1; // argument #1
|
||||
UINT64 arg2; // argument #2
|
||||
} WINDIVERT_IOCTL, *PWINDIVERT_IOCTL;
|
||||
|
||||
/*
|
||||
* WinDivert IOCTL structures.
|
||||
*/
|
||||
struct windivert_ioctl_filter_s
|
||||
typedef struct
|
||||
{
|
||||
UINT8 field; // WINDIVERT_FILTER_FIELD_IP_*
|
||||
UINT8 field; // WINDIVERT_FILTER_FIELD_*
|
||||
UINT8 test; // WINDIVERT_FILTER_TEST_*
|
||||
UINT16 success; // Success continuation.
|
||||
UINT16 failure; // Fail continuation.
|
||||
UINT8 success; // Success continuation.
|
||||
UINT8 failure; // Fail continuation.
|
||||
UINT32 arg[4]; // Argument.
|
||||
};
|
||||
typedef struct windivert_ioctl_filter_s *windivert_ioctl_filter_t;
|
||||
} WINDIVERT_FILTER, *PWINDIVERT_FILTER;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* IOCTL codes.
|
||||
*/
|
||||
#define IOCTL_WINDIVERT_SHUTDOWN \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x917, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_RECV \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x908, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x918, METHOD_OUT_DIRECT, FILE_READ_DATA)
|
||||
#define IOCTL_WINDIVERT_SEND \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x909, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x919, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_START_FILTER \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91A, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_SET_LAYER \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90B, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91B, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_SET_PRIORITY \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90C, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91C, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_SET_FLAGS \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90D, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91D, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_SET_PARAM \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90E, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91E, METHOD_IN_DIRECT, FILE_READ_DATA | \
|
||||
FILE_WRITE_DATA)
|
||||
#define IOCTL_WINDIVERT_GET_PARAM \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x91F, METHOD_OUT_DIRECT, FILE_READ_DATA)
|
||||
|
||||
#endif /* __WINDIVERT_DEVICE_H */
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = WFPCALLOUTS
|
||||
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
|
||||
Provider = %Basil%
|
||||
CatalogFile = WinDivert32.Cat
|
||||
DriverVer = 01/01/2019,2.0.0
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%
|
||||
|
||||
[SourceDisksFiles]
|
||||
WinDivert32.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12 ; %windir%\system32\drivers
|
||||
WinDivertCalloutDriver.DriverFiles = 12 ; %windir%\system32\drivers
|
||||
|
||||
[DefaultInstall]
|
||||
OptionDesc = %Description%
|
||||
CopyFiles = WinDivertCalloutDriver.DriverFiles
|
||||
|
||||
[DefaultInstall.Services]
|
||||
AddService = %ServiceName%,,WinDivertCalloutDriver.Service
|
||||
|
||||
[DefaultUninstall]
|
||||
DelFiles = WinDivertCalloutDriver.DriverFiles
|
||||
|
||||
[DefaultUninstall.Services]
|
||||
DelService = WinDivertCalloutDriver,0x200 ; SPSVCINST_STOPSERVICE
|
||||
|
||||
[WinDivertCalloutDriver.DriverFiles]
|
||||
WinDivert32.sys,,,0x00000040 ; COPYFLG_OVERWRITE_OLDER_ONLY
|
||||
|
||||
[WinDivertCalloutDriver.Service]
|
||||
DisplayName = %ServiceName%
|
||||
Description = %ServiceDesc%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 0 ; SERVICE_BOOT_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\WinDivert32.sys
|
||||
|
||||
[Strings]
|
||||
%Basil% = "Basil"
|
||||
%DiskName% = "WinDivert Installation Disk"
|
||||
%Description% = "WinDivert Driver"
|
||||
%ServiceName% = "WinDivert"
|
||||
%ServiceDesc% = "WinDivert Driver"
|
||||
@@ -0,0 +1,48 @@
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = WFPCALLOUTS
|
||||
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
|
||||
Provider = %Basil%
|
||||
CatalogFile = WinDivert64.Cat
|
||||
DriverVer = 01/01/2019,2.0.0
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%
|
||||
|
||||
[SourceDisksFiles]
|
||||
WinDivert64.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12 ; %windir%\system32\drivers
|
||||
WinDivertCalloutDriver.DriverFiles = 12 ; %windir%\system32\drivers
|
||||
|
||||
[DefaultInstall]
|
||||
OptionDesc = %Description%
|
||||
CopyFiles = WinDivertCalloutDriver.DriverFiles
|
||||
|
||||
[DefaultInstall.Services]
|
||||
AddService = %ServiceName%,,WinDivertCalloutDriver.Service
|
||||
|
||||
[DefaultUninstall]
|
||||
DelFiles = WinDivertCalloutDriver.DriverFiles
|
||||
|
||||
[DefaultUninstall.Services]
|
||||
DelService = WinDivertCalloutDriver,0x200 ; SPSVCINST_STOPSERVICE
|
||||
|
||||
[WinDivertCalloutDriver.DriverFiles]
|
||||
WinDivert64.sys,,,0x00000040 ; COPYFLG_OVERWRITE_OLDER_ONLY
|
||||
|
||||
[WinDivertCalloutDriver.Service]
|
||||
DisplayName = %ServiceName%
|
||||
Description = %ServiceDesc%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 0 ; SERVICE_BOOT_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\WinDivert64.sys
|
||||
|
||||
[Strings]
|
||||
%Basil% = "Basil"
|
||||
%DiskName% = "WinDivert Installation Disk"
|
||||
%Description% = "WinDivert Driver"
|
||||
%ServiceName% = "WinDivert"
|
||||
%ServiceDesc% = "WinDivert Driver"
|
||||
+66
-25
@@ -1,20 +1,36 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# mingw-build.sh
|
||||
# (C) 2013, all rights reserved,
|
||||
# (C) 2018, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This file is part of WinDivert.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
# WinDivert is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# WinDivert is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Script for MinGW/Linux cross compilation.
|
||||
# NOTE: run wddk-build.bat before this script.
|
||||
@@ -28,48 +44,73 @@ do
|
||||
if [ $ENV = "i686-w64-mingw32" ]
|
||||
then
|
||||
CPU=i386
|
||||
BITS=32
|
||||
MANGLE=_
|
||||
else
|
||||
CPU=amd64
|
||||
BITS=64
|
||||
MANGLE=
|
||||
fi
|
||||
if [ ! -d install/WDDK/$CPU ]
|
||||
then
|
||||
echo "WARNING: missing WDDK build; run wddk-build.bat first"
|
||||
echo "SKIP WDDK-$CPU"
|
||||
echo "SKIP MINGW-$CPU"
|
||||
continue
|
||||
fi
|
||||
echo "BUILD WDDK-$CPU"
|
||||
echo "BUILD MINGW-$CPU"
|
||||
CC="$ENV-gcc"
|
||||
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
|
||||
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
|
||||
CLIBS="-lgcc -lkernel32 -ladvapi32"
|
||||
STRIP="$ENV-strip"
|
||||
DLLTOOL="$ENV-dlltool"
|
||||
if [ -x "`which $CC`" ]
|
||||
then
|
||||
echo "\tmake install/MINGW/$CPU..."
|
||||
mkdir -p "install/MINGW/$CPU"
|
||||
echo "\tbuild install/MINGW/$CPU/WinDivert.dll..."
|
||||
$CC -Wall -O2 -Iinclude/ -c dll/windivert.c -o dll/windivert.o
|
||||
$CC -Wall -shared -o "install/MINGW/$CPU/WinDivert.dll" dll/windivert.o
|
||||
$STRIP --strip-debug "install/MINGW/$CPU/WinDivert.dll"
|
||||
$CC $COPTS -c dll/windivert.c -o dll/windivert.o
|
||||
$CC $COPTS -o "install/MINGW/$CPU/WinDivert.dll" \
|
||||
dll/windivert.o dll/windivert.def -nostdlib $CLIBS
|
||||
$STRIP "install/MINGW/$CPU/WinDivert.dll"
|
||||
echo "\tbuild install/MINGW/$CPU/WinDivert.lib..."
|
||||
$DLLTOOL --dllname install/MINGW/$CPU/WinDivert.dll \
|
||||
--def dll/windivert.def \
|
||||
--output-lib install/MINGW/$CPU/WinDivert.lib 2>/dev/null
|
||||
echo "\tbuild install/MINGW/$CPU/netdump.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/netdump/netdump.c \
|
||||
-o "install/MINGW/$CPU/netdump.exe" -lWinDivert -lws2_32 \
|
||||
-o "install/MINGW/$CPU/netdump.exe" -lWinDivert \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tbuild install/MINGW/$CPU/netfilter.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/netfilter/netfilter.c \
|
||||
-o "install/MINGW/$CPU/netfilter.exe" -lWinDivert -lws2_32 \
|
||||
-o "install/MINGW/$CPU/netfilter.exe" -lWinDivert \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tbuild install/MINGW/$CPU/passthru.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/passthru/passthru.c \
|
||||
-o "install/MINGW/$CPU/passthru.exe" -lWinDivert -lws2_32 \
|
||||
-o "install/MINGW/$CPU/passthru.exe" -lWinDivert \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tbuild install/MINGW/$CPU/webfilter.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/webfilter/webfilter.c \
|
||||
-o "install/MINGW/$CPU/webfilter.exe" -lWinDivert -lws2_32 \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert.inf..."
|
||||
cp install/WDDK/$CPU/WinDivert.inf install/MINGW/$CPU
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert.sys..."
|
||||
cp install/WDDK/$CPU/WinDivert.sys install/MINGW/$CPU
|
||||
echo "\tcopy install/MINGW/$CPU/WdfCoInstaller01009.dll..."
|
||||
cp install/WDDK/$CPU/WdfCoInstaller01009.dll install/MINGW/$CPU
|
||||
-o "install/MINGW/$CPU/webfilter.exe" -lWinDivert \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tbuild install/MINGW/$CPU/streamdump.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/streamdump/streamdump.c \
|
||||
-o "install/MINGW/$CPU/streamdump.exe" -lWinDivert -lws2_32 \
|
||||
-L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/flowtrack.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/flowtrack/flowtrack.c \
|
||||
-o "install/MINGW/$CPU/flowtrack.exe" -lWinDivert -lpsapi \
|
||||
-lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/windivertctl.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/windivertctl/windivertctl.c \
|
||||
-o "install/MINGW/$CPU/windivertctl.exe" -lWinDivert \
|
||||
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/socketdump.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/socketdump/socketdump.c \
|
||||
-o "install/MINGW/$CPU/socketdump.exe" -lWinDivert \
|
||||
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
|
||||
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
|
||||
else
|
||||
echo "WARNING: $CC not found"
|
||||
fi
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
:: msvc-build.bat
|
||||
:: (C) 2013, all rights reserved,
|
||||
::
|
||||
:: This program is free software: you can redistribute it and/or modify
|
||||
:: it under the terms of the GNU Lesser General Public License as published by
|
||||
:: the Free Software Foundation, either version 3 of the License, or
|
||||
:: (at your option) any later version.
|
||||
::
|
||||
:: This program is distributed in the hope that it will be useful,
|
||||
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
:: GNU Lesser General Public License for more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU Lesser General Public License
|
||||
:: along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
::
|
||||
:: Script for MSVC (Microsoft Visual Studio 2010) compilation.
|
||||
:: NOTE: run wddk-build.bat before this script.
|
||||
|
||||
@echo off
|
||||
|
||||
:: Determine target CPU.
|
||||
|
||||
cl 2>&1 | findstr "x86" > NUL
|
||||
|
||||
if %ERRORLEVEL% == 0 (
|
||||
set TARGET=i386
|
||||
set PLATFORM=Win32
|
||||
) ELSE (
|
||||
set TARGET=amd64
|
||||
set PLATFORM=x64
|
||||
)
|
||||
|
||||
set WDDK_INSTALL=install\WDDK\%TARGET%\
|
||||
set MSVC_INSTALL=install\MSVC\%TARGET%\
|
||||
|
||||
if not exist %WDDK_INSTALL% (
|
||||
echo ERROR: Missing WDDK build; run wddk-build.bat first
|
||||
exit /B
|
||||
)
|
||||
mkdir %MSVC_INSTALL%
|
||||
|
||||
:: Build WinDivert.dll
|
||||
cd dll
|
||||
msbuild /p:Platform=%PLATFORM% /p:OutDir=build\
|
||||
copy /Y build\WinDivert.dll ..\%MSVC_INSTALL%
|
||||
copy /Y build\WinDivert.lib ..\%MSVC_INSTALL%
|
||||
copy /Y build\WinDivert.lib ..\%MSVC_INSTALL%..
|
||||
rd /s /q build\
|
||||
cd ..
|
||||
|
||||
:: Build netdump
|
||||
cd examples\netdump
|
||||
msbuild /p:Platform=%PLATFORM% /p:OutDir=build\
|
||||
copy /Y build\netdump.exe ..\..\%MSVC_INSTALL%
|
||||
rd /s /q build\
|
||||
cd ..\..
|
||||
|
||||
:: Build netfilter
|
||||
cd examples\netfilter
|
||||
msbuild /p:Platform=%PLATFORM% /p:OutDir=build\
|
||||
copy /Y build\netfilter.exe ..\..\%MSVC_INSTALL%
|
||||
rd /s /q build\
|
||||
cd ..\..
|
||||
|
||||
:: Build passthru
|
||||
cd examples\passthru
|
||||
msbuild /p:Platform=%PLATFORM% /p:OutDir=build\
|
||||
copy /Y build\passthru.exe ..\..\%MSVC_INSTALL%
|
||||
rd /s /q build\
|
||||
cd ..\..
|
||||
|
||||
:: Build webfilter
|
||||
cd examples\webfilter
|
||||
msbuild /p:Platform=%PLATFORM% /p:OutDir=build\
|
||||
copy /Y build\webfilter.exe ..\..\%MSVC_INSTALL%
|
||||
rd /s /q build\
|
||||
cd ..\..
|
||||
|
||||
:: Copy files
|
||||
copy /Y %WDDK_INSTALL%\WinDivert.sys %MSVC_INSTALL%
|
||||
copy /Y %WDDK_INSTALL%\WinDivert.inf %MSVC_INSTALL%
|
||||
copy /Y %WDDK_INSTALL%\WdfCoInstaller*.dll %MSVC_INSTALL%
|
||||
|
||||
:: Clean-up
|
||||
del %MSVC_INSTALL%..\WinDivert.lib
|
||||
|
||||
+52
-57
@@ -1,20 +1,37 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# (C) 2013, all rights reserved,
|
||||
# release-build.sh
|
||||
# (C) 2018, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This file is part of WinDivert.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
# WinDivert is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# WinDivert is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Script for building WinDivert binary packages. This script assumes the
|
||||
# binaries are already built and are in the install/ subdirectory.
|
||||
|
||||
@@ -23,15 +40,15 @@ set -e
|
||||
VERSION=`cat ./VERSION`
|
||||
NAME=WinDivert-$VERSION
|
||||
|
||||
for TARGET in WDDK MSVC MINGW
|
||||
for TARGET in MINGW
|
||||
do
|
||||
if [ ! -d "install/$TARGET" ]
|
||||
then
|
||||
echo "SKIP $NAME-$TARGET"
|
||||
continue
|
||||
fi
|
||||
echo "BUILD $NAME-$TARGET"
|
||||
INSTALL=install/$NAME-$TARGET
|
||||
echo "BUILD $NAME"
|
||||
INSTALL=install/$NAME
|
||||
echo "\tmake $INSTALL..."
|
||||
mkdir -p $INSTALL
|
||||
echo "\tcopy $INSTALL/README..."
|
||||
@@ -52,29 +69,17 @@ do
|
||||
cp doc/windivert.html $INSTALL/doc/WinDivert.html
|
||||
echo "\tmake $INSTALL/x86..."
|
||||
mkdir -p $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/WinDivert.inf..."
|
||||
cp sys/windivert.inf $INSTALL/x86/WinDivert.inf
|
||||
echo "\tcopy $INSTALL/x86/WinDivert.sys..."
|
||||
cp install/$TARGET/i386/WinDivert.sys $INSTALL/x86
|
||||
if ! grep "DigiCert High Assurance EV Root" $INSTALL/x86/WinDivert.sys \
|
||||
echo "\tcopy $INSTALL/x86/WinDivert32.sys..."
|
||||
cp install/$TARGET/i386/WinDivert32.sys $INSTALL/x86
|
||||
if ! grep "DigiCert High Assurance EV Root" $INSTALL/x86/WinDivert32.sys \
|
||||
2>&1 >/dev/null
|
||||
then
|
||||
echo "\tWARNING: using unsigned WinDivert.sys..."
|
||||
fi
|
||||
if [ $TARGET != MINGW ]
|
||||
then
|
||||
echo "\tcopy $INSTALL/x86/WinDivert.lib..."
|
||||
cp install/$TARGET/i386/WinDivert.lib $INSTALL/x86
|
||||
echo "\t\033[33mWARNING\033[0m: unsigned WinDivert32.sys..."
|
||||
fi
|
||||
echo "\tcopy $INSTALL/x86/WinDivert.lib..."
|
||||
cp install/$TARGET/i386/WinDivert.lib $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/WinDivert.dll..."
|
||||
cp install/$TARGET/i386/WinDivert.dll $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/WdfCoInstaller01009.dll..."
|
||||
cp install/$TARGET/i386/WdfCoInstaller01009.dll $INSTALL/x86
|
||||
COINST_SIZE=`stat --printf="%s" $INSTALL/x86/WdfCoInstaller01009.dll`
|
||||
if [ $COINST_SIZE -gt 1000000 ]
|
||||
then
|
||||
echo "\tWARNING: using fat WdfCoInstaller01009.dll..."
|
||||
fi
|
||||
echo "\tcopy $INSTALL/x86/netdump.exe..."
|
||||
cp install/$TARGET/i386/netdump.exe $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/netfilter.exe..."
|
||||
@@ -83,33 +88,25 @@ do
|
||||
cp install/$TARGET/i386/passthru.exe $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/webfilter.exe..."
|
||||
cp install/$TARGET/i386/webfilter.exe $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/x86/streamdump.exe..."
|
||||
cp install/$TARGET/i386/streamdump.exe $INSTALL/x86
|
||||
echo "\tcopy $INSTALL/i386/flowtrack.exe..."
|
||||
cp install/$TARGET/i386/flowtrack.exe $INSTALL/amd64
|
||||
if [ -d "install/$TARGET/amd64" ]
|
||||
then
|
||||
echo "\tmake $INSTALL/amd64..."
|
||||
mkdir -p $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert.inf..."
|
||||
cp sys/windivert.inf $INSTALL/amd64/WinDivert.inf
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert.sys..."
|
||||
cp install/$TARGET/amd64/WinDivert.sys $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert64.sys..."
|
||||
cp install/$TARGET/amd64/WinDivert64.sys $INSTALL/amd64
|
||||
if ! grep "DigiCert High Assurance EV Root" \
|
||||
$INSTALL/amd64/WinDivert.sys 2>&1 >/dev/null
|
||||
$INSTALL/amd64/WinDivert64.sys 2>&1 >/dev/null
|
||||
then
|
||||
echo "\tWARNING: using unsigned WinDivert.sys..."
|
||||
fi
|
||||
if [ $TARGET != MINGW ]
|
||||
then
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert.lib..."
|
||||
cp install/$TARGET/amd64/WinDivert.lib $INSTALL/amd64
|
||||
echo -e "\t\033[33mWARNING\033[0m: unsigned WinDivert64.sys..."
|
||||
fi
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert.lib..."
|
||||
cp install/$TARGET/amd64/WinDivert.lib $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/WinDivert.dll..."
|
||||
cp install/$TARGET/amd64/WinDivert.dll $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/WdfCoInstaller01009.dll..."
|
||||
cp install/$TARGET/amd64/WdfCoInstaller01009.dll $INSTALL/amd64
|
||||
COINST_SIZE=`stat --printf="%s" $INSTALL/amd64/WdfCoInstaller01009.dll`
|
||||
if [ $COINST_SIZE -gt 1000000 ]
|
||||
then
|
||||
echo "\tWARNING: using fat WdfCoInstaller01009.dll..."
|
||||
fi
|
||||
echo "\tcopy $INSTALL/amd64/netdump.exe..."
|
||||
cp install/$TARGET/amd64/netdump.exe $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/netfilter.exe..."
|
||||
@@ -118,20 +115,18 @@ do
|
||||
cp install/$TARGET/amd64/passthru.exe $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/webfilter.exe..."
|
||||
cp install/$TARGET/amd64/webfilter.exe $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/streamdump.exe..."
|
||||
cp install/$TARGET/amd64/streamdump.exe $INSTALL/amd64
|
||||
echo "\tcopy $INSTALL/amd64/flowtrack.exe..."
|
||||
cp install/$TARGET/amd64/flowtrack.exe $INSTALL/amd64
|
||||
else
|
||||
echo "\tWARNING: skipping missing AMD64 build..."
|
||||
fi
|
||||
PACKAGE=$NAME-$TARGET.tar.gz
|
||||
PACKAGE=$NAME.zip
|
||||
echo "\tbuilding $PACKAGE..."
|
||||
(
|
||||
cd install;
|
||||
tar cvz --owner root --group root -f $PACKAGE $NAME-$TARGET > /dev/null
|
||||
)
|
||||
PACKAGE=$NAME-$TARGET.zip
|
||||
echo "\tbuilding $PACKAGE..."
|
||||
(
|
||||
cd install;
|
||||
zip -r $PACKAGE $NAME-$TARGET > /dev/null
|
||||
zip -r $PACKAGE $NAME > /dev/null
|
||||
)
|
||||
echo -n "\tclean $INSTALL..."
|
||||
rm -rf $INSTALL
|
||||
|
||||
+5
-20
@@ -1,26 +1,13 @@
|
||||
# sources
|
||||
# (C) 2013, all rights reserved,
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
!IF "$(_BUILDARCH)" == "x86"
|
||||
CPU=i386
|
||||
BITS=32
|
||||
!ELSE
|
||||
CPU=$(_BUILDARCH)
|
||||
BITS=64
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=WinDivert
|
||||
TARGETNAME=WinDivert$(BITS)
|
||||
TARGETTYPE=DRIVER
|
||||
TARGETPATH=..\install\WDDK
|
||||
TARGETLIBS=\
|
||||
@@ -28,12 +15,10 @@ TARGETLIBS=\
|
||||
$(DDK_LIB_PATH)\ndis.lib \
|
||||
$(DDK_LIB_PATH)\fwpkclnt.lib \
|
||||
$(SDK_LIB_PATH)\uuid.lib
|
||||
NTTARGETFILES=\
|
||||
$(TARGETPATH)\$(CPU)\WinDivert.inf \
|
||||
$(TARGETPATH)\$(CPU)\WdfCoInstaller01009.dll
|
||||
NTTARGETFILES=
|
||||
KMDF_VERSION_MAJOR=1
|
||||
C_DEFINES=$(C_DEFINES) -DBINARY_COMPATIBLE=0 -DNT -DUNICODE -D_UNICODE \
|
||||
-DNDIS60 -DNDIS_SUPPORT_NDIS60
|
||||
INCLUDES=$(DDK_INC_PATH);..\include
|
||||
INCLUDES=$(DDK_INC_PATH);..\include;..\dll
|
||||
SOURCES=windivert.rc windivert.c
|
||||
|
||||
|
||||
+4623
-1558
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
|
||||
[windivert.NT.Wdf]
|
||||
KmdfService = windivert, windivert_WdfSection
|
||||
|
||||
[windivert_WdfSection]
|
||||
KmdfLibraryVersion = 1.9
|
||||
|
||||
+33
-15
@@ -1,19 +1,35 @@
|
||||
/*
|
||||
* windivert.rc
|
||||
* (C) 2013, all rights reserved,
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
@@ -22,18 +38,20 @@
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
|
||||
#define VER_FILEDESCRIPTION_STR \
|
||||
"WinDivert network packet capture and (re)injection driver"
|
||||
"The WinDivert driver " \
|
||||
"[URL: https://reqrypt.org/windivert.html] " \
|
||||
"[Bitcoin: 1C5vZVSbizPeZ8ydTYhUfm4LA2cNwBfcYh]"
|
||||
#define VER_INTERNALNAME_STR "WinDivert.sys"
|
||||
#define VER_ORIGINALFILENAME_STR "WinDivert.sys"
|
||||
#define VER_PRODUCTVERSION 1.1
|
||||
#define VER_PRODUCTVERSION_STR "1.1"
|
||||
#define VER_COMPANYNAME_STR "Basil Projects"
|
||||
#define VER_LEGALCOPYRIGHT_YEARS "2011-2013"
|
||||
#define VER_PRODUCTVERSION 2.0
|
||||
#define VER_PRODUCTVERSION_STR "2.0"
|
||||
#define VER_COMPANYNAME_STR "Basil"
|
||||
#define VER_LEGALCOPYRIGHT_YEARS "2011-2019"
|
||||
#define VER_LEGALCOPYRIGHT_STR \
|
||||
"Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
|
||||
#define VER_PRODUCTNAME_STR "WinDivert driver"
|
||||
#define VER_PRODUCTNAME_STR "WinDivert 2.0 driver"
|
||||
|
||||
#include "common.ver"
|
||||
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# build.sh
|
||||
# (C) 2018, all rights reserved,
|
||||
#
|
||||
# This file is part of WinDivert.
|
||||
#
|
||||
# WinDivert is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# WinDivert is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Script for MinGW/Linux cross compilation.
|
||||
# NOTE: run wddk-build.bat before this script.
|
||||
|
||||
CC=x86_64-w64-mingw32-gcc
|
||||
|
||||
$CC -fno-ident -s -O2 -I../include/ test.c -o test.exe -lWinDivert \
|
||||
-L"../install/MINGW/amd64/"
|
||||
|
||||
+717
@@ -0,0 +1,717 @@
|
||||
/*
|
||||
* test.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* WinDivert testing framework.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAX_PACKET 2048
|
||||
|
||||
/*
|
||||
* Packet data.
|
||||
*/
|
||||
#include "test_data.c"
|
||||
|
||||
/*
|
||||
* Test entry.
|
||||
*/
|
||||
struct packet
|
||||
{
|
||||
const char *packet;
|
||||
size_t packet_len;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *filter;
|
||||
const struct packet *packet;
|
||||
BOOL match;
|
||||
};
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
static BOOL run_test(HANDLE inject_handle, const char *filter,
|
||||
const char *packet, const size_t packet_len, BOOL match, INT64 *diff);
|
||||
|
||||
/*
|
||||
* Test data.
|
||||
*/
|
||||
static const struct packet pkt_echo_request =
|
||||
{
|
||||
echo_request,
|
||||
sizeof(echo_request),
|
||||
"ipv4_icmp_echo_req"
|
||||
};
|
||||
static const struct packet pkt_http_request =
|
||||
{
|
||||
http_request,
|
||||
sizeof(http_request),
|
||||
"ipv4_tcp_http_req"
|
||||
};
|
||||
static const struct packet pkt_dns_request =
|
||||
{
|
||||
dns_request,
|
||||
sizeof(dns_request),
|
||||
"ipv4_udp_dns_req"
|
||||
};
|
||||
static const struct packet pkt_ipv6_tcp_syn =
|
||||
{
|
||||
ipv6_tcp_syn,
|
||||
sizeof(ipv6_tcp_syn),
|
||||
"ipv6_tcp_syn"
|
||||
};
|
||||
static const struct packet pkt_ipv6_echo_reply =
|
||||
{
|
||||
ipv6_echo_reply,
|
||||
sizeof(ipv6_echo_reply),
|
||||
"ipv6_icmpv6_echo_rep"
|
||||
};
|
||||
static const struct packet pkt_ipv6_exthdrs_udp =
|
||||
{
|
||||
ipv6_exthdrs_udp,
|
||||
sizeof(ipv6_exthdrs_udp),
|
||||
"ipv6_exthdrs_udp"
|
||||
};
|
||||
static const struct test tests[] =
|
||||
{
|
||||
{"event = PACKET", &pkt_echo_request, TRUE},
|
||||
{"packet[0] == 0x45", &pkt_echo_request, TRUE},
|
||||
{"packet[0] == 0x33", &pkt_echo_request, FALSE},
|
||||
{"packet[55] == 0x1b", &pkt_echo_request, TRUE},
|
||||
{"packet[55b] == 0x1b", &pkt_echo_request, TRUE},
|
||||
{"packet[1000] <= 0 || packet[-1000] = 7", &pkt_echo_request, FALSE},
|
||||
{"packet[-1] == 0x37 && packet[-2] == 0x36 && packet[-3] == 0x35 && "
|
||||
"packet[-4] == 0x34", &pkt_echo_request, TRUE},
|
||||
{"packet16[0] == 0x4500", &pkt_echo_request, TRUE},
|
||||
{"packet16[0] == 0x0045", &pkt_echo_request, FALSE},
|
||||
{"packet16[2b] == 0x0054", &pkt_echo_request, TRUE},
|
||||
{"packet16[1] == 0x0054", &pkt_echo_request, TRUE},
|
||||
{"packet16[0] == 0x4500 && packet16[1] == 0x0054 && "
|
||||
"packet16[-1] == 0x3637", &pkt_echo_request, TRUE},
|
||||
{"packet32[0b] == 0x45000054 && packet32[3b] == 0x54123440 && "
|
||||
"packet32[-4b] == 0x34353637 && packet32[-5b] == 0x33343536",
|
||||
&pkt_echo_request, TRUE},
|
||||
{"random8 < 10", &pkt_echo_request, TRUE},
|
||||
{"random16 >= 2222", &pkt_echo_request, TRUE},
|
||||
{"random32 <= 0x80000000", &pkt_echo_request, TRUE},
|
||||
{"(random8 < 128? icmp: udp)", &pkt_echo_request, TRUE},
|
||||
{"(random8 <= 128? "
|
||||
"(random16 <= 0x8000?"
|
||||
"(random32 <= 0x80000000? ip: ipv6): "
|
||||
"(random32 <= 0x80000000? icmpv6: icmp)): "
|
||||
"(random16 <= 0x8000?"
|
||||
"(random32 <= 0x80000000? tcp: icmp.Type >= 8): "
|
||||
"(random32 <= 0x80000000? outbound: loopback)))",
|
||||
&pkt_echo_request, TRUE},
|
||||
{"outbound and icmp", &pkt_echo_request, TRUE},
|
||||
{"outbound", &pkt_echo_request, TRUE},
|
||||
{"outbound and inbound", &pkt_echo_request, FALSE},
|
||||
{"loopback", &pkt_echo_request, FALSE},
|
||||
{"impostor", &pkt_echo_request, FALSE},
|
||||
{"icmp", &pkt_echo_request, TRUE},
|
||||
{"not icmp", &pkt_echo_request, FALSE},
|
||||
{"ip or ipv6", &pkt_echo_request, TRUE},
|
||||
{"inbound", &pkt_echo_request, FALSE},
|
||||
{"tcp", &pkt_echo_request, FALSE},
|
||||
{"icmp.Type == 8", &pkt_echo_request, TRUE},
|
||||
{"icmp.Type == 9", &pkt_echo_request, FALSE},
|
||||
{"(tcp? ip.Checksum == 0: icmp)", &pkt_echo_request, TRUE},
|
||||
{"(udp? icmp: icmp.Body == 5555)", &pkt_echo_request, FALSE},
|
||||
{"(false? false: false)", &pkt_echo_request, FALSE},
|
||||
{"(true? true: true)", &pkt_echo_request, TRUE},
|
||||
{"(tcp or udp or icmpv6 or ipv6? true: false)",
|
||||
&pkt_echo_request, FALSE},
|
||||
{"(ip and ipv6 and tcp and udp? false: icmp > 0)",
|
||||
&pkt_echo_request, TRUE},
|
||||
{"(tcp? tcp.DstPort == 80: true) and (udp? udp.DstPort == 80: true)",
|
||||
&pkt_echo_request, TRUE},
|
||||
{"ip and ip and ip and ip and ip and " // Max filter length:
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip and ip and ip and "
|
||||
"ip and ip and ip", &pkt_echo_request, TRUE},
|
||||
{"not true or false or not icmp or " // All fields:
|
||||
"icmp.Body == 33 or icmp.Checksum==2 or "
|
||||
"icmp.Code == 0x777 or "
|
||||
"icmp.Type == 0x333 or icmpv6 or "
|
||||
"icmpv6.Body or icmpv6.Checksum or "
|
||||
"icmpv6.Code or icmpv6.Type or "
|
||||
"ifIdx == 93923 or inbound or "
|
||||
"not ip or ip.Checksum == 8 or "
|
||||
"not ip.DF or ip.DstAddr == 1.2.3.4 or "
|
||||
"ip.FragOff == 4212 or "
|
||||
"ip.HdrLength == 2 or ip.Id = 0x0987 or "
|
||||
"ip.Length == 788 or ip.MF == 1 or "
|
||||
"ip.Protocol == 999 or "
|
||||
"ip.SrcAddr == 9.8.7.255 or "
|
||||
"ip.TOS == 3 or ip.TTL = 221 or ipv6 or "
|
||||
"ipv6.DstAddr or ipv6.FlowLabel or "
|
||||
"ipv6.HopLimit or ipv6.Length or "
|
||||
"ipv6.NextHdr or ipv6.SrcAddr or "
|
||||
"ipv6.TrafficClass or not outbound or "
|
||||
"subIfIdx == 888 or tcp or tcp.Ack or "
|
||||
"tcp.AckNum or tcp.Checksum or "
|
||||
"tcp.DstPort or tcp.Fin or "
|
||||
"tcp.HdrLength or tcp.PayloadLength or "
|
||||
"tcp.Psh or tcp.Rst or tcp.SeqNum or "
|
||||
"tcp.SrcPort or tcp.Syn or tcp.Urg or "
|
||||
"tcp.UrgPtr or tcp.Window or udp or "
|
||||
"udp.Checksum or udp.DstPort or "
|
||||
"udp.Length or udp.PayloadLength or "
|
||||
"udp.SrcPort", &pkt_echo_request, FALSE},
|
||||
{"(true and (true and (true and (true and "// Deep nesting:
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(true and (true and (true and (true and "
|
||||
"(((((((((((((((icmp)))))))))))))))))))"
|
||||
"))))))))))))))))))))))))))))))))))))))"
|
||||
"))))))))))))))))))))))))))))))))))))))", &pkt_echo_request, TRUE},
|
||||
{"not not not not not not not not icmp", &pkt_echo_request, TRUE},
|
||||
{"not not not not not not not icmp", &pkt_echo_request, FALSE},
|
||||
{"!!!!!!!icmp", &pkt_echo_request, FALSE},
|
||||
{"false and true or true", &pkt_echo_request, TRUE},
|
||||
{"true and false or false", &pkt_echo_request, FALSE},
|
||||
{"true or true and false", &pkt_echo_request, TRUE},
|
||||
{"false or false and true", &pkt_echo_request, FALSE},
|
||||
{"tcp && icmp || ip", &pkt_echo_request, TRUE},
|
||||
{"icmp && udp || tcp", &pkt_echo_request, FALSE},
|
||||
{"ip || icmp && icmpv6", &pkt_echo_request, TRUE},
|
||||
{"!ip || !icmp && !udp", &pkt_echo_request, FALSE},
|
||||
{"(((icmp)? (true): (false)) and "
|
||||
"(((tcp)? (false): (true)) and "
|
||||
"((ipv6)? (false): (true))))", &pkt_echo_request, TRUE},
|
||||
{"tcp", &pkt_http_request, TRUE},
|
||||
{"outbound and tcp and tcp.DstPort == 80", &pkt_http_request, TRUE},
|
||||
{"outbound and tcp and tcp.DstPort == 81", &pkt_http_request, FALSE},
|
||||
{"outbound and tcp and tcp.DstPort != 80", &pkt_http_request, FALSE},
|
||||
{"inbound and tcp and tcp.DstPort == 80", &pkt_http_request, FALSE},
|
||||
{"tcp.PayloadLength == 469", &pkt_http_request, TRUE},
|
||||
{"tcp.PayloadLength != 469", &pkt_http_request, FALSE},
|
||||
{"tcp.PayloadLength >= 469", &pkt_http_request, TRUE},
|
||||
{"tcp.PayloadLength <= 469", &pkt_http_request, TRUE},
|
||||
{"tcp.PayloadLength > 469", &pkt_http_request, FALSE},
|
||||
{"tcp.PayloadLength < 469", &pkt_http_request, FALSE},
|
||||
{"(outbound? (ip? (tcp.DstPort == 80? (tcp.PayloadLength > 0? true: "
|
||||
"false): false): false): false)", &pkt_http_request, TRUE},
|
||||
{"(outbound? (ip? (tcp.DstPort == 80? (tcp.PayloadLength == 0? true: "
|
||||
"false): false): false): false)", &pkt_http_request, FALSE},
|
||||
{"(ipv6? tcp and tcp.DstPort = 1234 and (tcp.SrcPort = 999? !tcp.UrgPtr: "
|
||||
"tcp.Syn) or udp: ip and tcp.DstPort == 80)",
|
||||
&pkt_http_request, TRUE},
|
||||
{"packet32[0] = 0x45000209 && packet32[1] = 0x482d4000 && "
|
||||
"packet16[8b] = 0x4006 && packet32[3] = 0x0a0a0a0a && "
|
||||
"packet32[4] = 0x5db8d877 && packet32[5] = 0xa31a0050 && "
|
||||
"packet32[6] = 0x5338ccc2 && packet32[7] = 0x5637b355 && "
|
||||
"packet32[8] = 0x80180073 && packet16[38b] = 0x0000 && "
|
||||
"packet32[10] = 0x0101080a && packet32[11] = 0x002c851b && "
|
||||
"packet32[12] = 0x1b7f3a71 && packet32[13] = 0x47455420 && "
|
||||
"packet32[14] = 0x2f204854 && packet32[15] = 0x54502f31 && "
|
||||
"packet32[16] = 0x2e310d0a && packet32[17] = 0x486f7374 && "
|
||||
"packet32[18] = 0x3a207777 && packet32[19] = 0x772e6578 && "
|
||||
"packet32[20] = 0x616d706c && packet32[21] = 0x652e636f && "
|
||||
"packet32[22] = 0x6d0d0a43 && packet32[23] = 0x6f6e6e65 && "
|
||||
"packet32[24] = 0x6374696f && packet32[25] = 0x6e3a206b && "
|
||||
"packet32[26] = 0x6565702d && packet32[27] = 0x616c6976 && "
|
||||
"packet32[28] = 0x650d0a43 && packet32[29] = 0x61636865 && "
|
||||
"packet32[30] = 0x2d436f6e && packet32[31] = 0x74726f6c && "
|
||||
"packet32[32] = 0x3a206d61 && packet32[33] = 0x782d6167 && "
|
||||
"packet32[34] = 0x653d300d && packet32[35] = 0x0a416363 && "
|
||||
"packet32[36] = 0x6570743a && packet32[37] = 0x20746578 && "
|
||||
"packet32[38] = 0x742f6874 && packet32[39] = 0x6d6c2c61 && "
|
||||
"packet32[40] = 0x70706c69 && packet32[41] = 0x63617469 && "
|
||||
"packet32[42] = 0x6f6e2f78 && packet32[43] = 0x68746d6c && "
|
||||
"packet32[44] = 0x2b786d6c && packet32[45] = 0x2c617070 && "
|
||||
"packet32[46] = 0x6c696361 && packet32[47] = 0x74696f6e && "
|
||||
"packet32[48] = 0x2f786d6c && packet32[49] = 0x3b713d30 && "
|
||||
"packet32[50] = 0x2e392c69 && packet32[51] = 0x6d616765 && "
|
||||
"packet32[52] = 0x2f776562 && packet32[53] = 0x702c2a2f && "
|
||||
"packet32[54] = 0x2a3b713d && packet32[55] = 0x302e380d && "
|
||||
"packet32[56] = 0x0a557365 && packet32[57] = 0x722d4167 && "
|
||||
"packet32[58] = 0x656e743a && packet32[59] = 0x20585858 && "
|
||||
"packet32[60] = 0x58585858 && packet32[61] = 0x58585858 && "
|
||||
"packet32[62] = 0x58585858 && packet32[63] = 0x58585858 && "
|
||||
"packet32[64] = 0x58585858 && packet32[65] = 0x58585858 && "
|
||||
"packet32[66] = 0x58585858 && packet32[67] = 0x58585858 && "
|
||||
"packet32[68] = 0x58585858 && packet32[69] = 0x58585858 && "
|
||||
"packet32[70] = 0x58585858 && packet32[71] = 0x58585858 && "
|
||||
"packet32[72] = 0x58585858 && packet32[73] = 0x58585858 && "
|
||||
"packet32[74] = 0x58585858 && packet32[75] = 0x58585858 && "
|
||||
"packet32[76] = 0x58585858 && packet32[77] = 0x58585858 && "
|
||||
"packet32[78] = 0x58585858 && packet32[79] = 0x58585858 && "
|
||||
"packet32[80] = 0x58585858 && packet32[81] = 0x58585858 && "
|
||||
"packet32[82] = 0x58585858 && packet32[83] = 0x58585858 && "
|
||||
"packet32[84] = 0x58585858 && packet32[85] = 0x58585858 && "
|
||||
"packet32[86] = 0x58585858 && packet32[87] = 0x58585858 && "
|
||||
"packet32[88] = 0x58585858 && packet32[89] = 0x58585858 && "
|
||||
"packet32[90] = 0x58585858 && packet32[91] = 0x58585858 && "
|
||||
"packet32[92] = 0x58580d0a && packet32[93] = 0x41636365 && "
|
||||
"packet32[94] = 0x70742d45 && packet32[95] = 0x6e636f64 && "
|
||||
"packet32[96] = 0x696e673a && packet32[97] = 0x20677a69 && "
|
||||
"packet32[98] = 0x702c6465 && packet32[99] = 0x666c6174 && "
|
||||
"packet32[100] = 0x652c7364 && packet32[101] = 0x63680d0a && "
|
||||
"packet32[102] = 0x41636365 && packet32[103] = 0x70742d4c && "
|
||||
"packet32[104] = 0x616e6775 && packet32[105] = 0x6167653a && "
|
||||
"packet32[106] = 0x20656e2d && packet32[107] = 0x55532c65 && "
|
||||
"packet32[108] = 0x6e3b713d && packet32[109] = 0x302e380d && "
|
||||
"packet32[110] = 0x0a49662d && packet32[111] = 0x4e6f6e65 && "
|
||||
"packet32[112] = 0x2d4d6174 && packet32[113] = 0x63683a20 && "
|
||||
"packet32[114] = 0x22333333 && packet32[115] = 0x33333333 && "
|
||||
"packet32[116] = 0x3333220d && packet32[117] = 0x0a49662d && "
|
||||
"packet32[118] = 0x4d6f6469 && packet32[119] = 0x66696564 && "
|
||||
"packet32[120] = 0x2d53696e && packet32[121] = 0x63653a20 && "
|
||||
"packet32[122] = 0x4672692c && packet32[123] = 0x20303320 && "
|
||||
"packet32[124] = 0x41756720 && packet32[125] = 0x32303134 && "
|
||||
"packet32[126] = 0x2031333a && packet32[127] = 0x33333a33 && "
|
||||
"packet32[128] = 0x3320474d && packet32[129] = 0x540d0a0d && "
|
||||
"packet[-1] = 0x0a", &pkt_http_request, TRUE},
|
||||
{"tcp.Payload16[-1] == 0x0d0a", &pkt_http_request, TRUE},
|
||||
{"tcp.Payload32[-2] == 0x20474d54", &pkt_http_request, TRUE},
|
||||
{"random8 < 128", &pkt_http_request, TRUE},
|
||||
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
|
||||
&pkt_http_request, TRUE},
|
||||
{"(random32 < 0x22223333? packet32[72] == 0x58585858: udp)",
|
||||
&pkt_http_request, TRUE},
|
||||
{"udp", &pkt_dns_request, TRUE},
|
||||
{"udp && udp.SrcPort > 1 && ipv6", &pkt_dns_request, FALSE},
|
||||
{"udp.DstPort == 53", &pkt_dns_request, TRUE},
|
||||
{"udp.DstPort > 100", &pkt_dns_request, FALSE},
|
||||
{"ip.DstAddr = 8.8.4.4", &pkt_dns_request, TRUE},
|
||||
{"ip.DstAddr = 8.8.8.8", &pkt_dns_request, FALSE},
|
||||
{"ip.DstAddr >= 8.8.0.0 &&"
|
||||
"ip.DstAddr <= 8.8.255.255", &pkt_dns_request, TRUE},
|
||||
{"ip.SrcAddr >= 10.0.0.0 && ip.SrcAddr <= 10.255.255.255",
|
||||
&pkt_dns_request, TRUE},
|
||||
{"ip.SrcAddr < 10.0.0.0 or ip.SrcAddr > 10.255.255.255",
|
||||
&pkt_dns_request, FALSE},
|
||||
{"ip.DstAddr == ::ffff:8.8.4.4", &pkt_dns_request, TRUE},
|
||||
{"ip.DstAddr == ::0:ffff:8.8.4.4", &pkt_dns_request, TRUE},
|
||||
{"udp.PayloadLength == 29", &pkt_dns_request, TRUE},
|
||||
{"udp.Payload16[-1] == 0x0001 && udp.Payload16[-2] == 0x0001",
|
||||
&pkt_dns_request, TRUE},
|
||||
{"packet16[-1] == 0x0001 && packet16[-2] == 0x0001",
|
||||
&pkt_dns_request, TRUE},
|
||||
{"tcp.Payload32[0] > 0", &pkt_dns_request, FALSE},
|
||||
{"udp.Payload32[1] > 0", &pkt_dns_request, TRUE},
|
||||
{"random8 < 128", &pkt_dns_request, TRUE},
|
||||
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
|
||||
&pkt_dns_request, TRUE},
|
||||
{"ipv6", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"ip", &pkt_ipv6_tcp_syn, FALSE},
|
||||
{"tcp.Syn", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"tcp.Syn == 1 && tcp.Ack == 0", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"tcp.Rst or tcp.Fin", &pkt_ipv6_tcp_syn, FALSE},
|
||||
{"(tcp.Syn? !tcp.Rst && !tcp.Fin: true)", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"(tcp.Rst? !tcp.Syn: (tcp.Fin? !tcp.Syn: tcp.Syn))",
|
||||
&pkt_ipv6_tcp_syn, TRUE},
|
||||
{"tcp.PayloadLength == 0", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"ipv6.SrcAddr == 1234:5678:1::aabb:ccdd", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"ipv6.SrcAddr == aabb:5678:1::1234:ccdd", &pkt_ipv6_tcp_syn, FALSE},
|
||||
{"tcp.SrcPort == 50046", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"tcp.SrcPort == 0x0000C37E", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"packet32[0b] == 0x60000000 && packet32[1b] == 0x00000000 && "
|
||||
"packet32[2b] == 0x00000028 && packet32[3b] == 0x00002806 && "
|
||||
"packet32[4b] == 0x00280640 && packet32[5b] == 0x28064012 && "
|
||||
"packet32[-4b] == 0x01030307 && packet32[-5b] == 0x00010303",
|
||||
&pkt_ipv6_tcp_syn, TRUE},
|
||||
{"tcp.Payload32[0] > 0", &pkt_ipv6_tcp_syn, FALSE},
|
||||
{"random8 < 128", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
|
||||
&pkt_ipv6_tcp_syn, TRUE},
|
||||
{"icmpv6", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"icmp", &pkt_ipv6_echo_reply, FALSE},
|
||||
{"icmp or icmpv6", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"not icmp", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"icmpv6.Type == 129", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"icmpv6.Code == 0", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"icmpv6.Body == 0x10720003", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"ipv6.DstAddr >= 1000", &pkt_ipv6_echo_reply, FALSE},
|
||||
{"ipv6.DstAddr <= 1", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"random8 < 128", &pkt_ipv6_echo_reply, TRUE},
|
||||
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
|
||||
&pkt_ipv6_echo_reply, TRUE},
|
||||
{"true", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"false", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"udp", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"tcp", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr == ::2", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::8.8.4.4", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr < abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr <= abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr != abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr >= abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr > abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"udp.SrcPort == 4660 and udp.DstPort == 43690",
|
||||
&pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"udp.SrcPort == 4660 and udp.DstPort == 12345",
|
||||
&pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"(outbound and tcp? tcp.DstPort == 0xABAB: false) or "
|
||||
"(outbound and udp? udp.DstPort == 0xAAAA: false) or "
|
||||
"(inbound and tcp? tcp.SrcPort == 0xABAB: false) or "
|
||||
"(inbound and udp? udp.SrcPort == 0xAAAA: false)",
|
||||
&pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"(tcp or udp) and (ip or ipv6) and (icmp or !icmpv6) and "
|
||||
"(tcp.Payload16[-1] == 0x1234 or udp.Payload16[-1] == 0x2101)",
|
||||
&pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"(tcp or icmp or icmpv6 or ip or !udp or ipv6? udp.PayloadLength > 0: "
|
||||
"udp.DstPort == 39482)", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"random8 < 128", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
|
||||
&pkt_ipv6_exthdrs_udp, TRUE},
|
||||
};
|
||||
|
||||
/*
|
||||
* Main.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
HANDLE upper_handle, lower_handle;
|
||||
HANDLE console;
|
||||
LARGE_INTEGER freq;
|
||||
UINT64 diff;
|
||||
size_t i;
|
||||
|
||||
// Open handles to:
|
||||
// (1) stop normal traffic from interacting with the tests; and
|
||||
// (2) stop test packets escaping to the Internet or TCP/IP stack.
|
||||
upper_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, -999,
|
||||
WINDIVERT_FLAG_DROP);
|
||||
lower_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 999,
|
||||
WINDIVERT_FLAG_DROP);
|
||||
if (upper_handle == INVALID_HANDLE_VALUE ||
|
||||
lower_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "error: failed to open WinDivert handle (err = %d)",
|
||||
GetLastError());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
QueryPerformanceFrequency(&freq);
|
||||
|
||||
// Wait for existing packets to flush:
|
||||
Sleep(150);
|
||||
|
||||
// Run tests:
|
||||
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests = 0;
|
||||
for (i = 0; i < num_tests; i++)
|
||||
{
|
||||
const char *filter = tests[i].filter;
|
||||
const char *packet = tests[i].packet->packet;
|
||||
size_t packet_len = tests[i].packet->packet_len;
|
||||
char *name = tests[i].packet->name;
|
||||
BOOL match = tests[i].match;
|
||||
|
||||
// Run the test:
|
||||
BOOL res = run_test(upper_handle, filter, packet, packet_len, match,
|
||||
&diff);
|
||||
diff = 1000000 * diff / freq.QuadPart;
|
||||
printf("%.3u ", i);
|
||||
if (res)
|
||||
{
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("PASSED");
|
||||
passed_tests++;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("FAILED");
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
printf(" %.5llu p=[", diff);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%s", name);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
printf("] f=[");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%s", filter);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
WinDivertClose(upper_handle);
|
||||
WinDivertClose(lower_handle);
|
||||
|
||||
printf("\npassed = %.2f%%\n",
|
||||
((double)passed_tests / (double)num_tests) * 100.0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run a test case.
|
||||
*/
|
||||
static BOOL run_test(HANDLE inject_handle, const char *filter,
|
||||
const char *packet, const size_t packet_len, BOOL match, INT64 *diff)
|
||||
{
|
||||
static char object[8192];
|
||||
char buf[2][MAX_PACKET];
|
||||
UINT buf_len[2], i, idx;
|
||||
DWORD iolen;
|
||||
WINDIVERT_ADDRESS addr[2], addr_send;
|
||||
OVERLAPPED overlapped[2];
|
||||
const char *err_str;
|
||||
UINT err_pos;
|
||||
PWINDIVERT_IPHDR iphdr = NULL;
|
||||
HANDLE handle[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
|
||||
HANDLE event[2] = {NULL, NULL};
|
||||
BOOL random, result, ipv4;
|
||||
LARGE_INTEGER end;
|
||||
|
||||
*diff = 0;
|
||||
|
||||
// (0) Verify the test data:
|
||||
if (!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_NETWORK,
|
||||
object, sizeof(object), &err_str, &err_pos))
|
||||
{
|
||||
fprintf(stderr, "error: filter string \"%s\" is invalid with error "
|
||||
"\"%s\" (position=%u)\n", filter, err_str, err_pos);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// (1) Open WinDivert handles:
|
||||
handle[0] = WinDivertOpen(object, WINDIVERT_LAYER_NETWORK, 777, 0);
|
||||
if (handle[0] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "error: failed to open WinDivert handle for filter "
|
||||
"\"%s\" (err = %d)\n", filter, GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
handle[1] = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 888, 0);
|
||||
if (handle[1] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "error: failed to open WinDivert handle "
|
||||
"(err = %d)\n", GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// (2) Create pended recv requests:
|
||||
event[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
event[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (event[0] == NULL || event[1] == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to create event (err = %d)\n",
|
||||
GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
memset(&overlapped[0], 0, sizeof(overlapped[0]));
|
||||
memset(&overlapped[1], 0, sizeof(overlapped[1]));
|
||||
overlapped[0].hEvent = event[0];
|
||||
overlapped[1].hEvent = event[1];
|
||||
if (WinDivertRecvEx(handle[0], buf[0], sizeof(buf[0]), &buf_len[0], 0,
|
||||
&addr[0], NULL, &overlapped[0]) ||
|
||||
GetLastError() != ERROR_IO_PENDING ||
|
||||
WinDivertRecvEx(handle[1], buf[1], sizeof(buf[1]), &buf_len[1], 0,
|
||||
&addr[1], NULL, &overlapped[1]) ||
|
||||
GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
fprintf(stderr, "error: failed to created pended recv from WinDivert "
|
||||
"handle (err = %d)\n", GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// (2) Inject the packet:
|
||||
memset(&addr_send, 0, sizeof(addr_send));
|
||||
addr_send.Outbound = TRUE;
|
||||
addr_send.PseudoIPChecksum = TRUE;
|
||||
addr_send.PseudoTCPChecksum = TRUE;
|
||||
addr_send.PseudoUDPChecksum = TRUE;
|
||||
if (!WinDivertSend(inject_handle, (PVOID)packet, packet_len, &addr_send,
|
||||
NULL))
|
||||
{
|
||||
fprintf(stderr, "error: failed to inject test packet (err = %d)\n",
|
||||
GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// (3) Wait for the packet to arrive.
|
||||
// NOTE: This may fail, so set a generous time-out of 250ms.
|
||||
switch (WaitForMultipleObjects(2, event, FALSE, 250))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
QueryPerformanceCounter(&end);
|
||||
result = TRUE;
|
||||
idx = 0;
|
||||
break;
|
||||
case WAIT_OBJECT_0+1:
|
||||
QueryPerformanceCounter(&end);
|
||||
result = FALSE;
|
||||
idx = 1;
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
fprintf(stderr, "error: failed to read packet from WinDivert "
|
||||
"handle (timeout)\n", GetLastError());
|
||||
goto failed;
|
||||
default:
|
||||
fprintf(stderr, "error: failed to wait for packet (err = %d)\n",
|
||||
GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
if (!GetOverlappedResult(handle[idx], &overlapped[idx], &iolen, TRUE))
|
||||
{
|
||||
fprintf(stderr, "error: failed to get the overlapped result from "
|
||||
"WinDivert handle (err = %d)\n", GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
buf_len[idx] = (UINT)iolen;
|
||||
*diff = end.QuadPart - addr[idx].Timestamp;
|
||||
|
||||
// (4) Verify that the packet is the same & matches.
|
||||
if (buf_len[idx] != packet_len)
|
||||
{
|
||||
fprintf(stderr, "error: packet length mis-match, expected (%u), got "
|
||||
"(%u)\n", packet_len, buf_len[idx]);
|
||||
goto failed;
|
||||
}
|
||||
iphdr = (PWINDIVERT_IPHDR)buf[idx];
|
||||
ipv4 = (iphdr->Version == 4);
|
||||
for (i = 0; i < packet_len; i++)
|
||||
{
|
||||
if (ipv4 && i >= offsetof(WINDIVERT_IPHDR, Checksum) &&
|
||||
i < offsetof(WINDIVERT_IPHDR, Checksum) + sizeof(UINT16))
|
||||
{
|
||||
// The IPv4 checksum can change, so ignore it.
|
||||
continue;
|
||||
}
|
||||
if (packet[i] != buf[idx][i])
|
||||
{
|
||||
fprintf(stderr, "error: packet data mis-match, expected byte #%u "
|
||||
"to be (0x%.2X), got (0x%.2X)\n", i, (unsigned char)packet[i],
|
||||
(unsigned char)buf[idx][i]);
|
||||
for (i = 0; i < packet_len; i++)
|
||||
{
|
||||
printf("%c", (packet[i] == buf[idx][i]? '.': 'X'));
|
||||
}
|
||||
putchar('\n');
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
random = (strstr(filter, "random") != 0);
|
||||
// If (random && !result), then we cannot verify since the original
|
||||
// non-matching random values have been lost:
|
||||
if ((!random &&
|
||||
WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
|
||||
&addr[idx]) != result) ||
|
||||
(random && result &&
|
||||
!WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
|
||||
&addr[idx])))
|
||||
{
|
||||
fprintf(stderr, "error: filter \"%s\" does not match the given "
|
||||
"packet\n", filter);
|
||||
goto failed;
|
||||
}
|
||||
if (!random && result != match)
|
||||
{
|
||||
fprintf(stderr, "error: filter \"%s\" does not match the expected "
|
||||
"result\n", filter);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// (5) Clean-up:
|
||||
if (!WinDivertClose(handle[0]) || !WinDivertClose(handle[1]))
|
||||
{
|
||||
fprintf(stderr, "error: failed to close WinDivert handle (err = %d)\n",
|
||||
GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
CloseHandle(event[0]);
|
||||
CloseHandle(event[1]);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (handle[i] != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WinDivertClose(handle[i]);
|
||||
}
|
||||
if (event[i] != NULL)
|
||||
{
|
||||
CloseHandle(event[i]);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* test_data.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
// IPV4 ICMP ECHO REQUEST
|
||||
static const unsigned char echo_request[] =
|
||||
{
|
||||
0x45, 0x00, 0x00, 0x54, 0x12, 0x34, 0x40, 0x00,
|
||||
0x40, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x3c, 0xd2,
|
||||
0x0d, 0x56, 0x00, 0x01, 0x8b, 0xa6, 0x60, 0x54,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf9, 0x08, 0x0a, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
|
||||
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
||||
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
|
||||
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
|
||||
0x34, 0x35, 0x36, 0x37
|
||||
};
|
||||
|
||||
// IPV4 TCP HTTP GET REQUEST
|
||||
static const unsigned char http_request[] =
|
||||
{
|
||||
0x45, 0x00, 0x02, 0x09, 0x48, 0x2d, 0x40, 0x00,
|
||||
0x40, 0x06, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a,
|
||||
0x5d, 0xb8, 0xd8, 0x77, 0xa3, 0x1a, 0x00, 0x50,
|
||||
0x53, 0x38, 0xcc, 0xc2, 0x56, 0x37, 0xb3, 0x55,
|
||||
0x80, 0x18, 0x00, 0x73, 0x02, 0xa4, 0x00, 0x00,
|
||||
0x01, 0x01, 0x08, 0x0a, 0x00, 0x2c, 0x85, 0x1b,
|
||||
0x1b, 0x7f, 0x3a, 0x71, 0x47, 0x45, 0x54, 0x20,
|
||||
0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,
|
||||
0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74,
|
||||
0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6b,
|
||||
0x65, 0x65, 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76,
|
||||
0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65,
|
||||
0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x3a, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67,
|
||||
0x65, 0x3d, 0x30, 0x0d, 0x0a, 0x41, 0x63, 0x63,
|
||||
0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x78,
|
||||
0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x61,
|
||||
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c,
|
||||
0x2b, 0x78, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70,
|
||||
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2f, 0x78, 0x6d, 0x6c, 0x3b, 0x71, 0x3d, 0x30,
|
||||
0x2e, 0x39, 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65,
|
||||
0x2f, 0x77, 0x65, 0x62, 0x70, 0x2c, 0x2a, 0x2f,
|
||||
0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d,
|
||||
0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x3a, 0x20, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
||||
0x58, 0x58, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65,
|
||||
0x70, 0x74, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, 0x69,
|
||||
0x70, 0x2c, 0x64, 0x65, 0x66, 0x6c, 0x61, 0x74,
|
||||
0x65, 0x2c, 0x73, 0x64, 0x63, 0x68, 0x0d, 0x0a,
|
||||
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c,
|
||||
0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a,
|
||||
0x20, 0x65, 0x6e, 0x2d, 0x55, 0x53, 0x2c, 0x65,
|
||||
0x6e, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d,
|
||||
0x0a, 0x49, 0x66, 0x2d, 0x4e, 0x6f, 0x6e, 0x65,
|
||||
0x2d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x20,
|
||||
0x22, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
||||
0x33, 0x33, 0x22, 0x0d, 0x0a, 0x49, 0x66, 0x2d,
|
||||
0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||
0x2d, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x3a, 0x20,
|
||||
0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x33, 0x20,
|
||||
0x41, 0x75, 0x67, 0x20, 0x32, 0x30, 0x31, 0x34,
|
||||
0x20, 0x31, 0x33, 0x3a, 0x33, 0x33, 0x3a, 0x33,
|
||||
0x33, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x0d,
|
||||
0x0a
|
||||
};
|
||||
|
||||
// IPV4 DNS REQUEST
|
||||
static const unsigned char dns_request[] =
|
||||
{
|
||||
0x45, 0x00, 0x00, 0x39, 0x20, 0x90, 0x00, 0x00,
|
||||
0x49, 0x11, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
|
||||
0x08, 0x08, 0x04, 0x04, 0xe0, 0x45, 0x00, 0x35,
|
||||
0x00, 0x25, 0x22, 0xa7, 0x17, 0x08, 0x01, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
|
||||
0x01
|
||||
};
|
||||
|
||||
// IPV6 TCP SYN
|
||||
static const unsigned char ipv6_tcp_syn[] =
|
||||
{
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40,
|
||||
0x12, 0x34, 0x56, 0x78, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0xc3, 0x7e, 0x00, 0x17, 0xe1, 0xd7, 0xc8, 0xaa,
|
||||
0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xaa, 0xaa,
|
||||
0xc3, 0x5e, 0x00, 0x00, 0x02, 0x04, 0xff, 0xc4,
|
||||
0x04, 0x02, 0x08, 0x0a, 0xff, 0xff, 0x91, 0x86,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x07
|
||||
};
|
||||
|
||||
// IPV6 ICMPV6 ECHO REPLY
|
||||
static const unsigned char ipv6_echo_reply[] =
|
||||
{
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x81, 0x00, 0x6e, 0xd6, 0x10, 0x72, 0x00, 0x03,
|
||||
0xa4, 0xd5, 0x69, 0x54, 0x00, 0x00, 0x00, 0x00,
|
||||
0xab, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
|
||||
};
|
||||
|
||||
// IPV6 EXTENSION HEADERS UDP
|
||||
static const unsigned char ipv6_exthdrs_udp[] =
|
||||
{
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x64,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x12, 0x34, 0xaa, 0xaa, 0x00, 0x15, 0xef, 0xf4,
|
||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f,
|
||||
0x72, 0x6c, 0x64, 0x21, 0x01
|
||||
};
|
||||
|
||||
+25
-9
@@ -1,19 +1,35 @@
|
||||
:: wddk-build.bat
|
||||
:: (C) 2013, all rights reserved,
|
||||
:: (C) 2018, all rights reserved,
|
||||
::
|
||||
:: This program is free software: you can redistribute it and/or modify
|
||||
:: it under the terms of the GNU Lesser General Public License as published by
|
||||
:: the Free Software Foundation, either version 3 of the License, or
|
||||
:: (at your option) any later version.
|
||||
:: This file is part of WinDivert.
|
||||
::
|
||||
:: This program is distributed in the hope that it will be useful,
|
||||
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
:: GNU Lesser General Public License for more details.
|
||||
:: WinDivert is free software: you can redistribute it and/or modify it under
|
||||
:: the terms of the GNU Lesser General Public License as published by the
|
||||
:: Free Software Foundation, either version 3 of the License, or (at your
|
||||
:: option) any later version.
|
||||
::
|
||||
:: This program is distributed in the hope that it will be useful, but
|
||||
:: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
:: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
:: License for more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU Lesser General Public License
|
||||
:: along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
::
|
||||
:: WinDivert is free software; you can redistribute it and/or modify it under
|
||||
:: the terms of the GNU General Public License as published by the Free
|
||||
:: Software Foundation; either version 2 of the License, or (at your option)
|
||||
:: any later version.
|
||||
::
|
||||
:: This program is distributed in the hope that it will be useful, but
|
||||
:: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
:: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
:: for more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU General Public License along
|
||||
:: with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
:: Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
::
|
||||
:: Script for WDDK compilation.
|
||||
:: NOTE: Use this script to build the driver
|
||||
|
||||
|
||||
Reference in New Issue
Block a user