mirror of
https://github.com/Zxilly/UA2F.git
synced 2026-01-14 06:07:18 +00:00
update
This commit is contained in:
parent
9673c3d61b
commit
75ccb3eb67
17
ref/libnetfilter-queue/.gitignore
vendored
Normal file
17
ref/libnetfilter-queue/.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
.deps/
|
||||
.libs/
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.o
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/build-aux/
|
||||
/config.*
|
||||
/configure
|
||||
/libtool
|
||||
|
||||
/doxygen.cfg
|
||||
/libnetfilter_queue.pc
|
||||
339
ref/libnetfilter-queue/COPYING
Normal file
339
ref/libnetfilter-queue/COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, 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 Library 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
|
||||
|
||||
Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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 Library General
|
||||
Public License instead of this License.
|
||||
2
ref/libnetfilter-queue/Make_global.am
Normal file
2
ref/libnetfilter-queue/Make_global.am
Normal file
@ -0,0 +1,2 @@
|
||||
AM_CPPFLAGS = -I${top_srcdir}/include ${LIBNFNETLINK_CFLAGS} ${LIBMNL_CFLAGS}
|
||||
AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN}
|
||||
13
ref/libnetfilter-queue/Makefile.am
Normal file
13
ref/libnetfilter-queue/Makefile.am
Normal file
@ -0,0 +1,13 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
EXTRA_DIST = $(man_MANS) include/linux
|
||||
|
||||
SUBDIRS = src utils include examples doxygen
|
||||
|
||||
man_MANS = #nfnetlink_queue.3 nfnetlink_queue.7
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libnetfilter_queue.pc
|
||||
|
||||
EXTRA_DIST += Make_global.am
|
||||
EXTRA_DIST += fixmanpages.sh
|
||||
39
ref/libnetfilter-queue/autogen.sh
Normal file
39
ref/libnetfilter-queue/autogen.sh
Normal file
@ -0,0 +1,39 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
include ()
|
||||
{
|
||||
# If we keep a copy of the kernel header in the SVN tree, we'll have
|
||||
# to worry about synchronization issues forever. Instead, we just copy
|
||||
# the headers that we need from the lastest kernel version at autogen
|
||||
# stage.
|
||||
|
||||
INCLUDEDIR=${KERNEL_DIR:-/lib/modules/`uname -r`/build}/include/linux
|
||||
if [ -f $INCLUDEDIR/netfilter/nfnetlink_queue.h ]
|
||||
then
|
||||
TARGET=include/libnetfilter_queue/linux_nfnetlink_queue.h
|
||||
echo "Copying nfnetlink_queue.h to linux_nfnetlink_queue.h"
|
||||
cp $INCLUDEDIR/netfilter/nfnetlink_queue.h $TARGET
|
||||
TEMP=`tempfile`
|
||||
sed 's/linux\/netfilter\/nfnetlink.h/libnfnetlink\/linux_nfnetlink.h/g' $TARGET > $TEMP
|
||||
# Add aligned_u64 definition after #define _NFNETLINK_QUEUE_H
|
||||
awk '{
|
||||
if ( $0 == "#define _NFNETLINK_QUEUE_H" ) {
|
||||
print $0
|
||||
getline
|
||||
print $0
|
||||
print "#ifndef aligned_u64"
|
||||
print "#define aligned_u64 unsigned long long __attribute__((aligned(8)))"
|
||||
print "#endif"
|
||||
}
|
||||
|
||||
print $0
|
||||
}' $TEMP > $TARGET
|
||||
else
|
||||
echo "can't find nfnetlink_queue.h kernel file in $INCLUDEDIR"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
[ "x$1" = "xdistrib" ] && include
|
||||
autoreconf -fi
|
||||
rm -Rf autom4te.cache
|
||||
55
ref/libnetfilter-queue/configure.ac
Normal file
55
ref/libnetfilter-queue/configure.ac
Normal file
@ -0,0 +1,55 @@
|
||||
dnl Process this file with autoconf to create configure.
|
||||
|
||||
AC_INIT([libnetfilter_queue], [1.0.5])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CANONICAL_HOST
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects
|
||||
tar-pax no-dist-gzip dist-bzip2 1.6])
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_DISABLE_STATIC
|
||||
AM_PROG_LIBTOOL
|
||||
AC_PROG_INSTALL
|
||||
CHECK_GCC_FVISIBILITY
|
||||
|
||||
case "$host" in
|
||||
*-*-linux* | *-*-uclinux*) ;;
|
||||
*) AC_MSG_ERROR([Linux only, dude!]);;
|
||||
esac
|
||||
|
||||
dnl Dependencies
|
||||
PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= 0.0.41])
|
||||
PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3])
|
||||
|
||||
dnl Output the makefiles
|
||||
AC_CONFIG_FILES([Makefile src/Makefile utils/Makefile examples/Makefile
|
||||
libnetfilter_queue.pc doxygen.cfg
|
||||
include/Makefile include/libnetfilter_queue/Makefile
|
||||
doxygen/Makefile
|
||||
include/linux/Makefile include/linux/netfilter/Makefile])
|
||||
|
||||
AC_ARG_WITH([doxygen], [AS_HELP_STRING([--with-doxygen],
|
||||
[create doxygen documentation [default=no]])],
|
||||
[], [with_doxygen=no])
|
||||
AS_IF([test "x$with_doxygen" = xyes], [
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
AC_CHECK_PROGS([DOT], [dot], [""])
|
||||
AS_IF([test "x$DOT" != "x"],
|
||||
[AC_SUBST(HAVE_DOT, YES)],
|
||||
[AC_SUBST(HAVE_DOT, NO)])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
|
||||
AC_OUTPUT
|
||||
|
||||
echo "
|
||||
libnetfilter_queue configuration:
|
||||
doxygen: ${with_doxygen}"
|
||||
27
ref/libnetfilter-queue/doxygen.cfg.in
Normal file
27
ref/libnetfilter-queue/doxygen.cfg.in
Normal file
@ -0,0 +1,27 @@
|
||||
# Difference with default Doxyfile 1.8.20
|
||||
PROJECT_NAME = @PACKAGE@
|
||||
PROJECT_NUMBER = @VERSION@
|
||||
OUTPUT_DIRECTORY = doxygen
|
||||
ABBREVIATE_BRIEF =
|
||||
FULL_PATH_NAMES = NO
|
||||
TAB_SIZE = 8
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
INPUT = .
|
||||
FILE_PATTERNS = *.c
|
||||
RECURSIVE = YES
|
||||
EXCLUDE_SYMBOLS = EXPORT_SYMBOL \
|
||||
tcp_word_hdr \
|
||||
nfq_handle \
|
||||
nfq_data \
|
||||
nfq_q_handle \
|
||||
tcp_flag_word
|
||||
EXAMPLE_PATTERNS =
|
||||
INPUT_FILTER = "sed 's/EXPORT_SYMBOL//g'"
|
||||
SOURCE_BROWSER = YES
|
||||
ALPHABETICAL_INDEX = NO
|
||||
SEARCHENGINE = NO
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_CMD_NAME = latex
|
||||
GENERATE_MAN = YES
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
DOT_TRANSPARENT = YES
|
||||
23
ref/libnetfilter-queue/doxygen/Makefile.am
Normal file
23
ref/libnetfilter-queue/doxygen/Makefile.am
Normal file
@ -0,0 +1,23 @@
|
||||
if HAVE_DOXYGEN
|
||||
doc_srcs = $(top_srcdir)/src/libnetfilter_queue.c \
|
||||
$(top_srcdir)/src/nlmsg.c \
|
||||
$(top_srcdir)/src/extra/checksum.c \
|
||||
$(top_srcdir)/src/extra/ipv6.c \
|
||||
$(top_srcdir)/src/extra/ipv4.c \
|
||||
$(top_srcdir)/src/extra/tcp.c \
|
||||
$(top_srcdir)/src/extra/udp.c \
|
||||
$(top_srcdir)/src/extra/pktbuff.c
|
||||
|
||||
doxyfile.stamp: $(doc_srcs) $(top_srcdir)/fixmanpages.sh
|
||||
rm -rf html man && cd .. && doxygen doxygen.cfg >/dev/null && ./fixmanpages.sh
|
||||
touch doxyfile.stamp
|
||||
|
||||
CLEANFILES = doxyfile.stamp
|
||||
|
||||
all-local: doxyfile.stamp
|
||||
clean-local:
|
||||
rm -rf $(top_srcdir)/doxygen/man $(top_srcdir)/doxygen/html
|
||||
install-data-local:
|
||||
mkdir -p $(DESTDIR)$(mandir)/man3
|
||||
cp --no-dereference --preserve=links,mode,timestamps man/man3/*.3 $(DESTDIR)$(mandir)/man3/
|
||||
endif
|
||||
7
ref/libnetfilter-queue/examples/Makefile.am
Normal file
7
ref/libnetfilter-queue/examples/Makefile.am
Normal file
@ -0,0 +1,7 @@
|
||||
include ${top_srcdir}/Make_global.am
|
||||
|
||||
check_PROGRAMS = nf-queue
|
||||
|
||||
nf_queue_SOURCES = nf-queue.c
|
||||
nf_queue_LDADD = ../src/libnetfilter_queue.la
|
||||
nf_queue_LDFLAGS = -dynamic -lmnl
|
||||
181
ref/libnetfilter-queue/examples/nf-queue.c
Normal file
181
ref/libnetfilter-queue/examples/nf-queue.c
Normal file
@ -0,0 +1,181 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
/* only for NFQA_CT, not needed otherwise: */
|
||||
#include <linux/netfilter/nfnetlink_conntrack.h>
|
||||
|
||||
static struct mnl_socket *nl;
|
||||
|
||||
static void
|
||||
nfq_send_verdict(int queue_num, uint32_t id)
|
||||
{
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
struct nlmsghdr *nlh;
|
||||
struct nlattr *nest;
|
||||
|
||||
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_VERDICT, queue_num);
|
||||
nfq_nlmsg_verdict_put(nlh, id, NF_ACCEPT);
|
||||
|
||||
/* example to set the connmark. First, start NFQA_CT section: */
|
||||
nest = mnl_attr_nest_start(nlh, NFQA_CT);
|
||||
|
||||
/* then, add the connmark attribute: */
|
||||
mnl_attr_put_u32(nlh, CTA_MARK, htonl(42));
|
||||
/* more conntrack attributes, e.g. CTA_LABELS could be set here */
|
||||
|
||||
/* end conntrack section */
|
||||
mnl_attr_nest_end(nlh, nest);
|
||||
|
||||
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
|
||||
perror("mnl_socket_send");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static int queue_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct nfqnl_msg_packet_hdr *ph = NULL;
|
||||
struct nlattr *attr[NFQA_MAX+1] = {};
|
||||
uint32_t id = 0, skbinfo;
|
||||
struct nfgenmsg *nfg;
|
||||
uint16_t plen;
|
||||
|
||||
if (nfq_nlmsg_parse(nlh, attr) < 0) {
|
||||
perror("problems parsing");
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
|
||||
nfg = mnl_nlmsg_get_payload(nlh);
|
||||
|
||||
if (attr[NFQA_PACKET_HDR] == NULL) {
|
||||
fputs("metaheader not set\n", stderr);
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
|
||||
ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
|
||||
|
||||
plen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
|
||||
/* void *payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]); */
|
||||
|
||||
skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
|
||||
|
||||
if (attr[NFQA_CAP_LEN]) {
|
||||
uint32_t orig_len = ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN]));
|
||||
if (orig_len != plen)
|
||||
printf("truncated ");
|
||||
}
|
||||
|
||||
if (skbinfo & NFQA_SKB_GSO)
|
||||
printf("GSO ");
|
||||
|
||||
id = ntohl(ph->packet_id);
|
||||
printf("packet received (id=%u hw=0x%04x hook=%u, payload len %u",
|
||||
id, ntohs(ph->hw_protocol), ph->hook, plen);
|
||||
|
||||
/*
|
||||
* ip/tcp checksums are not yet valid, e.g. due to GRO/GSO.
|
||||
* The application should behave as if the checksums are correct.
|
||||
*
|
||||
* If these packets are later forwarded/sent out, the checksums will
|
||||
* be corrected by kernel/hardware.
|
||||
*/
|
||||
if (skbinfo & NFQA_SKB_CSUMNOTREADY)
|
||||
printf(", checksum not ready");
|
||||
puts(")");
|
||||
|
||||
nfq_send_verdict(ntohs(nfg->res_id), id);
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *buf;
|
||||
/* largest possible packet payload, plus netlink data overhead: */
|
||||
size_t sizeof_buf = 0xffff + (MNL_SOCKET_BUFFER_SIZE/2);
|
||||
struct nlmsghdr *nlh;
|
||||
int ret;
|
||||
unsigned int portid, queue_num;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s [queue_num]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
queue_num = atoi(argv[1]);
|
||||
|
||||
nl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (nl == NULL) {
|
||||
perror("mnl_socket_open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
perror("mnl_socket_bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
portid = mnl_socket_get_portid(nl);
|
||||
|
||||
buf = malloc(sizeof_buf);
|
||||
if (!buf) {
|
||||
perror("allocate receive buffer");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
|
||||
nfq_nlmsg_cfg_put_cmd(nlh, AF_INET, NFQNL_CFG_CMD_BIND);
|
||||
|
||||
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
|
||||
perror("mnl_socket_send");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
|
||||
nfq_nlmsg_cfg_put_params(nlh, NFQNL_COPY_PACKET, 0xffff);
|
||||
|
||||
mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(NFQA_CFG_F_GSO));
|
||||
mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(NFQA_CFG_F_GSO));
|
||||
|
||||
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
|
||||
perror("mnl_socket_send");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* ENOBUFS is signalled to userspace when packets were lost
|
||||
* on kernel side. In most cases, userspace isn't interested
|
||||
* in this information, so turn it off.
|
||||
*/
|
||||
ret = 1;
|
||||
mnl_socket_setsockopt(nl, NETLINK_NO_ENOBUFS, &ret, sizeof(int));
|
||||
|
||||
for (;;) {
|
||||
ret = mnl_socket_recvfrom(nl, buf, sizeof_buf);
|
||||
if (ret == -1) {
|
||||
perror("mnl_socket_recvfrom");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
|
||||
if (ret < 0){
|
||||
perror("mnl_cb_run");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
mnl_socket_close(nl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
65
ref/libnetfilter-queue/fixmanpages.sh
Normal file
65
ref/libnetfilter-queue/fixmanpages.sh
Normal file
@ -0,0 +1,65 @@
|
||||
#!/bin/bash -p
|
||||
#set -x
|
||||
function main
|
||||
{
|
||||
set -e
|
||||
cd doxygen/man/man3
|
||||
rm -f _*
|
||||
setgroup LibrarySetup nfq_open
|
||||
add2group nfq_close nfq_bind_pf nfq_unbind_pf
|
||||
setgroup Parsing nfq_get_msg_packet_hdr
|
||||
add2group nfq_get_nfmark nfq_get_timestamp nfq_get_indev nfq_get_physindev
|
||||
add2group nfq_get_outdev nfq_get_physoutdev nfq_get_indev_name
|
||||
add2group nfq_get_physindev_name nfq_get_outdev_name
|
||||
add2group nfq_get_physoutdev_name nfq_get_packet_hw
|
||||
add2group nfq_get_skbinfo
|
||||
add2group nfq_get_uid nfq_get_gid
|
||||
add2group nfq_get_secctx nfq_get_payload
|
||||
setgroup Queue nfq_fd
|
||||
add2group nfq_create_queue nfq_destroy_queue nfq_handle_packet nfq_set_mode
|
||||
add2group nfq_set_queue_flags nfq_set_queue_maxlen nfq_set_verdict
|
||||
add2group nfq_set_verdict2 nfq_set_verdict_batch
|
||||
add2group nfq_set_verdict_batch2 nfq_set_verdict_mark
|
||||
setgroup ipv4 nfq_ip_get_hdr
|
||||
add2group nfq_ip_set_transport_header nfq_ip_mangle nfq_ip_snprintf
|
||||
setgroup ip_internals nfq_ip_set_checksum
|
||||
setgroup ipv6 nfq_ip6_get_hdr
|
||||
add2group nfq_ip6_set_transport_header nfq_ip6_mangle nfq_ip6_snprintf
|
||||
setgroup nfq_cfg nfq_nlmsg_cfg_put_cmd
|
||||
add2group nfq_nlmsg_cfg_put_params nfq_nlmsg_cfg_put_qmaxlen
|
||||
setgroup nfq_verd nfq_nlmsg_verdict_put
|
||||
add2group nfq_nlmsg_verdict_put_mark nfq_nlmsg_verdict_put_pkt
|
||||
setgroup nlmsg nfq_nlmsg_parse
|
||||
add2group nfq_nlmsg_put
|
||||
setgroup pktbuff pktb_alloc
|
||||
add2group pktb_data pktb_len pktb_mangle pktb_mangled
|
||||
add2group pktb_free
|
||||
setgroup otherfns pktb_tailroom
|
||||
add2group pktb_mac_header pktb_network_header pktb_transport_header
|
||||
setgroup uselessfns pktb_push
|
||||
add2group pktb_pull pktb_put pktb_trim
|
||||
setgroup tcp nfq_tcp_get_hdr
|
||||
add2group nfq_tcp_get_payload nfq_tcp_get_payload_len
|
||||
add2group nfq_tcp_snprintf nfq_tcp_mangle_ipv4 nfq_tcp_mangle_ipv6
|
||||
setgroup tcp_internals nfq_tcp_compute_checksum_ipv4
|
||||
add2group nfq_tcp_compute_checksum_ipv6
|
||||
setgroup udp nfq_udp_get_hdr
|
||||
add2group nfq_udp_get_payload nfq_udp_get_payload_len
|
||||
add2group nfq_udp_mangle_ipv4 nfq_udp_mangle_ipv6 nfq_udp_snprintf
|
||||
setgroup udp_internals nfq_udp_compute_checksum_ipv4
|
||||
add2group nfq_udp_compute_checksum_ipv6
|
||||
setgroup Printing nfq_snprintf_xml
|
||||
}
|
||||
function setgroup
|
||||
{
|
||||
mv $1.3 $2.3
|
||||
BASE=$2
|
||||
}
|
||||
function add2group
|
||||
{
|
||||
for i in $@
|
||||
do
|
||||
ln -sf $BASE.3 $i.3
|
||||
done
|
||||
}
|
||||
main
|
||||
1
ref/libnetfilter-queue/include/Makefile.am
Normal file
1
ref/libnetfilter-queue/include/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS= libnetfilter_queue linux
|
||||
@ -0,0 +1,7 @@
|
||||
pkginclude_HEADERS = libnetfilter_queue.h \
|
||||
linux_nfnetlink_queue.h \
|
||||
libnetfilter_queue_ipv4.h \
|
||||
libnetfilter_queue_ipv6.h \
|
||||
libnetfilter_queue_tcp.h \
|
||||
libnetfilter_queue_udp.h \
|
||||
pktbuff.h
|
||||
@ -0,0 +1,159 @@
|
||||
/* libnfqnetlink.h: Header file for the Netfilter Queue library.
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
*
|
||||
* Changelog :
|
||||
* (2005/08/11) added parsing function (Eric Leblond <regit@inl.fr>)
|
||||
*
|
||||
* This software may be used and distributed according to the terms
|
||||
* of the GNU General Public License, incorporated herein by reference.
|
||||
*/
|
||||
|
||||
#ifndef __LIBCTNETLINK_H
|
||||
#define __LIBCTNETLINK_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <libnfnetlink/libnfnetlink.h>
|
||||
|
||||
#include <libnetfilter_queue/linux_nfnetlink_queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nfq_handle;
|
||||
struct nfq_q_handle;
|
||||
struct nfq_data;
|
||||
|
||||
extern int nfq_errno;
|
||||
|
||||
extern struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h);
|
||||
extern int nfq_fd(struct nfq_handle *h);
|
||||
|
||||
typedef int nfq_callback(struct nfq_q_handle *gh, struct nfgenmsg *nfmsg,
|
||||
struct nfq_data *nfad, void *data);
|
||||
|
||||
|
||||
extern struct nfq_handle *nfq_open(void);
|
||||
extern struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh);
|
||||
extern int nfq_close(struct nfq_handle *h);
|
||||
|
||||
extern int nfq_bind_pf(struct nfq_handle *h, uint16_t pf);
|
||||
extern int nfq_unbind_pf(struct nfq_handle *h, uint16_t pf);
|
||||
|
||||
extern struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h,
|
||||
uint16_t num,
|
||||
nfq_callback *cb,
|
||||
void *data);
|
||||
extern int nfq_destroy_queue(struct nfq_q_handle *qh);
|
||||
|
||||
extern int nfq_handle_packet(struct nfq_handle *h, char *buf, int len);
|
||||
|
||||
extern int nfq_set_mode(struct nfq_q_handle *qh,
|
||||
uint8_t mode, unsigned int len);
|
||||
|
||||
int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
|
||||
uint32_t queuelen);
|
||||
|
||||
extern int nfq_set_queue_flags(struct nfq_q_handle *qh,
|
||||
uint32_t mask, uint32_t flags);
|
||||
|
||||
extern int nfq_set_verdict(struct nfq_q_handle *qh,
|
||||
uint32_t id,
|
||||
uint32_t verdict,
|
||||
uint32_t data_len,
|
||||
const unsigned char *buf);
|
||||
|
||||
extern int nfq_set_verdict2(struct nfq_q_handle *qh,
|
||||
uint32_t id,
|
||||
uint32_t verdict,
|
||||
uint32_t mark,
|
||||
uint32_t datalen,
|
||||
const unsigned char *buf);
|
||||
|
||||
extern int nfq_set_verdict_batch(struct nfq_q_handle *qh,
|
||||
uint32_t id,
|
||||
uint32_t verdict);
|
||||
|
||||
extern int nfq_set_verdict_batch2(struct nfq_q_handle *qh,
|
||||
uint32_t id,
|
||||
uint32_t verdict,
|
||||
uint32_t mark);
|
||||
|
||||
extern __attribute__((deprecated))
|
||||
int nfq_set_verdict_mark(struct nfq_q_handle *qh,
|
||||
uint32_t id,
|
||||
uint32_t verdict,
|
||||
uint32_t mark,
|
||||
uint32_t datalen,
|
||||
const unsigned char *buf);
|
||||
|
||||
/* message parsing function */
|
||||
|
||||
extern struct nfqnl_msg_packet_hdr *
|
||||
nfq_get_msg_packet_hdr(struct nfq_data *nfad);
|
||||
|
||||
extern uint32_t nfq_get_nfmark(struct nfq_data *nfad);
|
||||
|
||||
extern int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv);
|
||||
|
||||
/* return 0 if not set */
|
||||
extern uint32_t nfq_get_indev(struct nfq_data *nfad);
|
||||
extern uint32_t nfq_get_physindev(struct nfq_data *nfad);
|
||||
extern uint32_t nfq_get_outdev(struct nfq_data *nfad);
|
||||
extern uint32_t nfq_get_physoutdev(struct nfq_data *nfad);
|
||||
extern uint32_t nfq_get_skbinfo(struct nfq_data *nfad);
|
||||
extern int nfq_get_uid(struct nfq_data *nfad, uint32_t *uid);
|
||||
extern int nfq_get_gid(struct nfq_data *nfad, uint32_t *gid);
|
||||
extern int nfq_get_secctx(struct nfq_data *nfad, unsigned char **secdata);
|
||||
|
||||
extern int nfq_get_indev_name(struct nlif_handle *nlif_handle,
|
||||
struct nfq_data *nfad, char *name);
|
||||
extern int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
|
||||
struct nfq_data *nfad, char *name);
|
||||
extern int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
|
||||
struct nfq_data *nfad, char *name);
|
||||
extern int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
|
||||
struct nfq_data *nfad, char *name);
|
||||
|
||||
extern struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad);
|
||||
|
||||
/* return -1 if problem, length otherwise */
|
||||
extern int nfq_get_payload(struct nfq_data *nfad, unsigned char **data);
|
||||
|
||||
enum {
|
||||
NFQ_XML_HW = (1 << 0),
|
||||
NFQ_XML_MARK = (1 << 1),
|
||||
NFQ_XML_DEV = (1 << 2),
|
||||
NFQ_XML_PHYSDEV = (1 << 3),
|
||||
NFQ_XML_PAYLOAD = (1 << 4),
|
||||
NFQ_XML_TIME = (1 << 5),
|
||||
NFQ_XML_UID = (1 << 6),
|
||||
NFQ_XML_GID = (1 << 7),
|
||||
NFQ_XML_SECCTX = (1 << 8),
|
||||
NFQ_XML_ALL = ~0U,
|
||||
};
|
||||
|
||||
extern int nfq_snprintf_xml(char *buf, size_t len, struct nfq_data *tb, int flags);
|
||||
|
||||
/*
|
||||
* New API based on libmnl
|
||||
*/
|
||||
|
||||
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd);
|
||||
void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range);
|
||||
void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t qmaxlen);
|
||||
|
||||
void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict);
|
||||
void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark);
|
||||
void nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt, uint32_t pktlen);
|
||||
|
||||
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr);
|
||||
struct nlmsghdr *nfq_nlmsg_put(char *buf, int type, uint32_t queue_num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __LIBNFQNETLINK_H */
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef _LIBNFQUEUE_IPV4_
|
||||
#define _LIBNFQUEUE_IPV4_
|
||||
|
||||
struct pkt_buff;
|
||||
struct iphdr;
|
||||
|
||||
struct iphdr *nfq_ip_get_hdr(struct pkt_buff *pktb);
|
||||
int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph);
|
||||
void nfq_ip_set_checksum(struct iphdr *iph);
|
||||
int nfq_ip_mangle(struct pkt_buff *pktb, unsigned int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,12 @@
|
||||
#ifndef _LIBNFQUEUE_H_
|
||||
#define _LIBNFQUEUE_H_
|
||||
|
||||
struct pkt_buff;
|
||||
struct ip6_hdr;
|
||||
|
||||
struct ip6_hdr *nfq_ip6_get_hdr(struct pkt_buff *pktb);
|
||||
int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *iph, uint8_t target);
|
||||
int nfq_ip6_mangle(struct pkt_buff *pktb, unsigned int dataoff,unsigned int match_offset, unsigned int match_len,const char *rep_buffer, unsigned int rep_len);
|
||||
int nfq_ip6_snprintf(char *buf, size_t size, const struct ip6_hdr *ip6h);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,21 @@
|
||||
#ifndef _LIBNFQUEUE_TCP_H_
|
||||
#define _LIBNFQUEUE_TCP_H_
|
||||
|
||||
struct pkt_buff;
|
||||
|
||||
struct tcphdr *nfq_tcp_get_hdr(struct pkt_buff *pktb);
|
||||
void *nfq_tcp_get_payload(struct tcphdr *tcph, struct pkt_buff *pktb);
|
||||
unsigned int nfq_tcp_get_payload_len(struct tcphdr *tcph, struct pkt_buff *pktb);
|
||||
|
||||
struct iphdr;
|
||||
struct ip6_hdr;
|
||||
|
||||
void nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph);
|
||||
void nfq_tcp_compute_checksum_ipv6(struct tcphdr *tcph, struct ip6_hdr *ip6h);
|
||||
|
||||
int nfq_tcp_mangle_ipv4(struct pkt_buff *pktb, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
int nfq_tcp_mangle_ipv6(struct pkt_buff *pktb, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
|
||||
int nfq_tcp_snprintf(char *buf, size_t size, const struct tcphdr *tcp);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef _LIBNFQUEUE_UDP_H_
|
||||
#define _LIBNFQUEUE_UDP_H_
|
||||
|
||||
struct pkt_buff;
|
||||
|
||||
struct udphdr *nfq_udp_get_hdr(struct pkt_buff *pktb);
|
||||
void *nfq_udp_get_payload(struct udphdr *udph, struct pkt_buff *pktb);
|
||||
unsigned int nfq_udp_get_payload_len(struct udphdr *udph, struct pkt_buff *pktb);
|
||||
|
||||
void nfq_udp_compute_checksum_ipv4(struct udphdr *udph, struct iphdr *iph);
|
||||
void nfq_udp_compute_checksum_ipv6(struct udphdr *udph, struct ip6_hdr *ip6h);
|
||||
|
||||
int nfq_udp_mangle_ipv4(struct pkt_buff *pktb, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
int nfq_udp_mangle_ipv6(struct pkt_buff *pktb, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
|
||||
int nfq_udp_snprintf(char *buf, size_t size, const struct udphdr *udp);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,121 @@
|
||||
#ifndef _NFNETLINK_QUEUE_H
|
||||
#define _NFNETLINK_QUEUE_H
|
||||
|
||||
#ifndef aligned_u64
|
||||
#define aligned_u64 unsigned long long __attribute__((aligned(8)))
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <libnfnetlink/linux_nfnetlink.h>
|
||||
|
||||
enum nfqnl_msg_types {
|
||||
NFQNL_MSG_PACKET, /* packet from kernel to userspace */
|
||||
NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */
|
||||
NFQNL_MSG_CONFIG, /* connect to a particular queue */
|
||||
NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */
|
||||
|
||||
NFQNL_MSG_MAX
|
||||
};
|
||||
|
||||
struct nfqnl_msg_packet_hdr {
|
||||
__be32 packet_id; /* unique ID of packet in queue */
|
||||
__be16 hw_protocol; /* hw protocol (network order) */
|
||||
__u8 hook; /* netfilter hook */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfqnl_msg_packet_hw {
|
||||
__be16 hw_addrlen;
|
||||
__u16 _pad;
|
||||
__u8 hw_addr[8];
|
||||
};
|
||||
|
||||
struct nfqnl_msg_packet_timestamp {
|
||||
__aligned_be64 sec;
|
||||
__aligned_be64 usec;
|
||||
};
|
||||
|
||||
enum nfqnl_attr_type {
|
||||
NFQA_UNSPEC,
|
||||
NFQA_PACKET_HDR,
|
||||
NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */
|
||||
NFQA_MARK, /* __u32 nfmark */
|
||||
NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */
|
||||
NFQA_IFINDEX_INDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_OUTDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_PHYSINDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */
|
||||
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
|
||||
NFQA_PAYLOAD, /* opaque data payload */
|
||||
NFQA_CT, /* nf_conntrack_netlink.h */
|
||||
NFQA_CT_INFO, /* enum ip_conntrack_info */
|
||||
NFQA_CAP_LEN, /* __u32 length of captured packet */
|
||||
NFQA_SKB_INFO, /* __u32 skb meta information */
|
||||
NFQA_EXP, /* nf_conntrack_netlink.h */
|
||||
NFQA_UID, /* __u32 sk uid */
|
||||
NFQA_GID, /* __u32 sk gid */
|
||||
NFQA_SECCTX, /* security context string */
|
||||
|
||||
__NFQA_MAX
|
||||
};
|
||||
#define NFQA_MAX (__NFQA_MAX - 1)
|
||||
|
||||
struct nfqnl_msg_verdict_hdr {
|
||||
__be32 verdict;
|
||||
__be32 id;
|
||||
};
|
||||
|
||||
|
||||
enum nfqnl_msg_config_cmds {
|
||||
NFQNL_CFG_CMD_NONE,
|
||||
NFQNL_CFG_CMD_BIND,
|
||||
NFQNL_CFG_CMD_UNBIND,
|
||||
NFQNL_CFG_CMD_PF_BIND,
|
||||
NFQNL_CFG_CMD_PF_UNBIND,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_cmd {
|
||||
__u8 command; /* nfqnl_msg_config_cmds */
|
||||
__u8 _pad;
|
||||
__be16 pf; /* AF_xxx for PF_[UN]BIND */
|
||||
};
|
||||
|
||||
enum nfqnl_config_mode {
|
||||
NFQNL_COPY_NONE,
|
||||
NFQNL_COPY_META,
|
||||
NFQNL_COPY_PACKET,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_params {
|
||||
__be32 copy_range;
|
||||
__u8 copy_mode; /* enum nfqnl_config_mode */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
enum nfqnl_attr_config {
|
||||
NFQA_CFG_UNSPEC,
|
||||
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
|
||||
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
|
||||
NFQA_CFG_QUEUE_MAXLEN, /* __u32 */
|
||||
NFQA_CFG_MASK, /* identify which flags to change */
|
||||
NFQA_CFG_FLAGS, /* value of these flags (__u32) */
|
||||
__NFQA_CFG_MAX
|
||||
};
|
||||
#define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
|
||||
|
||||
/* Flags for NFQA_CFG_FLAGS */
|
||||
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
|
||||
#define NFQA_CFG_F_CONNTRACK (1 << 1)
|
||||
#define NFQA_CFG_F_GSO (1 << 2)
|
||||
#define NFQA_CFG_F_UID_GID (1 << 3)
|
||||
#define NFQA_CFG_F_SECCTX (1 << 4)
|
||||
#define NFQA_CFG_F_MAX (1 << 5)
|
||||
|
||||
/* flags for NFQA_SKB_INFO */
|
||||
/* packet appears to have wrong checksums, but they are ok */
|
||||
#define NFQA_SKB_CSUMNOTREADY (1 << 0)
|
||||
/* packet is GSO (i.e., exceeds device mtu) */
|
||||
#define NFQA_SKB_GSO (1 << 1)
|
||||
/* csum not validated (incoming device doesn't support hw checksum, etc.) */
|
||||
#define NFQA_SKB_CSUM_NOTVERIFIED (1 << 2)
|
||||
|
||||
#endif /* _NFNETLINK_QUEUE_H */
|
||||
26
ref/libnetfilter-queue/include/libnetfilter_queue/pktbuff.h
Normal file
26
ref/libnetfilter-queue/include/libnetfilter_queue/pktbuff.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _PKTBUFF_H_
|
||||
#define _PKTBUFF_H_
|
||||
|
||||
struct pkt_buff;
|
||||
|
||||
struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra);
|
||||
void pktb_free(struct pkt_buff *pktb);
|
||||
|
||||
uint8_t *pktb_data(struct pkt_buff *pktb);
|
||||
uint32_t pktb_len(struct pkt_buff *pktb);
|
||||
|
||||
void pktb_push(struct pkt_buff *pktb, unsigned int len);
|
||||
void pktb_pull(struct pkt_buff *pktb, unsigned int len);
|
||||
void pktb_put(struct pkt_buff *pktb, unsigned int len);
|
||||
void pktb_trim(struct pkt_buff *pktb, unsigned int len);
|
||||
unsigned int pktb_tailroom(struct pkt_buff *pktb);
|
||||
|
||||
uint8_t *pktb_mac_header(struct pkt_buff *pktb);
|
||||
uint8_t *pktb_network_header(struct pkt_buff *pktb);
|
||||
uint8_t *pktb_transport_header(struct pkt_buff *pktb);
|
||||
|
||||
int pktb_mangle(struct pkt_buff *pktb, int dataoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
|
||||
|
||||
bool pktb_mangled(const struct pkt_buff *pktb);
|
||||
|
||||
#endif
|
||||
1
ref/libnetfilter-queue/include/linux/Makefile.am
Normal file
1
ref/libnetfilter-queue/include/linux/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS = netfilter
|
||||
@ -0,0 +1 @@
|
||||
noinst_HEADERS = nfnetlink_queue.h
|
||||
115
ref/libnetfilter-queue/include/linux/netfilter/nfnetlink_queue.h
Normal file
115
ref/libnetfilter-queue/include/linux/netfilter/nfnetlink_queue.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef _NFNETLINK_QUEUE_H
|
||||
#define _NFNETLINK_QUEUE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
||||
enum nfqnl_msg_types {
|
||||
NFQNL_MSG_PACKET, /* packet from kernel to userspace */
|
||||
NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */
|
||||
NFQNL_MSG_CONFIG, /* connect to a particular queue */
|
||||
NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */
|
||||
|
||||
NFQNL_MSG_MAX
|
||||
};
|
||||
|
||||
struct nfqnl_msg_packet_hdr {
|
||||
__be32 packet_id; /* unique ID of packet in queue */
|
||||
__be16 hw_protocol; /* hw protocol (network order) */
|
||||
__u8 hook; /* netfilter hook */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfqnl_msg_packet_hw {
|
||||
__be16 hw_addrlen;
|
||||
__u16 _pad;
|
||||
__u8 hw_addr[8];
|
||||
};
|
||||
|
||||
struct nfqnl_msg_packet_timestamp {
|
||||
__aligned_be64 sec;
|
||||
__aligned_be64 usec;
|
||||
};
|
||||
|
||||
enum nfqnl_attr_type {
|
||||
NFQA_UNSPEC,
|
||||
NFQA_PACKET_HDR,
|
||||
NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */
|
||||
NFQA_MARK, /* __u32 nfmark */
|
||||
NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */
|
||||
NFQA_IFINDEX_INDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_OUTDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_PHYSINDEV, /* __u32 ifindex */
|
||||
NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */
|
||||
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
|
||||
NFQA_PAYLOAD, /* opaque data payload */
|
||||
NFQA_CT, /* nf_conntrack_netlink.h */
|
||||
NFQA_CT_INFO, /* enum ip_conntrack_info */
|
||||
NFQA_CAP_LEN, /* __u32 length of captured packet */
|
||||
NFQA_SKB_INFO, /* __u32 skb meta information */
|
||||
NFQA_EXP, /* nf_conntrack_netlink.h */
|
||||
NFQA_UID, /* __u32 sk uid */
|
||||
NFQA_GID, /* __u32 sk gid */
|
||||
NFQA_SECCTX,
|
||||
|
||||
__NFQA_MAX
|
||||
};
|
||||
#define NFQA_MAX (__NFQA_MAX - 1)
|
||||
|
||||
struct nfqnl_msg_verdict_hdr {
|
||||
__be32 verdict;
|
||||
__be32 id;
|
||||
};
|
||||
|
||||
|
||||
enum nfqnl_msg_config_cmds {
|
||||
NFQNL_CFG_CMD_NONE,
|
||||
NFQNL_CFG_CMD_BIND,
|
||||
NFQNL_CFG_CMD_UNBIND,
|
||||
NFQNL_CFG_CMD_PF_BIND,
|
||||
NFQNL_CFG_CMD_PF_UNBIND,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_cmd {
|
||||
__u8 command; /* nfqnl_msg_config_cmds */
|
||||
__u8 _pad;
|
||||
__be16 pf; /* AF_xxx for PF_[UN]BIND */
|
||||
};
|
||||
|
||||
enum nfqnl_config_mode {
|
||||
NFQNL_COPY_NONE,
|
||||
NFQNL_COPY_META,
|
||||
NFQNL_COPY_PACKET,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_params {
|
||||
__be32 copy_range;
|
||||
__u8 copy_mode; /* enum nfqnl_config_mode */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
enum nfqnl_attr_config {
|
||||
NFQA_CFG_UNSPEC,
|
||||
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
|
||||
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
|
||||
NFQA_CFG_QUEUE_MAXLEN, /* __u32 */
|
||||
NFQA_CFG_MASK, /* identify which flags to change */
|
||||
NFQA_CFG_FLAGS, /* value of these flags (__u32) */
|
||||
__NFQA_CFG_MAX
|
||||
};
|
||||
#define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
|
||||
|
||||
/* Flags for NFQA_CFG_FLAGS */
|
||||
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
|
||||
#define NFQA_CFG_F_CONNTRACK (1 << 1)
|
||||
#define NFQA_CFG_F_GSO (1 << 2)
|
||||
#define NFQA_CFG_F_UID_GID (1 << 3)
|
||||
#define NFQA_CFG_F_SECCTX (1 << 4)
|
||||
#define NFQA_CFG_F_MAX (1 << 5)
|
||||
|
||||
/* flags for NFQA_SKB_INFO */
|
||||
/* packet appears to have wrong checksums, but they are ok */
|
||||
#define NFQA_SKB_CSUMNOTREADY (1 << 0)
|
||||
/* packet is GSO (i.e., exceeds device mtu) */
|
||||
#define NFQA_SKB_GSO (1 << 1)
|
||||
|
||||
#endif /* _NFNETLINK_QUEUE_H */
|
||||
16
ref/libnetfilter-queue/libnetfilter_queue.pc.in
Normal file
16
ref/libnetfilter-queue/libnetfilter_queue.pc.in
Normal file
@ -0,0 +1,16 @@
|
||||
# libnetfilter_queue pkg-config file
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libnetfilter_queue
|
||||
Description: netfilter userspace packet queueing library
|
||||
URL: http://netfilter.org/projects/libnetfilter_queue/
|
||||
Version: @VERSION@
|
||||
Requires: libnfnetlink
|
||||
Conflicts:
|
||||
Libs: -L${libdir} -lnetfilter_queue
|
||||
Libs.private: @LIBNFNETLINK_LIBS@
|
||||
Cflags: -I${includedir}
|
||||
2
ref/libnetfilter-queue/m4/.gitignore
vendored
Normal file
2
ref/libnetfilter-queue/m4/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/libtool.m4
|
||||
/lt*.m4
|
||||
21
ref/libnetfilter-queue/m4/gcc4_visibility.m4
Normal file
21
ref/libnetfilter-queue/m4/gcc4_visibility.m4
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
# GCC 4.x -fvisibility=hidden
|
||||
|
||||
AC_DEFUN([CHECK_GCC_FVISIBILITY], [
|
||||
AC_LANG_PUSH([C])
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$saved_CFLAGS -fvisibility=hidden"
|
||||
AC_CACHE_CHECK([whether compiler accepts -fvisibility=hidden],
|
||||
[ac_cv_fvisibility_hidden], AC_COMPILE_IFELSE(
|
||||
[AC_LANG_SOURCE()],
|
||||
[ac_cv_fvisibility_hidden=yes],
|
||||
[ac_cv_fvisibility_hidden=no]
|
||||
))
|
||||
if test "$ac_cv_fvisibility_hidden" = "yes"; then
|
||||
AC_DEFINE([HAVE_VISIBILITY_HIDDEN], [1],
|
||||
[True if compiler supports -fvisibility=hidden])
|
||||
AC_SUBST([GCC_FVISIBILITY_HIDDEN], [-fvisibility=hidden])
|
||||
fi
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_LANG_POP([C])
|
||||
])
|
||||
40
ref/libnetfilter-queue/src/Makefile.am
Normal file
40
ref/libnetfilter-queue/src/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
||||
# This is _NOT_ the library release version, it's an API version.
|
||||
# Extracted from Chapter 6 "Library interface versions" of the libtool docs.
|
||||
#
|
||||
# <snippet>
|
||||
# Here are a set of rules to help you update your library version information:
|
||||
#
|
||||
# 1. Start with version information of `0:0:0' for each libtool library.
|
||||
# 2. Update the version information only immediately before a public release
|
||||
# of your software. More frequent updates are unnecessary, and only guarantee
|
||||
# that the current interface number gets larger faster.
|
||||
# 3. If the library source code has changed at all since the last update,
|
||||
# then increment revision (`c:r:a' becomes `c:r+1:a').
|
||||
# 4. If any interfaces have been added, removed, or changed since the last
|
||||
# update, increment current, and set revision to 0.
|
||||
# 5. If any interfaces have been added since the last public release, then
|
||||
# increment age.
|
||||
# 6. If any interfaces have been removed since the last public release, then
|
||||
# set age to 0.
|
||||
# </snippet>
|
||||
#
|
||||
LIBVERSION=6:0:5
|
||||
|
||||
include ${top_srcdir}/Make_global.am
|
||||
|
||||
lib_LTLIBRARIES = libnetfilter_queue.la
|
||||
|
||||
noinst_HEADERS = internal.h
|
||||
|
||||
libnetfilter_queue_la_LDFLAGS = -Wc,-nostartfiles -lnfnetlink \
|
||||
-version-info $(LIBVERSION)
|
||||
libnetfilter_queue_la_SOURCES = libnetfilter_queue.c \
|
||||
nlmsg.c \
|
||||
extra/checksum.c \
|
||||
extra/ipv6.c \
|
||||
extra/tcp.c \
|
||||
extra/ipv4.c \
|
||||
extra/pktbuff.c \
|
||||
extra/udp.c
|
||||
|
||||
libnetfilter_queue_la_LIBADD = ${LIBNFNETLINK_LIBS} ${LIBMNL_LIBS}
|
||||
82
ref/libnetfilter-queue/src/extra/checksum.c
Normal file
82
ref/libnetfilter-queue/src/extra/checksum.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <endian.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
uint16_t nfq_checksum(uint32_t sum, uint16_t *buf, int size)
|
||||
{
|
||||
while (size > 1) {
|
||||
sum += *buf++;
|
||||
size -= sizeof(uint16_t);
|
||||
}
|
||||
if (size) {
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
sum += (uint16_t)*(uint8_t *)buf << 8;
|
||||
#else
|
||||
sum += (uint16_t)*(uint8_t *)buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >>16);
|
||||
|
||||
return (uint16_t)(~sum);
|
||||
}
|
||||
|
||||
uint16_t nfq_checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protonum)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint32_t iph_len = iph->ihl*4;
|
||||
uint32_t len = ntohs(iph->tot_len) - iph_len;
|
||||
uint8_t *payload = (uint8_t *)iph + iph_len;
|
||||
|
||||
sum += (iph->saddr >> 16) & 0xFFFF;
|
||||
sum += (iph->saddr) & 0xFFFF;
|
||||
sum += (iph->daddr >> 16) & 0xFFFF;
|
||||
sum += (iph->daddr) & 0xFFFF;
|
||||
sum += htons(protonum);
|
||||
sum += htons(len);
|
||||
|
||||
return nfq_checksum(sum, (uint16_t *)payload, len);
|
||||
}
|
||||
|
||||
uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr,
|
||||
uint16_t protonum)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint32_t hdr_len = (uint8_t *)transport_hdr - (uint8_t *)ip6h;
|
||||
/* Allow for extra headers before the UDP header */
|
||||
/* TODO: Deal with routing headers */
|
||||
uint32_t len = ntohs(ip6h->ip6_plen) - (hdr_len - sizeof *ip6h);
|
||||
uint8_t *payload = (uint8_t *)ip6h + hdr_len;
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
sum += (ip6h->ip6_src.s6_addr16[i]);
|
||||
}
|
||||
for (i=0; i<8; i++) {
|
||||
sum += (ip6h->ip6_dst.s6_addr16[i]);
|
||||
}
|
||||
sum += htons(protonum);
|
||||
sum += htons(len);
|
||||
|
||||
return nfq_checksum(sum, (uint16_t *)payload, len);
|
||||
}
|
||||
175
ref/libnetfilter-queue/src/extra/ipv4.c
Normal file
175
ref/libnetfilter-queue/src/extra/ipv4.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
|
||||
#include <libnetfilter_queue/pktbuff.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup ipv4 IPv4 helper functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_ip_get_hdr - get the IPv4 header
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
* \returns validated pointer to the IPv4 header or NULL if IP is malformed or
|
||||
* not version 4
|
||||
*
|
||||
* Many programs will not need to call this function. A possible use is to
|
||||
* determine the layer 4 protocol. The validation is that the buffer is big
|
||||
* enough for the declared lengths in the header, i.e. an extra check for packet
|
||||
* truncation.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct iphdr *nfq_ip_get_hdr(struct pkt_buff *pktb)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
unsigned int pktlen = pktb_tail(pktb) - pktb->network_header;
|
||||
|
||||
/* Not enough room for IPv4 header. */
|
||||
if (pktlen < sizeof(struct iphdr))
|
||||
return NULL;
|
||||
|
||||
iph = (struct iphdr *)pktb->network_header;
|
||||
|
||||
/* Not IPv4 packet. */
|
||||
if (iph->version != 4)
|
||||
return NULL;
|
||||
|
||||
/* Malformed IPv4 total length field. */
|
||||
if (ntohs(iph->tot_len) > pktlen)
|
||||
return NULL;
|
||||
|
||||
return iph;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_ip_set_transport_header - set the \b transport_header field in \b pktb
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
* \param iph: Pointer to the IPv4 header
|
||||
* \returns 0 on success or -1 if a minimal validation check fails
|
||||
* \note
|
||||
* Most programs should call __nfq_ip_set_transport_header__ as soon as
|
||||
* possible, since most layer 4 helper functions assume the
|
||||
* \b transport_header field is valid.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip_set_transport_header(struct pkt_buff *pktb, struct iphdr *iph)
|
||||
{
|
||||
int doff = iph->ihl * 4;
|
||||
|
||||
/* Wrong offset to IPv4 payload. */
|
||||
if ((int)pktb->len - doff <= 0)
|
||||
return -1;
|
||||
|
||||
pktb->transport_header = pktb->network_header + doff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \defgroup ip_internals Internal IP functions
|
||||
*
|
||||
* Most user-space programs will never need these.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_ip_set_checksum - set IPv4 checksum
|
||||
* \param iph: Pointer to the IPv4 header
|
||||
* \note
|
||||
* nfq_ip_mangle() invokes this function.
|
||||
* As long as developers always use the appropriate mangler for the layer being
|
||||
* mangled, there is no need to call __nfq_ip_set_checksum__.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_ip_set_checksum(struct iphdr *iph)
|
||||
{
|
||||
uint32_t iph_len = iph->ihl * 4;
|
||||
|
||||
iph->check = 0;
|
||||
iph->check = nfq_checksum(0, (uint16_t *)iph, iph_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_ip_mangle - mangle IPv4 packet buffer
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
* \param dataoff: Offset to layer 4 header, or zero to mangle IP header
|
||||
* \param match_offset: Offset to content that you want to mangle
|
||||
* \param match_len: Length of the existing content you want to mangle
|
||||
* \param rep_buffer: Pointer to data you want to use to replace current content
|
||||
* \param rep_len: Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv4 length if necessary and recalculates the
|
||||
* IPv4 checksum.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip_mangle(struct pkt_buff *pktb, unsigned int dataoff,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct iphdr *iph = (struct iphdr *) pktb->network_header;
|
||||
|
||||
if (!pktb_mangle(pktb, dataoff, match_offset, match_len, rep_buffer,
|
||||
rep_len))
|
||||
return 0;
|
||||
|
||||
/* fix IP hdr checksum information */
|
||||
iph->tot_len = htons(pktb_tail(pktb) - pktb->network_header);
|
||||
nfq_ip_set_checksum(iph);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_pkt_snprintf_ip - print IPv4 header into buffer in iptables LOG format
|
||||
* \param buf: Pointer to buffer that will be used to print the header
|
||||
* \param size: Size of the buffer (or remaining room in it)
|
||||
* \param iph: Pointer to a valid IPv4 header
|
||||
* \returns same as snprintf
|
||||
* \sa **snprintf**(3)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip_snprintf(char *buf, size_t size, const struct iphdr *iph)
|
||||
{
|
||||
int ret;
|
||||
struct in_addr src = { iph->saddr };
|
||||
struct in_addr dst = { iph->daddr };
|
||||
|
||||
char src_str[INET_ADDRSTRLEN];
|
||||
char dst_str[INET_ADDRSTRLEN];
|
||||
|
||||
ret = snprintf(buf, size, "SRC=%s DST=%s LEN=%u TOS=0x%X "
|
||||
"PREC=0x%X TTL=%u ID=%u PROTO=%u ",
|
||||
inet_ntop(AF_INET, &src, src_str, INET_ADDRSTRLEN),
|
||||
inet_ntop(AF_INET, &dst, dst_str, INET_ADDRSTRLEN),
|
||||
ntohs(iph->tot_len), IPTOS_TOS(iph->tos),
|
||||
IPTOS_PREC(iph->tos), iph->ttl, ntohs(iph->id),
|
||||
iph->protocol);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
180
ref/libnetfilter-queue/src/extra/ipv6.c
Normal file
180
ref/libnetfilter-queue/src/extra/ipv6.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv6.h>
|
||||
#include <libnetfilter_queue/pktbuff.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup ipv6 IPv6 helper functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_ip6_get_hdr - get IPv6 header
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
*
|
||||
* \returns pointer to IPv6 header if a valid header found, else NULL.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct ip6_hdr *nfq_ip6_get_hdr(struct pkt_buff *pktb)
|
||||
{
|
||||
struct ip6_hdr *ip6h;
|
||||
unsigned int pktlen = pktb_tail(pktb) - pktb->network_header;
|
||||
|
||||
/* Not enough room for IPv6 header. */
|
||||
if (pktlen < sizeof(struct ip6_hdr))
|
||||
return NULL;
|
||||
|
||||
ip6h = (struct ip6_hdr *)pktb->network_header;
|
||||
|
||||
/* Not IPv6 packet. */
|
||||
if ((*(uint8_t *)ip6h & 0xf0) != 0x60)
|
||||
return NULL;
|
||||
|
||||
return ip6h;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_ip6_set_transport_header - set transport header pointer for IPv6 packet
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
* \param ip6h: Pointer to IPv6 header
|
||||
* \param target: Protocol number to find transport header (ie. IPPROTO_*)
|
||||
*
|
||||
* \returns 1 if the protocol has been found and the transport
|
||||
* header has been set, else 0.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *ip6h,
|
||||
uint8_t target)
|
||||
{
|
||||
uint8_t nexthdr = ip6h->ip6_nxt;
|
||||
uint8_t *cur = (uint8_t *)ip6h + sizeof(struct ip6_hdr);
|
||||
|
||||
while (nexthdr != target) {
|
||||
struct ip6_ext *ip6_ext;
|
||||
uint32_t hdrlen;
|
||||
|
||||
/* No more extensions, we're done. */
|
||||
if (nexthdr == IPPROTO_NONE) {
|
||||
cur = NULL;
|
||||
break;
|
||||
}
|
||||
/* No room for extension, bad packet. */
|
||||
if (pktb_tail(pktb) - cur < sizeof(struct ip6_ext)) {
|
||||
cur = NULL;
|
||||
break;
|
||||
}
|
||||
ip6_ext = (struct ip6_ext *)cur;
|
||||
|
||||
if (nexthdr == IPPROTO_FRAGMENT) {
|
||||
uint16_t *frag_off;
|
||||
|
||||
/* No room for full fragment header, bad packet. */
|
||||
if (pktb_tail(pktb) - cur < sizeof(struct ip6_frag)) {
|
||||
cur = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
frag_off = (uint16_t *)cur +
|
||||
offsetof(struct ip6_frag, ip6f_offlg);
|
||||
|
||||
/* Fragment offset is only 13 bits long. */
|
||||
if (htons(*frag_off & ~0x7)) {
|
||||
/* Not the first fragment, it does not contain
|
||||
* any headers.
|
||||
*/
|
||||
cur = NULL;
|
||||
break;
|
||||
}
|
||||
hdrlen = sizeof(struct ip6_frag);
|
||||
} else if (nexthdr == IPPROTO_AH)
|
||||
hdrlen = (ip6_ext->ip6e_len + 2) << 2;
|
||||
else
|
||||
hdrlen = ip6_ext->ip6e_len;
|
||||
|
||||
nexthdr = ip6_ext->ip6e_nxt;
|
||||
cur += hdrlen;
|
||||
}
|
||||
pktb->transport_header = cur;
|
||||
return cur ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_ip6_mangle - mangle IPv6 packet buffer
|
||||
* \param pktb: Pointer to user-space network packet buffer
|
||||
* \param dataoff: Offset to layer 4 header
|
||||
* \param match_offset: Offset to content that you want to mangle
|
||||
* \param match_len: Length of the existing content you want to mangle
|
||||
* \param rep_buffer: Pointer to data you want to use to replace current content
|
||||
* \param rep_len: Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv6 length (if necessary)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip6_mangle(struct pkt_buff *pktb, unsigned int dataoff,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct ip6_hdr *ip6h = (struct ip6_hdr *)pktb->network_header;
|
||||
|
||||
if (!pktb_mangle(pktb, dataoff, match_offset, match_len, rep_buffer,
|
||||
rep_len))
|
||||
return 0;
|
||||
|
||||
/* Fix IPv6 hdr length information */
|
||||
ip6h->ip6_plen =
|
||||
htons(pktb_tail(pktb) - pktb->network_header - sizeof *ip6h);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_ip6_snprintf - print IPv6 header into one buffer in iptables LOG format
|
||||
* \param buf: Pointer to buffer that is used to print the object
|
||||
* \param size: Size of the buffer (or remaining room in it).
|
||||
* \param ip6h: Pointer to a valid IPv6 header.
|
||||
* \returns same as snprintf
|
||||
* \sa **snprintf**(3)
|
||||
*
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_ip6_snprintf(char *buf, size_t size, const struct ip6_hdr *ip6h)
|
||||
{
|
||||
int ret;
|
||||
char src[INET6_ADDRSTRLEN];
|
||||
char dst[INET6_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET6, &ip6h->ip6_src, src, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &ip6h->ip6_dst, dst, INET6_ADDRSTRLEN);
|
||||
|
||||
ret = snprintf(buf, size, "SRC=%s DST=%s LEN=%zu TC=0x%X "
|
||||
"HOPLIMIT=%u FLOWLBL=%u ",
|
||||
src, dst,
|
||||
ntohs(ip6h->ip6_plen) + sizeof(struct ip6_hdr),
|
||||
(ip6h->ip6_flow & 0x0ff00000) >> 20,
|
||||
ip6h->ip6_hlim,
|
||||
(ip6h->ip6_flow & 0x000fffff));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
366
ref/libnetfilter-queue/src/extra/pktbuff.c
Normal file
366
ref/libnetfilter-queue/src/extra/pktbuff.c
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup pktbuff User-space network packet buffer
|
||||
*
|
||||
* This library provides the user-space network packet buffer. This abstraction
|
||||
* is strongly inspired by Linux kernel network buffer, the so-called sk_buff.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* pktb_alloc - allocate a new packet buffer
|
||||
* \param family Indicate what family. Currently supported families are
|
||||
* AF_BRIDGE, AF_INET & AF_INET6.
|
||||
* \param data Pointer to packet data
|
||||
* \param len Packet length
|
||||
* \param extra Extra memory in the tail to be allocated (for mangling)
|
||||
*
|
||||
* This function returns a packet buffer that contains the packet data and
|
||||
* some extra memory room in the tail (if requested).
|
||||
*
|
||||
* \return Pointer to a new userspace packet buffer or NULL on failure.
|
||||
* \par Errors
|
||||
* __ENOMEM__ From __calloc__()
|
||||
* \n
|
||||
* __EPROTONOSUPPORT__ _family_ was __AF_BRIDGE__ and this is not an IP packet
|
||||
* (v4 or v6)
|
||||
* \sa __calloc__(3)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct pkt_buff *pktb_alloc(int family, void *data, size_t len, size_t extra)
|
||||
{
|
||||
struct pkt_buff *pktb;
|
||||
struct ethhdr *ethhdr;
|
||||
void *pkt_data;
|
||||
|
||||
pktb = calloc(1, sizeof(struct pkt_buff) + len + extra);
|
||||
if (pktb == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Better make sure alignment is correct. */
|
||||
pkt_data = (uint8_t *)pktb + sizeof(struct pkt_buff);
|
||||
memcpy(pkt_data, data, len);
|
||||
|
||||
pktb->len = len;
|
||||
pktb->data_len = len + extra;
|
||||
|
||||
pktb->data = pkt_data;
|
||||
|
||||
switch(family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
pktb->network_header = pktb->data;
|
||||
break;
|
||||
case AF_BRIDGE:
|
||||
ethhdr = (struct ethhdr *)pktb->data;
|
||||
pktb->mac_header = pktb->data;
|
||||
|
||||
switch(ethhdr->h_proto) {
|
||||
case ETH_P_IP:
|
||||
case ETH_P_IPV6:
|
||||
pktb->network_header = pktb->data + ETH_HLEN;
|
||||
break;
|
||||
default:
|
||||
/* This protocol is unsupported. */
|
||||
errno = EPROTONOSUPPORT;
|
||||
free(pktb);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return pktb;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_data - get pointer to network packet
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return Pointer to start of network packet data within __pktb__
|
||||
* \par
|
||||
* It is appropriate to use _pktb_data_ as the second argument of
|
||||
* nfq_nlmsg_verdict_put_pkt()
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
uint8_t *pktb_data(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_len - get length of packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return Length of packet contained within __pktb__
|
||||
* \par
|
||||
* It is appropriate to use _pktb_len_ as the third argument of
|
||||
* nfq_nlmsg_verdict_put_pkt()
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
uint32_t pktb_len(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_free - release packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void pktb_free(struct pkt_buff *pktb)
|
||||
{
|
||||
free(pktb);
|
||||
}
|
||||
|
||||
/**
|
||||
* \defgroup otherfns Other functions
|
||||
*
|
||||
* The library provides a number of other functions which many user-space
|
||||
* programs will never need. These divide into 2 groups:
|
||||
* \n
|
||||
* 1. Functions to get values of members of opaque __struct pktbuff__, described
|
||||
* below
|
||||
* \n
|
||||
* 2. Internal functions, described in Module __Internal functions__
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup uselessfns Internal functions
|
||||
*
|
||||
* \warning Do not use these functions. Instead, always use the mangle
|
||||
* function appropriate to the level at which you are working.
|
||||
* \n
|
||||
* pktb_mangle() uses all the below functions except _pktb_pull_, which is not
|
||||
* used by anything.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* pktb_push - decrement pointer to packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \param len Number of bytes to subtract from packet start address
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void pktb_push(struct pkt_buff *pktb, unsigned int len)
|
||||
{
|
||||
pktb->data -= len;
|
||||
pktb->len += len;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_pull - increment pointer to packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \param len Number of bytes to add to packet start address
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void pktb_pull(struct pkt_buff *pktb, unsigned int len)
|
||||
{
|
||||
pktb->data += len;
|
||||
pktb->len -= len;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_put - add extra bytes to the tail of the packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \param len Number of bytes to add to packet tail (and length)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void pktb_put(struct pkt_buff *pktb, unsigned int len)
|
||||
{
|
||||
pktb->len += len;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_trim - set new length for this packet buffer
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \param len New packet length (tail is adjusted to reflect this)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void pktb_trim(struct pkt_buff *pktb, unsigned int len)
|
||||
{
|
||||
pktb->len = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* pktb_tailroom - get room available for packet expansion
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return room in bytes after the tail of the packet buffer
|
||||
* \n
|
||||
* This starts off as the __extra__ argument to pktb_alloc().
|
||||
* Programmers should ensure this __extra__ argument is sufficient for any
|
||||
* packet mangle, as packet buffers cannot be expanded dynamically.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
unsigned int pktb_tailroom(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->data_len - pktb->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_mac_header - get address of layer 2 header (if any)
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return Pointer to MAC header or NULL if no such header present.
|
||||
* \n
|
||||
* Only packet buffers in family __AF_BRIDGE__ have a non-NULL MAC header.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
uint8_t *pktb_mac_header(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->mac_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_network_header - get address of layer 3 header
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return Pointer to layer 3 header or NULL if the packet buffer was created
|
||||
* with an unsupported family
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
uint8_t *pktb_network_header(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->network_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_transport_header - get address of layer 4 header (if known)
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return Pointer to layer 4 header or NULL if not (yet) set
|
||||
* \note
|
||||
* Unlike the lower-level headers, it is the programmer's responsibility to
|
||||
* create the level 4 (transport) header pointer by caling e.g.
|
||||
* nfq_ip_set_transport_header()
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
uint8_t *pktb_transport_header(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->transport_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
static int pktb_expand_tail(struct pkt_buff *pktb, int extra)
|
||||
{
|
||||
/* No room in packet, cannot mangle it. We don't support dynamic
|
||||
* reallocation. Instead, increase the size of the extra room in
|
||||
* the tail in pktb_alloc.
|
||||
*/
|
||||
if (pktb->len + extra > pktb->data_len)
|
||||
return 0;
|
||||
|
||||
pktb->len += extra;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int enlarge_pkt(struct pkt_buff *pktb, unsigned int extra)
|
||||
{
|
||||
if (pktb->len + extra > 65535)
|
||||
return 0;
|
||||
|
||||
if (!pktb_expand_tail(pktb, extra - pktb_tailroom(pktb)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_mangle - adjust contents of a packet
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \param dataoff Supplementary offset, usually offset from layer 3 (IP) header
|
||||
* to the layer 4 (TCP or UDP) header. Specify zero to access the layer 3
|
||||
* header. If \b pktb was created in family \b AF_BRIDGE, specify
|
||||
* \b -ETH_HLEN (a negative offset) to access the layer 2 (MAC) header.
|
||||
* \param match_offset Further offset to content that you want to mangle
|
||||
* \param match_len Length of the existing content you want to mangle
|
||||
* \param rep_buffer Pointer to data you want to use to replace current content
|
||||
* \param rep_len Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. Failure will occur if the \b extra
|
||||
* argument to the pktb_alloc() call that created \b pktb is less than the
|
||||
* excess of \b rep_len over \b match_len
|
||||
\warning pktb_mangle does not update any checksums. Developers should use the
|
||||
appropriate mangler for the protocol level: nfq_ip_mangle(),
|
||||
nfq_tcp_mangle_ipv4() or nfq_udp_mangle_ipv4(). IPv6 versions are planned.
|
||||
\n
|
||||
It is appropriate to use pktb_mangle to change the MAC header.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int pktb_mangle(struct pkt_buff *pktb,
|
||||
int dataoff,
|
||||
unsigned int match_offset,
|
||||
unsigned int match_len,
|
||||
const char *rep_buffer,
|
||||
unsigned int rep_len)
|
||||
{
|
||||
unsigned char *data;
|
||||
|
||||
if (rep_len > match_len &&
|
||||
rep_len - match_len > pktb_tailroom(pktb) &&
|
||||
!enlarge_pkt(pktb, rep_len - match_len))
|
||||
return 0;
|
||||
|
||||
data = pktb->network_header + dataoff;
|
||||
|
||||
/* move post-replacement */
|
||||
memmove(data + match_offset + rep_len,
|
||||
data + match_offset + match_len,
|
||||
pktb_tail(pktb) - (pktb->network_header + dataoff +
|
||||
match_offset + match_len));
|
||||
|
||||
/* insert data from buffer */
|
||||
memcpy(data + match_offset, rep_buffer, rep_len);
|
||||
|
||||
/* update packet info */
|
||||
if (rep_len > match_len)
|
||||
pktb_put(pktb, rep_len - match_len);
|
||||
else
|
||||
pktb_trim(pktb, pktb->len + rep_len - match_len);
|
||||
|
||||
pktb->mangled = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* pktb_mangled - test whether packet has been mangled
|
||||
* \param pktb Pointer to userspace packet buffer
|
||||
* \return __true__ if packet has been mangled (modified), else __false__
|
||||
* \par
|
||||
* When assembling a verdict, it is not necessary to return the contents of
|
||||
* un-modified packets. Use _pktb_mangled_ to decide whether packet contents
|
||||
* need to be returned.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
bool pktb_mangled(const struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->mangled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
279
ref/libnetfilter-queue/src/extra/tcp.c
Normal file
279
ref/libnetfilter-queue/src/extra/tcp.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <stdbool.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_tcp.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv6.h>
|
||||
#include <libnetfilter_queue/pktbuff.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup tcp TCP helper functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_tcp_get_hdr - get the TCP header
|
||||
* \param pktb: pointer to user-space network packet buffer
|
||||
* \returns validated pointer to the TCP header or NULL if the TCP header was
|
||||
* not set or if a minimal length check fails.
|
||||
* \note You have to call nfq_ip_set_transport_header() or
|
||||
* nfq_ip6_set_transport_header() first to set the TCP header.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct tcphdr *nfq_tcp_get_hdr(struct pkt_buff *pktb)
|
||||
{
|
||||
if (pktb->transport_header == NULL)
|
||||
return NULL;
|
||||
|
||||
/* No room for the TCP header. */
|
||||
if (pktb_tail(pktb) - pktb->transport_header < sizeof(struct tcphdr))
|
||||
return NULL;
|
||||
|
||||
return (struct tcphdr *)pktb->transport_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_tcp_get_payload - get the TCP packet payload
|
||||
* \param tcph: pointer to the TCP header
|
||||
* \param pktb: pointer to user-space network packet buffer
|
||||
* \returns Pointer to the TCP payload, or NULL if malformed TCP packet.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void *nfq_tcp_get_payload(struct tcphdr *tcph, struct pkt_buff *pktb)
|
||||
{
|
||||
unsigned int len = tcph->doff * 4;
|
||||
|
||||
/* TCP packet is too short */
|
||||
if (len < sizeof(struct tcphdr))
|
||||
return NULL;
|
||||
|
||||
/* malformed TCP data offset. */
|
||||
if (pktb->transport_header + len > pktb_tail(pktb))
|
||||
return NULL;
|
||||
|
||||
return pktb->transport_header + len;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_tcp_get_payload_len - get the tcp packet payload
|
||||
* \param tcph: pointer to the TCP header
|
||||
* \param pktb: pointer to user-space network packet buffer
|
||||
* \returns Length of TCP payload (user data)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
unsigned int nfq_tcp_get_payload_len(struct tcphdr *tcph, struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb_tail(pktb) - pktb->transport_header - (tcph->doff * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* \defgroup tcp_internals Internal TCP functions
|
||||
*
|
||||
* Most user-space programs will never need these.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_tcp_compute_checksum_ipv4 - computes IPv4/TCP packet checksum
|
||||
* \param tcph: pointer to the TCP header
|
||||
* \param iph: pointer to the IPv4 header
|
||||
* \note
|
||||
* nfq_tcp_mangle_ipv4() invokes this function.
|
||||
* As long as developers always use __nfq_tcp_mangle_ipv4__ when changing the
|
||||
* content of a TCP message, there is no need to call
|
||||
* __nfq_tcp_compute_checksum_ipv4__.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph)
|
||||
{
|
||||
/* checksum field in header needs to be zero for calculation. */
|
||||
tcph->check = 0;
|
||||
tcph->check = nfq_checksum_tcpudp_ipv4(iph, IPPROTO_TCP);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_tcp_compute_checksum_ipv6 - computes IPv6/TCP packet checksum
|
||||
* \param tcph: pointer to the TCP header
|
||||
* \param ip6h: pointer to the IPv6 header
|
||||
* \note
|
||||
* nfq_tcp_mangle_ipv6() invokes this function.
|
||||
* As long as developers always use __nfq_tcp_mangle_ipv6__ when changing the
|
||||
* content of a TCP message, there is no need to call
|
||||
* __nfq_tcp_compute_checksum_ipv6__.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_tcp_compute_checksum_ipv6(struct tcphdr *tcph, struct ip6_hdr *ip6h)
|
||||
{
|
||||
/* checksum field in header needs to be zero for calculation. */
|
||||
tcph->check = 0;
|
||||
tcph->check = nfq_checksum_tcpudp_ipv6(ip6h, tcph, IPPROTO_TCP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*
|
||||
* The union cast uses a gcc extension to avoid aliasing problems
|
||||
* (union is compatible to any of its members)
|
||||
* This means this part of the code is -fstrict-aliasing safe now.
|
||||
*/
|
||||
union tcp_word_hdr {
|
||||
struct tcphdr hdr;
|
||||
uint32_t words[5];
|
||||
};
|
||||
|
||||
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words[3])
|
||||
|
||||
/**
|
||||
* nfq_pkt_snprintf_tcp_hdr - print tcp header into one buffer in a humnan
|
||||
* readable way
|
||||
* \param buf: pointer to buffer that is used to print the object
|
||||
* \param size: size of the buffer (or remaining room in it).
|
||||
* \param tcph: pointer to a valid tcp header.
|
||||
* \returns Same as \b snprintf
|
||||
* \sa __snprintf__(3)
|
||||
*
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_tcp_snprintf(char *buf, size_t size, const struct tcphdr *tcph)
|
||||
{
|
||||
int ret, len = 0;
|
||||
|
||||
#define TCP_RESERVED_BITS htonl(0x0F000000)
|
||||
|
||||
ret = snprintf(buf, size, "SPT=%u DPT=%u SEQ=%u ACK=%u "
|
||||
"WINDOW=%u RES=0x%02x ",
|
||||
ntohs(tcph->source), ntohs(tcph->dest),
|
||||
ntohl(tcph->seq), ntohl(tcph->ack_seq),
|
||||
ntohs(tcph->window),
|
||||
(uint8_t)
|
||||
(ntohl(tcp_flag_word(tcph) & TCP_RESERVED_BITS) >> 22));
|
||||
len += ret;
|
||||
|
||||
if (tcph->urg) {
|
||||
ret = snprintf(buf+len, size-len, "URG ");
|
||||
len += ret;
|
||||
}
|
||||
if (tcph->ack) {
|
||||
ret = snprintf(buf+len, size-len, "ACK ");
|
||||
len += ret;
|
||||
}
|
||||
if (tcph->psh) {
|
||||
ret = snprintf(buf+len, size-len, "PSH ");
|
||||
len += ret;
|
||||
}
|
||||
if (tcph->rst) {
|
||||
ret = snprintf(buf+len, size-len, "RST ");
|
||||
len += ret;
|
||||
}
|
||||
if (tcph->syn) {
|
||||
ret = snprintf(buf+len, size-len, "SYN ");
|
||||
len += ret;
|
||||
}
|
||||
if (tcph->fin) {
|
||||
ret = snprintf(buf+len, size-len, "FIN ");
|
||||
len += ret;
|
||||
}
|
||||
/* XXX: Not TCP options implemented yet, sorry. */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_tcp_mangle_ipv4 - mangle TCP/IPv4 packet buffer
|
||||
* \param pktb: pointer to network packet buffer
|
||||
* \param match_offset: offset to content that you want to mangle
|
||||
* \param match_len: length of the existing content you want to mangle
|
||||
* \param rep_buffer: pointer to data you want to use to replace current content
|
||||
* \param rep_len: length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv4 length and recalculates the IPv4 & TCP
|
||||
* checksums for you.
|
||||
* \warning After changing the length of a TCP message, the application will
|
||||
* need to mangle sequence numbers in both directions until another change
|
||||
* puts them in sync again
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_tcp_mangle_ipv4(struct pkt_buff *pktb,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct tcphdr *tcph;
|
||||
|
||||
iph = (struct iphdr *)pktb->network_header;
|
||||
tcph = (struct tcphdr *)(pktb->network_header + iph->ihl*4);
|
||||
|
||||
if (!nfq_ip_mangle(pktb, iph->ihl*4 + tcph->doff*4,
|
||||
match_offset, match_len, rep_buffer, rep_len))
|
||||
return 0;
|
||||
|
||||
nfq_tcp_compute_checksum_ipv4(tcph, iph);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_tcp_mangle_ipv6 - Mangle TCP/IPv6 packet buffer
|
||||
* \param pktb: Pointer to network packet buffer
|
||||
* \param match_offset: Offset from start of TCP data of content that you want
|
||||
* to mangle
|
||||
* \param match_len: Length of the existing content you want to mangle
|
||||
* \param rep_buffer: Pointer to data you want to use to replace current content
|
||||
* \param rep_len: Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv6 length and recalculates the TCP
|
||||
* checksum for you.
|
||||
* \warning After changing the length of a TCP message, the application will
|
||||
* need to mangle sequence numbers in both directions until another change
|
||||
* puts them in sync again
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_tcp_mangle_ipv6(struct pkt_buff *pktb,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct ip6_hdr *ip6h;
|
||||
struct tcphdr *tcph;
|
||||
|
||||
ip6h = (struct ip6_hdr *)pktb->network_header;
|
||||
tcph = (struct tcphdr *)(pktb->transport_header);
|
||||
if (!tcph)
|
||||
return 0;
|
||||
|
||||
if (!nfq_ip6_mangle(pktb,
|
||||
pktb->transport_header - pktb->network_header +
|
||||
tcph->doff * 4,
|
||||
match_offset, match_len, rep_buffer, rep_len))
|
||||
return 0;
|
||||
|
||||
nfq_tcp_compute_checksum_ipv6(tcph, ip6h);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
228
ref/libnetfilter-queue/src/extra/udp.c
Normal file
228
ref/libnetfilter-queue/src/extra/udp.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_udp.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue_ipv6.h>
|
||||
#include <libnetfilter_queue/pktbuff.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup udp UDP helper functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_udp_get_hdr - get the UDP header.
|
||||
* \param pktb: Pointer to userspace network packet buffer
|
||||
*
|
||||
* \returns validated pointer to the UDP header or NULL if the UDP header was
|
||||
* not set or if a minimal length check fails.
|
||||
* \note You have to call nfq_ip_set_transport_header() or
|
||||
* nfq_ip6_set_transport_header() first to set the UDP header.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct udphdr *nfq_udp_get_hdr(struct pkt_buff *pktb)
|
||||
{
|
||||
if (pktb->transport_header == NULL)
|
||||
return NULL;
|
||||
|
||||
/* No room for the UDP header. */
|
||||
if (pktb_tail(pktb) - pktb->transport_header < sizeof(struct udphdr))
|
||||
return NULL;
|
||||
|
||||
return (struct udphdr *)pktb->transport_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_udp_get_payload - get the UDP packet payload.
|
||||
* \param udph: Pointer to UDP header
|
||||
* \param pktb: Pointer to userspace network packet buffer
|
||||
* \returns Pointer to the UDP payload, or NULL if malformed UDP packet.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void *nfq_udp_get_payload(struct udphdr *udph, struct pkt_buff *pktb)
|
||||
{
|
||||
uint16_t len = ntohs(udph->len);
|
||||
|
||||
/* the UDP packet is too short. */
|
||||
if (len < sizeof(struct udphdr))
|
||||
return NULL;
|
||||
|
||||
/* malformed UDP packet. */
|
||||
if (pktb->transport_header + len > pktb_tail(pktb))
|
||||
return NULL;
|
||||
|
||||
return pktb->transport_header + sizeof(struct udphdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_udp_get_payload_len - get the udp packet payload.
|
||||
* \param udph: Pointer to UDP header
|
||||
* \param pktb: Pointer to userspace network packet buffer
|
||||
* \returns Length of UDP payload (user data)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
unsigned int nfq_udp_get_payload_len(struct udphdr *udph, struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb_tail(pktb) - pktb->transport_header - sizeof(struct udphdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \defgroup udp_internals Internal UDP functions
|
||||
*
|
||||
* Most user-space programs will never need these.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_udp_compute_checksum_ipv4 - sets up the UDP checksum in a UDP/IPv4 packet
|
||||
* \param udph: pointer to the UDP header
|
||||
* \param iph: pointer to the IPv4 header
|
||||
* \note
|
||||
* nfq_udp_mangle_ipv4() invokes this function.
|
||||
* As long as developers always use __nfq_udp_mangle_ipv4__ when changing the
|
||||
* content of a UDP message, there is no need to call
|
||||
* __nfq_udp_compute_checksum_ipv4__.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_udp_compute_checksum_ipv4(struct udphdr *udph, struct iphdr *iph)
|
||||
{
|
||||
/* checksum field in header needs to be zero for calculation. */
|
||||
udph->check = 0;
|
||||
udph->check = nfq_checksum_tcpudp_ipv4(iph, IPPROTO_UDP);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_udp_compute_checksum_ipv6 - sets up the UDP checksum in a UDP/IPv6 packet
|
||||
* \param udph: pointer to the UDP header
|
||||
* \param ip6h: pointer to the IPv6 header
|
||||
* \note
|
||||
* nfq_udp_mangle_ipv6() invokes this function.
|
||||
* As long as developers always use __nfq_udp_mangle_ipv6__ when changing the
|
||||
* content of a UDP message, there is no need to call
|
||||
* __nfq_udp_compute_checksum_ipv6__.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_udp_compute_checksum_ipv6(struct udphdr *udph, struct ip6_hdr *ip6h)
|
||||
{
|
||||
/* checksum field in header needs to be zero for calculation. */
|
||||
udph->check = 0;
|
||||
udph->check = nfq_checksum_tcpudp_ipv6(ip6h, udph, IPPROTO_UDP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_udp_mangle_ipv4 - Mangle UDP/IPv4 packet buffer
|
||||
* \param pktb: Pointer to network packet buffer
|
||||
* \param match_offset: Offset from start of UDP data of content that you want
|
||||
* to mangle
|
||||
* \param match_len: Length of the existing content you want to mangle
|
||||
* \param rep_buffer: Pointer to data you want to use to replace current content
|
||||
* \param rep_len: Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv4 and UDP lengths and recalculates their
|
||||
* checksums for you.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_udp_mangle_ipv4(struct pkt_buff *pktb,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct udphdr *udph;
|
||||
|
||||
iph = (struct iphdr *)pktb->network_header;
|
||||
udph = (struct udphdr *)(pktb->network_header + iph->ihl*4);
|
||||
|
||||
udph->len = htons(ntohs(udph->len) + rep_len - match_len);
|
||||
|
||||
if (!nfq_ip_mangle(pktb, iph->ihl*4 + sizeof(struct udphdr),
|
||||
match_offset, match_len, rep_buffer, rep_len))
|
||||
return 0;
|
||||
|
||||
nfq_udp_compute_checksum_ipv4(udph, iph);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_udp_mangle_ipv6 - Mangle UDP/IPv6 packet buffer
|
||||
* \param pktb: Pointer to network packet buffer
|
||||
* \param match_offset: Offset from start of UDP data of content that you want
|
||||
* to mangle
|
||||
* \param match_len: Length of the existing content you want to mangle
|
||||
* \param rep_buffer: Pointer to data you want to use to replace current content
|
||||
* \param rep_len: Length of data you want to use to replace current content
|
||||
* \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
|
||||
* \note This function updates the IPv6 and UDP lengths and recalculates the UDP
|
||||
* checksum for you.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_udp_mangle_ipv6(struct pkt_buff *pktb,
|
||||
unsigned int match_offset, unsigned int match_len,
|
||||
const char *rep_buffer, unsigned int rep_len)
|
||||
{
|
||||
struct ip6_hdr *ip6h;
|
||||
struct udphdr *udph;
|
||||
|
||||
ip6h = (struct ip6_hdr *)pktb->network_header;
|
||||
udph = (struct udphdr *)(pktb->transport_header);
|
||||
if (!udph)
|
||||
return 0;
|
||||
|
||||
udph->len = htons(ntohs(udph->len) + rep_len - match_len);
|
||||
|
||||
if (!nfq_ip6_mangle(pktb,
|
||||
pktb->transport_header - pktb->network_header +
|
||||
sizeof(struct udphdr),
|
||||
match_offset, match_len, rep_buffer, rep_len))
|
||||
return 0;
|
||||
|
||||
nfq_udp_compute_checksum_ipv6(udph, ip6h);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_pkt_snprintf_udp_hdr - print udp header into one buffer in a humnan
|
||||
* readable way
|
||||
* \param buf: pointer to buffer that is used to print the object
|
||||
* \param size: size of the buffer (or remaining room in it).
|
||||
* \param udph: pointer to a valid udp header.
|
||||
* \returns The number of characters notionally written (excluding trailing NUL)
|
||||
* \sa __snprintf__(3)
|
||||
*
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_udp_snprintf(char *buf, size_t size, const struct udphdr *udph)
|
||||
{
|
||||
return snprintf(buf, size, "SPT=%u DPT=%u ",
|
||||
htons(udph->source), htons(udph->dest));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
38
ref/libnetfilter-queue/src/internal.h
Normal file
38
ref/libnetfilter-queue/src/internal.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H 1
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef HAVE_VISIBILITY_HIDDEN
|
||||
# define EXPORT_SYMBOL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define EXPORT_SYMBOL
|
||||
#endif
|
||||
|
||||
struct iphdr;
|
||||
struct ip6_hdr;
|
||||
|
||||
uint16_t nfq_checksum(uint32_t sum, uint16_t *buf, int size);
|
||||
uint16_t nfq_checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protonum);
|
||||
uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr,
|
||||
uint16_t protonum);
|
||||
|
||||
struct pkt_buff {
|
||||
uint8_t *mac_header;
|
||||
uint8_t *network_header;
|
||||
uint8_t *transport_header;
|
||||
|
||||
uint8_t *data;
|
||||
|
||||
uint32_t len;
|
||||
uint32_t data_len;
|
||||
|
||||
bool mangled;
|
||||
};
|
||||
|
||||
static inline uint8_t *pktb_tail(struct pkt_buff *pktb)
|
||||
{
|
||||
return pktb->data + pktb->len;
|
||||
}
|
||||
#endif
|
||||
1534
ref/libnetfilter-queue/src/libnetfilter_queue.c
Normal file
1534
ref/libnetfilter-queue/src/libnetfilter_queue.c
Normal file
File diff suppressed because it is too large
Load Diff
299
ref/libnetfilter-queue/src/nlmsg.c
Normal file
299
ref/libnetfilter-queue/src/nlmsg.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <arpa/inet.h>
|
||||
#include <time.h>
|
||||
#include <endian.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libmnl/libmnl.h>
|
||||
|
||||
#ifndef __aligned_be64
|
||||
#define __aligned_be64 __be64 __attribute__((aligned(8)))
|
||||
#define __aligned_le64 __le64 __attribute__((aligned(8)))
|
||||
#endif
|
||||
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* \defgroup nfq_verd Verdict helpers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_verdict_put - Put a verdict into a Netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param id ID assigned to packet by netfilter
|
||||
* \param verdict verdict to return to netfilter (see \b Verdicts below)
|
||||
* \par Verdicts
|
||||
* __NF_DROP__ Drop the packet. This is final.
|
||||
* \n
|
||||
* __NF_ACCEPT__ Accept the packet. Processing of the current base chain
|
||||
* and any called chains terminates,
|
||||
* but the packet may still be processed by subsequently invoked base chains.
|
||||
* \n
|
||||
* __NF_STOP__ Like __NF_ACCEPT__, but skip any further base chains using the
|
||||
* current hook.
|
||||
* \n
|
||||
* __NF_REPEAT__ Like __NF_ACCEPT__, but re-queue this packet to the
|
||||
* current base chain. One way to prevent a re-queueing loop is to
|
||||
* also set a packet mark using nfq_nlmsg_verdict_put_mark() and have the
|
||||
* program test for this mark in \c attr[NFQA_MARK]; or have the nefilter rules
|
||||
* do this test.
|
||||
* \n
|
||||
* __NF_QUEUE_NR__(*new_queue*) Like __NF_ACCEPT__, but queue this packet to
|
||||
* queue number *new_queue*. As with the command-line \b queue \b num verdict,
|
||||
* if no process is listening to that queue then the packet is discarded; but
|
||||
* again like with the command-line, one may OR in a flag to bypass *new_queue*
|
||||
* if there is no listener, as in this snippet:
|
||||
* \verbatim
|
||||
nfq_nlmsg_verdict_put(nlh, id, NF_QUEUE_NR(new_queue) |
|
||||
NF_VERDICT_FLAG_QUEUE_BYPASS);
|
||||
\endverbatim
|
||||
*
|
||||
* See examples/nf-queue.c, line
|
||||
* <a class="el" href="nf-queue_8c_source.html#l00046">46</a>
|
||||
* for an example of how to use this function in context.
|
||||
* The calling sequence is \b main --> \b mnl_cb_run --> \b queue_cb -->
|
||||
* \b nfq_send_verdict --> \b nfq_nlmsg_verdict_put
|
||||
* (\b cb being short for \b callback).
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
|
||||
{
|
||||
struct nfqnl_msg_verdict_hdr vh = {
|
||||
.verdict = htonl(verdict),
|
||||
.id = htonl(id),
|
||||
};
|
||||
mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_verdict_put_mark - Put a packet mark into a netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param mark Value of mark to put
|
||||
*
|
||||
* The mark becomes part of the packet's metadata, and may be tested by the *nft
|
||||
* primary expression* **meta mark**
|
||||
* \sa __nft__(1)
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark)
|
||||
{
|
||||
mnl_attr_put_u32(nlh, NFQA_MARK, htonl(mark));
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL
|
||||
/**
|
||||
* nfq_nlmsg_verdict_put_pkt - Put replacement packet content into a netlink
|
||||
* message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param pkt Pointer to start of modified IP datagram
|
||||
* \param plen Length of modified IP datagram
|
||||
*
|
||||
* There is only ever a need to return packet content if it has been modified.
|
||||
* Usually one of the nfq_*_mangle_* functions does the modifying.
|
||||
*
|
||||
* This code snippet uses nfq_udp_mangle_ipv4. See nf-queue.c for
|
||||
* context:
|
||||
* \verbatim
|
||||
// main calls queue_cb (line 64) to process an enqueued packet:
|
||||
// Extra variables
|
||||
uint8_t *payload, *rep_data;
|
||||
unsigned int match_offset, match_len, rep_len;
|
||||
|
||||
// The next line was commented-out (with payload void*)
|
||||
payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
|
||||
// Copy data to a packet buffer (allow 255 bytes for mangling).
|
||||
pktb = pktb_alloc(AF_INET, payload, plen, 255);
|
||||
// (decide that this packet needs mangling)
|
||||
nfq_udp_mangle_ipv4(pktb, match_offset, match_len, rep_data, rep_len);
|
||||
// nfq_udp_mangle_ipv4 updates packet length, no need to track locally
|
||||
|
||||
// Eventually nfq_send_verdict (line 39) gets called
|
||||
// The received packet may or may not have been modified.
|
||||
// Add this code before nfq_nlmsg_verdict_put call:
|
||||
if (pktb_mangled(pktb))
|
||||
nfq_nlmsg_verdict_put_pkt(nlh, pktb_data(pktb), pktb_len(pktb));
|
||||
\endverbatim
|
||||
*/
|
||||
void nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt,
|
||||
uint32_t plen)
|
||||
{
|
||||
mnl_attr_put(nlh, NFQA_PAYLOAD, plen, pkt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup nfq_cfg Config helpers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_cfg_put_cmd Add netlink config command to netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param pf Packet family (e.g. AF_INET)
|
||||
* \param cmd nfqueue nfnetlink command.
|
||||
*
|
||||
* Possible commands are:
|
||||
*
|
||||
* - NFQNL_CFG_CMD_NONE: Do nothing. It can be useful to know if the queue
|
||||
* subsystem is working.
|
||||
* - NFQNL_CFG_CMD_BIND: Binds the program to a specific queue.
|
||||
* - NFQNL_CFG_CMD_UNBIND: Unbinds the program to a specifiq queue.
|
||||
*
|
||||
* Obsolete commands:
|
||||
* - NFQNL_CFG_CMD_PF_BIND: Binds to process packets belonging to the given
|
||||
* protocol family (ie. PF_INET, PF_INET6, etc).
|
||||
* - NFQNL_CFG_CMD_PF_UNBIND: Unbinds from processing packets belonging to the
|
||||
* given protocol family. Both commands are ignored by Linux kernel 3.8 and
|
||||
* later versions.
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
|
||||
{
|
||||
struct nfqnl_msg_config_cmd command = {
|
||||
.command = cmd,
|
||||
.pf = htons(pf),
|
||||
};
|
||||
mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(command), &command);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_cfg_put_params Add parameter to netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param mode one of NFQNL_COPY_NONE, NFQNL_COPY_META or NFQNL_COPY_PACKET
|
||||
* \param range value of parameter
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)
|
||||
{
|
||||
struct nfqnl_msg_config_params params = {
|
||||
.copy_range = htonl(range),
|
||||
.copy_mode = mode,
|
||||
};
|
||||
mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), ¶ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_cfg_put_qmaxlen Add queue maximum length to netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param queue_maxlen Maximum queue length
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t queue_maxlen)
|
||||
{
|
||||
mnl_attr_put_u32(nlh, NFQA_CFG_QUEUE_MAXLEN, htonl(queue_maxlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup nlmsg Netlink message helper functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int nfq_pkt_parse_attr_cb(const struct nlattr *attr, void *data)
|
||||
{
|
||||
const struct nlattr **tb = data;
|
||||
int type = mnl_attr_get_type(attr);
|
||||
|
||||
/* skip unsupported attribute in user-space */
|
||||
if (mnl_attr_type_valid(attr, NFQA_MAX) < 0)
|
||||
return MNL_CB_OK;
|
||||
|
||||
switch(type) {
|
||||
case NFQA_MARK:
|
||||
case NFQA_IFINDEX_INDEV:
|
||||
case NFQA_IFINDEX_OUTDEV:
|
||||
case NFQA_IFINDEX_PHYSINDEV:
|
||||
case NFQA_IFINDEX_PHYSOUTDEV:
|
||||
case NFQA_CAP_LEN:
|
||||
case NFQA_SKB_INFO:
|
||||
case NFQA_SECCTX:
|
||||
case NFQA_UID:
|
||||
case NFQA_GID:
|
||||
case NFQA_CT_INFO:
|
||||
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
|
||||
return MNL_CB_ERROR;
|
||||
break;
|
||||
case NFQA_TIMESTAMP:
|
||||
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
|
||||
sizeof(struct nfqnl_msg_packet_timestamp)) < 0) {
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
break;
|
||||
case NFQA_HWADDR:
|
||||
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
|
||||
sizeof(struct nfqnl_msg_packet_hw)) < 0) {
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
break;
|
||||
case NFQA_PACKET_HDR:
|
||||
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
|
||||
sizeof(struct nfqnl_msg_packet_hdr)) < 0) {
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
break;
|
||||
case NFQA_PAYLOAD:
|
||||
case NFQA_CT:
|
||||
case NFQA_EXP:
|
||||
break;
|
||||
}
|
||||
tb[type] = attr;
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_parse - set packet attributes from netlink message
|
||||
* \param nlh Pointer to netlink message
|
||||
* \param attr Pointer to array of attributes to set
|
||||
* \returns MNL_CB_OK on success or MNL_CB_ERROR if any error occurs
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
|
||||
{
|
||||
return mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
|
||||
nfq_pkt_parse_attr_cb, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfq_nlmsg_put - Convert memory buffer into a Netlink buffer
|
||||
* \param *buf Pointer to memory buffer
|
||||
* \param type Either NFQNL_MSG_CONFIG or NFQNL_MSG_VERDICT
|
||||
* \param queue_num Queue number
|
||||
* \returns Pointer to netlink message
|
||||
*/
|
||||
EXPORT_SYMBOL
|
||||
struct nlmsghdr *nfq_nlmsg_put(char *buf, int type, uint32_t queue_num)
|
||||
{
|
||||
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
|
||||
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
|
||||
nlh->nlmsg_flags = NLM_F_REQUEST;
|
||||
|
||||
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
|
||||
nfg->nfgen_family = AF_UNSPEC;
|
||||
nfg->version = NFNETLINK_V0;
|
||||
nfg->res_id = htons(queue_num);
|
||||
|
||||
return nlh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
1
ref/libnetfilter-queue/utils/.gitignore
vendored
Normal file
1
ref/libnetfilter-queue/utils/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/nfqnl_test
|
||||
9
ref/libnetfilter-queue/utils/Makefile.am
Normal file
9
ref/libnetfilter-queue/utils/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
include ${top_srcdir}/Make_global.am
|
||||
|
||||
check_PROGRAMS = nfqnl_test
|
||||
|
||||
nfqnl_test_SOURCES = nfqnl_test.c
|
||||
nfqnl_test_LDADD = ../src/libnetfilter_queue.la
|
||||
nfqnl_test_LDFLAGS = -dynamic
|
||||
|
||||
|
||||
186
ref/libnetfilter-queue/utils/nfqnl_test.c
Normal file
186
ref/libnetfilter-queue/utils/nfqnl_test.c
Normal file
@ -0,0 +1,186 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netfilter.h> /* for NF_ACCEPT */
|
||||
#include <errno.h>
|
||||
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
/* returns packet id */
|
||||
static uint32_t print_pkt (struct nfq_data *tb)
|
||||
{
|
||||
int id = 0;
|
||||
struct nfqnl_msg_packet_hdr *ph;
|
||||
struct nfqnl_msg_packet_hw *hwph;
|
||||
uint32_t mark, ifi, uid, gid;
|
||||
int ret;
|
||||
unsigned char *data, *secdata;
|
||||
|
||||
ph = nfq_get_msg_packet_hdr(tb);
|
||||
if (ph) {
|
||||
id = ntohl(ph->packet_id);
|
||||
printf("hw_protocol=0x%04x hook=%u id=%u ",
|
||||
ntohs(ph->hw_protocol), ph->hook, id);
|
||||
}
|
||||
|
||||
hwph = nfq_get_packet_hw(tb);
|
||||
if (hwph) {
|
||||
int i, hlen = ntohs(hwph->hw_addrlen);
|
||||
|
||||
printf("hw_src_addr=");
|
||||
for (i = 0; i < hlen-1; i++)
|
||||
printf("%02x:", hwph->hw_addr[i]);
|
||||
printf("%02x ", hwph->hw_addr[hlen-1]);
|
||||
}
|
||||
|
||||
mark = nfq_get_nfmark(tb);
|
||||
if (mark)
|
||||
printf("mark=%u ", mark);
|
||||
|
||||
ifi = nfq_get_indev(tb);
|
||||
if (ifi)
|
||||
printf("indev=%u ", ifi);
|
||||
|
||||
ifi = nfq_get_outdev(tb);
|
||||
if (ifi)
|
||||
printf("outdev=%u ", ifi);
|
||||
ifi = nfq_get_physindev(tb);
|
||||
if (ifi)
|
||||
printf("physindev=%u ", ifi);
|
||||
|
||||
ifi = nfq_get_physoutdev(tb);
|
||||
if (ifi)
|
||||
printf("physoutdev=%u ", ifi);
|
||||
|
||||
if (nfq_get_uid(tb, &uid))
|
||||
printf("uid=%u ", uid);
|
||||
|
||||
if (nfq_get_gid(tb, &gid))
|
||||
printf("gid=%u ", gid);
|
||||
|
||||
ret = nfq_get_secctx(tb, &secdata);
|
||||
if (ret > 0)
|
||||
printf("secctx=\"%.*s\" ", ret, secdata);
|
||||
|
||||
ret = nfq_get_payload(tb, &data);
|
||||
if (ret >= 0)
|
||||
printf("payload_len=%d ", ret);
|
||||
|
||||
fputc('\n', stdout);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
|
||||
struct nfq_data *nfa, void *data)
|
||||
{
|
||||
uint32_t id = print_pkt(nfa);
|
||||
printf("entering callback\n");
|
||||
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct nfq_handle *h;
|
||||
struct nfq_q_handle *qh;
|
||||
int fd;
|
||||
int rv;
|
||||
uint32_t queue = 0;
|
||||
char buf[4096] __attribute__ ((aligned));
|
||||
|
||||
if (argc == 2) {
|
||||
queue = atoi(argv[1]);
|
||||
if (queue > 65535) {
|
||||
fprintf(stderr, "Usage: %s [<0-65535>]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
printf("opening library handle\n");
|
||||
h = nfq_open();
|
||||
if (!h) {
|
||||
fprintf(stderr, "error during nfq_open()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
|
||||
if (nfq_unbind_pf(h, AF_INET) < 0) {
|
||||
fprintf(stderr, "error during nfq_unbind_pf()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
|
||||
if (nfq_bind_pf(h, AF_INET) < 0) {
|
||||
fprintf(stderr, "error during nfq_bind_pf()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("binding this socket to queue '%d'\n", queue);
|
||||
qh = nfq_create_queue(h, queue, &cb, NULL);
|
||||
if (!qh) {
|
||||
fprintf(stderr, "error during nfq_create_queue()\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("setting copy_packet mode\n");
|
||||
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
|
||||
fprintf(stderr, "can't set packet_copy mode\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("setting flags to request UID and GID\n");
|
||||
if (nfq_set_queue_flags(qh, NFQA_CFG_F_UID_GID, NFQA_CFG_F_UID_GID)) {
|
||||
fprintf(stderr, "This kernel version does not allow to "
|
||||
"retrieve process UID/GID.\n");
|
||||
}
|
||||
|
||||
printf("setting flags to request security context\n");
|
||||
if (nfq_set_queue_flags(qh, NFQA_CFG_F_SECCTX, NFQA_CFG_F_SECCTX)) {
|
||||
fprintf(stderr, "This kernel version does not allow to "
|
||||
"retrieve security context.\n");
|
||||
}
|
||||
|
||||
printf("Waiting for packets...\n");
|
||||
|
||||
fd = nfq_fd(h);
|
||||
|
||||
for (;;) {
|
||||
if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
|
||||
printf("pkt received\n");
|
||||
nfq_handle_packet(h, buf, rv);
|
||||
continue;
|
||||
}
|
||||
/* if your application is too slow to digest the packets that
|
||||
* are sent from kernel-space, the socket buffer that we use
|
||||
* to enqueue packets may fill up returning ENOBUFS. Depending
|
||||
* on your application, this error may be ignored. Please, see
|
||||
* the doxygen documentation of this library on how to improve
|
||||
* this situation.
|
||||
*/
|
||||
if (rv < 0 && errno == ENOBUFS) {
|
||||
printf("losing packets!\n");
|
||||
continue;
|
||||
}
|
||||
perror("recv failed");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("unbinding from queue 0\n");
|
||||
nfq_destroy_queue(qh);
|
||||
|
||||
#ifdef INSANE
|
||||
/* normally, applications SHOULD NOT issue this command, since
|
||||
* it detaches other programs/sockets from AF_INET, too ! */
|
||||
printf("unbinding from AF_INET\n");
|
||||
nfq_unbind_pf(h, AF_INET);
|
||||
#endif
|
||||
|
||||
printf("closing library handle\n");
|
||||
nfq_close(h);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
19
src/ua2f.c
19
src/ua2f.c
@ -45,7 +45,7 @@ static int queue_cb(const struct nlmsghdr *nlh, void *customdata)
|
||||
plen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
|
||||
/* void *payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]); */
|
||||
|
||||
skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
|
||||
// skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
|
||||
|
||||
if (attr[NFQA_CAP_LEN]) {
|
||||
uint32_t orig_len = ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN]));
|
||||
@ -53,11 +53,14 @@ static int queue_cb(const struct nlmsghdr *nlh, void *customdata)
|
||||
printf("truncated ");
|
||||
}
|
||||
|
||||
if (skbinfo & NFQA_SKB_GSO) //NFQA_SKB_GSO为2,取倒数第二位
|
||||
printf("GSO ");
|
||||
// if (skbinfo & NFQA_SKB_GSO) //NFQA_SKB_GSO为2,取倒数第二位
|
||||
// printf("GSO ");
|
||||
|
||||
id = ntohl(ph->packet_id);
|
||||
printf("packet received (id=%u hw=0x%04x hook=%u, payload len %u",
|
||||
if (ph->hw_protocol==IPPROTO_TCP){
|
||||
printf("get a TCP packet\n");
|
||||
}
|
||||
printf("packet received (id=%u hw=%u hook=%u, payload len %u",
|
||||
id, ntohs(ph->hw_protocol), ph->hook, plen);
|
||||
|
||||
/*
|
||||
@ -67,9 +70,9 @@ static int queue_cb(const struct nlmsghdr *nlh, void *customdata)
|
||||
* If these packets are later forwarded/sent out, the checksums will
|
||||
* be corrected by kernel/hardware.
|
||||
*/
|
||||
if (skbinfo & NFQA_SKB_CSUMNOTREADY) //NFQA_SKB_GSO为2,取倒数第二位
|
||||
printf(", checksum not ready");
|
||||
puts(")");
|
||||
// if (skbinfo & NFQA_SKB_CSUMNOTREADY) //NFQA_SKB_GSO为2,取倒数第二位
|
||||
// printf(", checksum not ready");
|
||||
// puts(")");
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
@ -81,7 +84,7 @@ int main(int argc, char *argv[])
|
||||
size_t sizeof_buf = 0xffff + (MNL_SOCKET_BUFFER_SIZE/2);
|
||||
struct nlmsghdr *nlh;
|
||||
int ret;
|
||||
unsigned int portid, queue_num;
|
||||
unsigned int portid;
|
||||
|
||||
|
||||
nl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user