1
0
Fork 0

Adding upstream version 1.1.0+debian.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-09 08:30:48 +01:00
parent f890831723
commit 8d1b12293d
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
261 changed files with 31196 additions and 0 deletions

6
.clang-format Normal file
View file

@ -0,0 +1,6 @@
BasedOnStyle: webkit
IndentWidth: 4
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignOperands: true
SortIncludes: false

23
.copr/Makefile Normal file
View file

@ -0,0 +1,23 @@
top=..
all: srpm
prereq: $(top)/rpmbuild
rpm -q git rpm-build >/dev/null || dnf -y install git rpm-build
update-dist-tools: $(top)/dist-tools
( cd "$(top)/dist-tools" && git pull )
$(top)/dist-tools:
git clone https://github.com/jelu/dist-tools.git "$(top)/dist-tools"
$(top)/rpmbuild:
mkdir -p "$(top)"/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
srpm: prereq update-dist-tools
test -f .gitmodules && git submodule update --init || true
echo "$(spec)" | grep -q "develop.spec" && auto_build_number=`date --utc +%s` message="Auto build `date --utc --iso-8601=seconds`" "$(top)/dist-tools/spec-new-changelog-entry" || true
overwrite=yes nosign=yes "$(top)/dist-tools/create-source-packages" rpm
cp ../*.orig.tar.gz "$(top)/rpmbuild/SOURCES/"
echo "$(spec)" | grep -q "develop.spec" && rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist rpm/*.spec || rpmbuild -bs --define "%_topdir $(top)/rpmbuild" --undefine=dist "$(spec)"
cp "$(top)"/rpmbuild/SRPMS/*.src.rpm "$(outdir)"

1
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1 @@
custom: https://www.dns-oarc.net/donate

100
.gitignore vendored Normal file
View file

@ -0,0 +1,100 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Automake
Makefile.in
aclocal.m4
ar-lib
autom4te.cache
compile
config.guess
config.sub
configure
depcomp
install-sh
ltmain.sh
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
missing
config.h.in
config.h.in~
test-driver
# Configure
Makefile
config.log
config.status
libtool
.deps
src/config.h
src/stamp-h1
build
.dirstamp
# Project specific files
*.luao
*.luaho
src/dnsjit
src/dnsjit.1
src/dnsjit.*.3in
src/dnsjit.*.3
src/core/compat.hh
src/core/log_errstr.c
src/test/test-suite.log
src/test/test*.sh.log
src/test/test*.sh.trs
src/test/*.dist
src/test/*-dist

21
.lgtm.yml Normal file
View file

@ -0,0 +1,21 @@
extraction:
cpp:
prepare:
packages:
- build-essential
- automake
- autoconf
- libtool
- pkg-config
- libluajit-5.1-dev
- libpcap-dev
- luajit
- liblmdb-dev
- libck-dev
- libgnutls28-dev
- libuv1-dev
- libnghttp2-dev
configure:
command:
- ./autogen.sh
- ./configure

29
.travis.yml Normal file
View file

@ -0,0 +1,29 @@
dist: xenial
addons:
apt:
update: true
packages:
- libluajit-5.1-dev
- libpcap-dev
- luajit
- liblmdb-dev
- libck-dev
- libgnutls28-dev
- libuv1-dev
- libnghttp2-dev
language: c
compiler:
- clang
- gcc
install: ./autogen.sh
script:
- ./configure --enable-warn-all
- make dist
- tar zxvf *.tar.gz
- cd dnsjit-[0-9]*
- mkdir build
- cd build
- ../configure --enable-warn-all
- make
- make test
- cat src/test/test*.sh.log

106
CHANGES Normal file
View file

@ -0,0 +1,106 @@
2021-02-03 Jerry Lundström
Release 1.1.0
This releases adds a new module for handling Base64 URLs and new calls
for error handling and opening PCAPs using file descriptors, along with
a bug fix in `lib.getopt` and other changes.
The `dnssim` module has also gotten its own version and changelog, this
is to prepare it for being moved outside of dnsjit's repository in the
future.
New modules, calls, features:
- New `lib.base64url`: Utility library to convert data to base64url format
- `core.log`: New call `Log.errstr()`: Convert error number to its text representation
- `input.fpcap`: New call `Fpcap.openfp()`: Open a PCAP file for processing using a file descriptor, for example `io.stdin`
- `output.dnssim`: Support for DNS-over-HTTPS
Bug fixes:
- `lib.getopt`: Fix bug where `-` and `--` could not be used as arguments to options
Other changes:
- Fix typo in configure help text
- Add coverage
- `filter.ipsplit`: Extend PRNG modulus to 2^31, new implementation is the same as glibc's `rand()`
- `lib.ip`: Fix typo in documentation
- `output.dnssim`:
- This module now has it's own changelog
- Updated to v20210129
- Depend on libhttp2 for dnssim DNS-over-HTTPS capabilities
- `output.pcap`: Log libpcap error when failing to open
- SUSE packages now depend on moonjit because of lack of LuaJIT support
d001ccb m4
4b63bce output/dnssim: add changelog
7355810 output/dnssim: add version checks
95fa6a9 input pcap/fpcap, getopt
99c3d9f test/test_ipsplit: update to use new PRNG
3235b09 filter/ipsplit: extend PRNG modulus to 2^31
8ff81a0 fixup! input.fpcap: filename "-" reads from stdin
63cf0a4 output/dnssim: fix regression in DoH GET
367d0b8 input.pcap: document stdin feature of open_offline()
8d94504 input.fpcap: filename "-" reads from stdin
617058e getopt: accept singleton - also as option value
7d7f17c output/dnssim: unify failed to bind error messages
bdf1517 output/dnssim: add IPv4 support
15a21da Sonarcloud
ceeea1d SUSE
1fc3c82 PR179
2f5d38f output/dnssim: allow user-set instance log name
b036c68 Info
0af1ffb Travis, configure
49bdc08 output/dnssim: implement udp(tcp_fallback) method
b4f9cf9 man: update gitlab.labs.nic.cz to gitlab.nic.cz
45b977d output/dnssim: update man page
4184090 output/dnssim: https2 - fix connection closure issues
342f33e output/dnssim: https2 - omit closing connection inside callback
67a76d5 output/dnssim: handle all states when closing connection
41f04d8 output/dnssim: document importance of conn state enum ordering
795ab6f output/dnssim: tls - fix handling of CONGESTED connections
8792b32 output/dnssim: match QUESTION section of received responses
3a88f5b Coverage
4f611c8 dnssim
6e35d5b Compile
63faa44 README, format code, man-page
925f85e lib: add missing man reference
9239087 output/dnssim: fix man formatting
bd7bee5 fix lua log levels
4083efd output/dnssim: fix doc typo
24c22b8 lib/base64url: add lua bindings
69be2a1 core/log: add errstr() utility function
0c14d74 output/dnssim: improve https2() documentation and behaviour
f74e19c output/pcap: log errors when opening output PCAP
6fe699a output/dnssim: cleanup and nitpicks
96db8a9 output/https2: handle max_concurrent_streams similar to nghttp2
15ea609 output/dnssim: https2 - ensure uri authority is always set
fad3ed6 output/dnssim: https2 - fix some TODOs
0bee6d8 output/dnssim: https2 - lua documentation
e83e010 output/dnssim: https2 - implement GET method
b553e0f output/dnssim: https2 - configure method
a431a0d contrib: add base64url functions
c753097 output/dnssim: https2 - set default concurrent stream limit
d49f275 output/dnssim: https2 - track number of open streams
2f7217f output/dnssim: https2 - improve data send edge cases
c0abebc output/dnssim: https2 - return correct error code on send failure
5b1f6c3 output/dnssim: conn - avoid assert when tearing down failed connections
5c42266 output/dnssim: exit when file descriptors run out
1ab2ab6 output/dnssim: https2 - additional asserts to detect invalid data
4424eb3 output/dnssim: https2 - check response code
303f2cd output/dnssim: https2 - improve QID mismatch debug msg
86e3761 output/dnssim: https2 - bugfixes
4a52f47 output/dnssim: https2 - use more consistent code style for pointers
c8d853e output/dnssim: conn - fix potential memory leak
3e6038b output/dnssim: https2 - enable zero-ing out msgid
712634c output/dnssim: https2 - properly match dnsmsg to query from http request
5abe943 output/dnssim: https2 - free memory on teardown
39a9e9e output/dnssim: https2 - initial implementation
058aee2 output/dnssim: https2 - initialize and setup session
85eb4a3 output/dnssim: https2 - add libnghttp2 dependency
6712bd6 output/dnssim: https2 - add skeleton
2020-07-23 Jerry Lundström
Release 1.0.0
First release of dnsjit.

674
LICENSE Normal file
View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. 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
them 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 prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. 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.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey 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;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU 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 that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
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.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
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.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

31
Makefile.am Normal file
View file

@ -0,0 +1,31 @@
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
ACLOCAL_AMFLAGS = -I m4
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in \
$(srcdir)/src/config.h.in~ \
$(srcdir)/configure
SUBDIRS = src examples
dist_doc_DATA = CHANGES README.md LICENSE
EXTRA_DIST = m4
test: check

153
README.md Normal file
View file

@ -0,0 +1,153 @@
# Engine for capturing, parsing and replaying DNS
[![Build Status](https://travis-ci.com/DNS-OARC/dnsjit.svg?branch=develop)](https://travis-ci.com/DNS-OARC/dnsjit) [![Total alerts](https://img.shields.io/lgtm/alerts/g/DNS-OARC/dnsjit.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/DNS-OARC/dnsjit/alerts/) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adnsjit&metric=bugs)](https://sonarcloud.io/dashboard?id=dns-oarc%3Adnsjit) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=dns-oarc%3Adnsjit&metric=security_rating)](https://sonarcloud.io/dashboard?id=dns-oarc%3Adnsjit)
**dnsjit** is a combination of parts taken from **dsc**, **dnscap**, **drool**,
and put together around Lua to create a script-based engine for easy
capturing, parsing and statistics gathering of DNS messages while also
providing facilities for replaying DNS traffic.
One of the core functionality that **dnsjit** brings is to tie together C
and Lua modules through a receiver/producer interface.
This allows creation of custom chains of functionality to meet various
requirements.
Another core functionality is the ability to parse and process DNS messages
even if the messages are non-compliant with the DNS standards.
The following Lua module categories exists:
- `dnsjit.core`: Core modules for handling things like logging, DNS messages and receiver/receive functionality.
- `dnsjit.lib`: Various Lua libraries or C library bindings.
- `dnsjit.input`: Input modules used to read DNS messages in various ways.
- `dnsjit.filter`: Filter modules to process or manipulate DNS messages.
- `dnsjit.output`: Output modules used to display DNS message, export to various formats or replay them against other targets.
See each category's man-page for more information.
More information may be found here:
- https://www.dns-oarc.net/tools/dnsjit
Issues should be reported here:
- https://github.com/DNS-OARC/dnsjit/issues
General support and discussion:
- Mattermost: https://chat.dns-oarc.net/community/channels/oarc-software
## Packages
https://dev.dns-oarc.net/packages
Packages for Debian, Ubuntu, EPEL, SLE, openSUSE can be found in the
PRE-RELEASE channel. Some distributions are limited to certain
architectures because of LuaJIT.
## Dependencies
- [libluajit](http://luajit.org/) 2.0+ (or compatible alternatives)
- [libpcap](http://www.tcpdump.org/)
- [liblmdb](https://github.com/LMDB/lmdb)
- [libck](https://github.com/concurrencykit/ck)
- [libgnutls](https://www.gnutls.org/)
- [libuv](http://libuv.org/)
- [libnghttp2](https://www.nghttp2.org/)
- [luajit](http://luajit.org/) (for building)
- automake/autoconf/libtool/pkg-config (for building)
Debian/Ubuntu: `apt-get install libluajit-5.1-dev libpcap-dev luajit liblmdb-dev libck-dev libgnutls28-dev libuv1-dev libnghttp2-dev`
CentOS: `yum install luajit-devel libpcap-devel lmdb-devel ck-devel gnutls-devel libuv-devel libnghttp2-devel`
FreeBSD: `pkg install luajit libpcap lmdb gnutls concurrencykit libuv libnghttp2`
OpenBSD: `pkg_add luajit gnutls libuv nghttp2` + manual install of libpcap, liblmdb and libck
On some version of SUSE Linux Enterprise moonjit is used as an compatible
alternative to luajit.
## Build
```shell
git clone https://github.com/DNS-OARC/dnsjit
cd dnsjit
sh autogen.sh
./configure
make
```
## Documentation
Most documentation exists in man-pages and you do not have to install to
access them, after building you can do:
```shell
man src/dnsjit.1
man src/dnsjit.core.3
man src/dnsjit.lib.3
man src/dnsjit.input.3
man src/dnsjit.filter.3
man src/dnsjit.output.3
```
## Usage
Run a Lua script:
```shell
dnsjit file.lua ...
```
Shebang-style:
```lua
#!/usr/bin/env dnsjit
...
```
## Example
Following example display the DNS ID found in queries.
```lua
require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
input:open_offline(arg[2])
layer:producer(input)
local producer, ctx = layer:produce()
while true do
local object = producer(ctx)
if object == nil then break end
if object:type() == "payload" then
dns.obj_prev = object
if dns:parse_header() == 0 then
print(dns.id)
end
end
end
```
See more examples in the [examples](https://github.com/DNS-OARC/dnsjit/tree/develop/examples) directory.
## Copyright
Copyright (c) 2018-2021, OARC, Inc.
All rights reserved.
```
This file is part of dnsjit.
dnsjit is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
```

20
autogen.sh Executable file
View file

@ -0,0 +1,20 @@
#!/bin/sh -e
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
autoreconf --force --install --no-recursive --include=m4

131
configure.ac Normal file
View file

@ -0,0 +1,131 @@
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.64)
AC_INIT([dnsjit], [1.1.0], [admin@dns-oarc.net], [dnsjit], [https://github.com/DNS-OARC/dnsjit/issues])
AC_DEFINE([PACKAGE_MAJOR_VERSION], [1], [Define to the major version of this package.])
AC_DEFINE([PACKAGE_MINOR_VERSION], [1], [Define to the minor version of this package.])
AC_DEFINE([PACKAGE_PATCH_VERSION], [0], [Define to the patch version of this package.])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([src/dnsjit.c])
AC_CONFIG_HEADER([src/config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_CANONICAL_HOST
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LT_INIT([disable-static])
# Check --enable-warn-all
AC_ARG_ENABLE([warn-all], [AS_HELP_STRING([--enable-warn-all], [Enable all compiler warnings])], [AX_CFLAGS_WARN_ALL()])
# Check --with-extra-cflags
AC_ARG_WITH([extra-cflags], [AS_HELP_STRING([--with-extra-cflags=CFLAGS], [Add extra CFLAGS])], [
AC_MSG_NOTICE([appending extra CFLAGS... $withval])
AS_VAR_APPEND(CFLAGS, [" $withval"])
])
# Check --with-extra-ldflags
AC_ARG_WITH([extra-ldflags], [AS_HELP_STRING([--with-extra-ldflags=LDFLAGS], [Add extra LDFLAGS])], [
AC_MSG_NOTICE([appending extra LDFLAGS... $withval])
AS_VAR_APPEND(LDFLAGS, [" $withval"])
])
# Check --enable-gcov
AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [Enable coverage testing])], [
coverage_cflags="--coverage" # ld fails with: -g -O0 -fno-inline -fno-inline-small-functions -fno-default-inline
AC_MSG_NOTICE([enabling coverage testing... $coverage_cflags])
AS_VAR_APPEND(CFLAGS, [" $coverage_cflags"])
])
AM_CONDITIONAL([ENABLE_GCOV], [test "x$enable_gcov" != "xno"])
AM_EXTRA_RECURSIVE_TARGETS([gcov])
# Checks for support.
AC_ARG_ENABLE([cpuext], [AS_HELP_STRING([--enable-cpuext], [check for and enable all available CPU extensions])], [
case "${enableval}" in
yes) AX_EXT ;;
*) ;;
esac])
AC_HEADER_TIME
AX_PTHREAD
AC_CHECK_LIB([pcap], [pcap_open_live], [], [AC_MSG_ERROR([libpcap not found])])
AC_CHECK_HEADER([pcap/pcap.h], [], [AC_MSG_ERROR([libpcap header not found])])
AC_CHECK_HEADERS([endian.h sys/endian.h machine/endian.h sys/time.h byteswap.h])
AC_CHECK_FUNCS([pcap_create pcap_set_tstamp_precision pcap_set_immediate_mode])
AC_CHECK_FUNCS([pcap_set_tstamp_type pcap_setdirection sched_yield])
AC_CHECK_FUNCS([pcap_open_offline_with_tstamp_precision pcap_activate])
AC_CHECK_TYPES([pcap_direction_t], [], [], [[#include <pcap/pcap.h>]])
AC_CHECK_HEADERS([net/ethernet.h])
AC_CHECK_HEADERS([net/ethertypes.h])
AC_SEARCH_LIBS([clock_gettime],[rt])
AC_CHECK_FUNCS([clock_nanosleep nanosleep])
PKG_CHECK_MODULES([luajit], [luajit >= 2],, [AC_MSG_ERROR([luajit v2+ not found])])
AC_PATH_PROGS([LUAJIT], [luajit luajit51])
if test "x$ac_cv_path_LUAJIT" = "x"; then
AC_MSG_ERROR([luajit not found])
fi
AC_CHECK_HEADERS([lmdb.h])
AC_CHECK_LIB([lmdb], [mdb_env_create])
PKG_CHECK_MODULES([libuv], [libuv])
PKG_CHECK_MODULES([libnghttp2], [libnghttp2])
PKG_CHECK_MODULES([ck], [ck >= 0], [
AS_VAR_APPEND([CFLAGS], [" $ck_CFLAGS"])
AS_VAR_APPEND([LIBS], [" $ck_LIBS"])
], [
AC_CHECK_HEADERS([ck_ring.h ck_pr.h],, [AC_MSG_ERROR([libck headers not found])])
AC_CHECK_LIB([ck], [ck_array_init],, [AC_MSG_ERROR([libck not found])])
])
AC_CHECK_LIB([gnutls], [gnutls_init],, [AC_MSG_ERROR([libgnutls not found])])
# Checks for sizes
AC_CHECK_SIZEOF([void*])
AC_CHECK_SIZEOF([pthread_t],,[#include <pthread.h>])
AC_CHECK_SIZEOF([pthread_mutex_t],,[#include <pthread.h>])
AC_CHECK_SIZEOF([pthread_cond_t],,[#include <pthread.h>])
AC_CHECK_SIZEOF([struct sockaddr_storage],,[#include <sys/types.h>
#include <sys/socket.h>])
AC_CHECK_SIZEOF([ck_ring_t],,[#if defined(__GNUC__) || defined(__SUNPRO_C)
#include "gcc/ck_cc.h"
#ifdef CK_CC_RESTRICT
#undef CK_CC_RESTRICT
#define CK_CC_RESTRICT __restrict__
#endif
#endif
#include <ck_ring.h>])
AC_CHECK_SIZEOF([ck_ring_buffer_t],,[#if defined(__GNUC__) || defined(__SUNPRO_C)
#include "gcc/ck_cc.h"
#ifdef CK_CC_RESTRICT
#undef CK_CC_RESTRICT
#define CK_CC_RESTRICT __restrict__
#endif
#endif
#include <ck_ring.h>])
AC_CHECK_SIZEOF([gnutls_session_t],,[#include <gnutls/gnutls.h>])
AC_CHECK_SIZEOF([gnutls_certificate_credentials_t],,[#include <gnutls/gnutls.h>])
AC_CHECK_SIZEOF([struct pollfd],,[#include <poll.h>])
# Output Makefiles
AC_CONFIG_FILES([
Makefile
src/Makefile
src/test/Makefile
examples/Makefile
])
AC_OUTPUT

21
examples/Makefile.am Normal file
View file

@ -0,0 +1,21 @@
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
dist_doc_DATA = capture.lua dumpdns2pcap.lua dumpdns.lua dumpdns-qr.lua \
filter_rcode.lua qr-multi-pcap-state.lua readme.lua replay.lua \
replay_multicli.lua respdiff.lua test_pcap_read.lua test_throughput.lua

47
examples/capture.lua Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env dnsjit
local interface = arg[2]
if interface == nil then
print("usage: "..arg[1].." <interface or any/all>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
input:create(interface)
input:activate()
layer:producer(input)
local producer, ctx = layer:produce()
while true do
local obj = producer(ctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
dns.obj_prev = obj
if transport ~= nil and protocol ~= nil then
transport = transport:cast()
protocol = protocol:cast()
print(protocol:type().." "..transport:source()..":"..tonumber(protocol.sport).." -> "..transport:destination()..":"..tonumber(protocol.dport))
dns:print()
end
end
end

50
examples/count-pkts-per-ip.lua Executable file
View file

@ -0,0 +1,50 @@
#!/usr/bin/env dnsjit
-- count-pkts-per-ip.lua: count number of packets received from each IP/IPv6 address
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local object = require("dnsjit.core.objects")
local ip = require("dnsjit.lib.ip")
local trie = require("dnsjit.lib.trie").new("uint64_t", true)
local getopt = require("dnsjit.lib.getopt").new({})
local pcap = unpack(getopt:parse())
if pcap == nil then
print("usage: "..arg[1].." <pcap>")
end
-- Set up input
input:open_offline(pcap)
layer:producer(input)
local produce, pctx = layer:produce()
-- Read input and count packets
while true do
local obj = produce(pctx)
if obj == nil then break end
local pkt = obj:cast_to(object.IP) or obj:cast_to(object.IP6)
if pkt ~= nil then
local iplen = 4
if pkt:type() == "ip6" then
iplen = 16
end
local node = trie:get_ins(pkt.src, iplen)
node:set(node:get() + 1)
end
end
-- Print statistics
local iter = trie:iter()
local node = iter:node()
while node ~= nil do
local npkts = tonumber(node:get())
local key = node:key()
local ipstr = ip.tostring(key, true)
print(ipstr.." sent "..npkts.." packets")
iter:next()
node = iter:node()
end

85
examples/dumpdns-qr.lua Executable file
View file

@ -0,0 +1,85 @@
#!/usr/bin/env dnsjit
local pcap = arg[2]
if pcap == nil then
print("usage: "..arg[1].." <pcap>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
local label = require("dnsjit.core.object.dns.label")
local ffi = require("ffi")
local labels = require("dnsjit.core.object.dns.label").new(16)
local q = require("dnsjit.core.object.dns.q").new()
input:open_offline(pcap)
layer:producer(input)
local producer, ctx = layer:produce()
local queries = {}
local responses = {}
while true do
local obj = producer(ctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
dns.obj_prev = obj
if transport ~= nil and protocol ~= nil and dns:parse_header() == 0 then
transport = transport:cast()
protocol = protocol:cast()
if dns.qr == 1 then
table.insert(responses, {
src = transport:source(),
sport = protocol.sport,
dst = transport:destination(),
dport = protocol.dport,
id = dns.id,
rcode = dns.rcode_tostring(dns.rcode),
})
else
if dns.qdcount > 0 and dns:parse_q(q, labels, 16) == 0 then
table.insert(queries, {
src = transport:source(),
sport = protocol.sport,
dst = transport:destination(),
dport = protocol.dport,
id = dns.id,
qname = label.tooffstr(dns, labels, 16),
qtype = dns.type_tostring(q.type)
})
end
end
end
end
end
print("src", "dst", "id", "rcode", "qname", "qtype")
local q, r
for _, q in pairs(queries) do
for _, r in pairs(responses) do
if q.id == r.id and q.sport == r.dport and q.dport == r.sport and q.src == r.dst and q.dst == r.src then
print(q.src, q.dst, q.id, r.rcode, q.qname, q.qtype)
end
end
end

46
examples/dumpdns.lua Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/env dnsjit
local pcap = arg[2]
if pcap == nil then
print("usage: "..arg[1].." <pcap>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
input:open_offline(pcap)
layer:producer(input)
local producer, ctx = layer:produce()
while true do
local obj = producer(ctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
dns.obj_prev = obj
if transport ~= nil and protocol ~= nil then
transport = transport:cast()
protocol = protocol:cast()
print(protocol:type().." "..transport:source()..":"..tonumber(protocol.sport).." -> "..transport:destination()..":"..tonumber(protocol.dport))
dns:print()
end
end
end

38
examples/dumpdns2pcap.lua Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env dnsjit
local pcap_in = arg[2]
local pcap_out = arg[3]
if pcap_in == nil or pcap_out == nil then
print("usage: "..arg[1].." <pcap in> <pcap out>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
local output = require("dnsjit.output.pcap").new()
input:open_offline(pcap_in)
layer:producer(input)
local producer, ctx = layer:produce()
output:open(pcap_out, input:linktype(), input:snaplen())
local receiver, rctx = output:receive()
local n = 0
while true do
local obj = producer(ctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
dns.obj_prev = obj
if dns:parse_header() == 0 then
receiver(rctx, obj)
n = n + 1
end
end
end
output:close()
print(n, "DNS packets dumped")

38
examples/filter_rcode.lua Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env dnsjit
local pcap = arg[2]
local rcode = tonumber(arg[3])
if pcap == nil or rcode == nil then
print("usage: "..arg[1].." <pcap> <rcode>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
input:open_offline(pcap)
layer:producer(input)
local producer, ctx = layer:produce()
while true do
local obj = producer(ctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
dns.obj_prev = obj
if transport and dns and dns:parse_header() == 0 and dns.have_rcode == 1 and dns.rcode == rcode then
transport = transport:cast()
print(dns.id, transport:source().." -> "..transport:destination())
end
end
end

270
examples/qr-multi-pcap-state.lua Executable file
View file

@ -0,0 +1,270 @@
#!/usr/bin/env dnsjit
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
local getopt = require("dnsjit.lib.getopt").new({
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ "r", "read-state", "", "File to read state from before processing", "?" },
{ "w", "write-state", "", "File to write state to after processing", "?" },
})
local pcap = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if pcap == nil then
print("usage: "..arg[1].." <pcap>")
return
end
local object = require("dnsjit.core.objects")
local input = require("dnsjit.input.mmpcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
local label = require("dnsjit.core.object.dns.label")
local ffi = require("ffi")
local labels = require("dnsjit.core.object.dns.label").new(16)
local q = require("dnsjit.core.object.dns.q").new()
local bit = require("bit")
hash_u32 = ffi.new("uint32_t[2]")
hash_u32p = ffi.cast("uint32_t*", hash_u32)
function hashkey(dns, transport, protocol)
if transport.obj_type == object.IP then
ffi.copy(hash_u32p, transport.src, 4)
hash_u32[1] = hash_u32[0]
ffi.copy(hash_u32p, transport.dst, 4)
hash_u32[1] = bit.bxor(hash_u32[0], hash_u32[1])
else
local srcp = ffi.cast("uint8_t*", transport.src)
ffi.copy(hash_u32p, srcp, 4)
hash_u32[1] = hash_u32[0]
ffi.copy(hash_u32p, srcp+4, 4)
hash_u32[1] = bit.bxor(hash_u32[0], hash_u32[1])
srcp = ffi.cast("uint8_t*", transport.dst)
ffi.copy(hash_u32p, srcp, 4)
hash_u32[1] = bit.bxor(hash_u32[0], hash_u32[1])
ffi.copy(hash_u32p, srcp+4, 4)
hash_u32[1] = bit.bxor(hash_u32[0], hash_u32[1])
end
if dns.qr == 1 then
hash_u32[0] = protocol.dport + bit.lshift(protocol.sport, 16)
else
hash_u32[0] = protocol.sport + bit.lshift(protocol.dport, 16)
end
hash_u32[1] = bit.bxor(hash_u32[0], hash_u32[1])
hash_u32[0] = dns.id + bit.lshift(dns.id, 16)
return bit.bxor(hash_u32[0], hash_u32[1])
end
function dump_inflight(hkey, obj)
return string.format("return %d, { qsec = %d, qnsec = %d, rsec = %d, rnsec = %d, src = %q, sport = %d, dst = %q, dport = %d, id = %d, qname = %q, qtype = %q, rcode = %d }",
hkey,
tonumber(obj.qsec), tonumber(obj.qnsec),
tonumber(obj.rsec), tonumber(obj.rnsec),
obj.src, obj.sport,
obj.dst, obj.dport,
obj.id,
obj.qname, obj.qtype,
obj.rcode
)
end
function qrout(res)
local tsq = tonumber(res.qsec) + (tonumber(res.qnsec)/1000000000)
local tsr = tonumber(res.rsec) + (tonumber(res.rnsec)/1000000000)
print(tsq, tsr, math.floor(((tsr-tsq)*1000000)+0.5),
res.src, res.dst, res.id, res.rcode, res.qname, res.qtype)
end
input:open(pcap)
layer:producer(input)
local producer, ctx = layer:produce()
local inflight = {}
if getopt:val("read-state") > "" then
local f, _ = io.open(getopt:val("read-state"))
local inflights = 0
if f ~= nil then
for chunk in f:lines() do
local hkey, query = assert(loadstring(chunk))()
if hkey and query then
if not inflight[hkey] then
inflight[hkey] = {
queries = {},
size = 0,
}
end
table.insert(inflight[hkey].queries, query)
inflight[hkey].size = inflight[hkey].size + 1
inflights = inflights + 1
end
end
f:close()
print(string.format("== read %d inflight states from %q", inflights, getopt:val("read-state")))
end
end
local stat = {
packets = 0,
queries = 0,
responses = 0,
dropped = 0,
}
local start_sec, start_nsec = clock:monotonic()
while true do
local obj = producer(ctx)
if obj == nil then break end
stat.packets = stat.packets + 1
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
local transport = protocol.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local pcap = transport.obj_prev
while pcap ~= nil do
if pcap.obj_type == object.PCAP then
break
end
pcap = pcap.obj_prev
end
dns.obj_prev = obj
if pcap ~= nil and transport ~= nil and protocol ~= nil and dns:parse_header() == 0 then
transport = transport:cast()
protocol = protocol:cast()
pcap = pcap:cast()
local hkey = hashkey(dns, transport, protocol)
if dns.qr == 1 then
stat.responses = stat.responses + 1
if inflight[hkey] then
for k, n in pairs(inflight[hkey].queries) do
if n.id == dns.id
and n.sport == protocol.dport
and n.dport == protocol.sport
and n.src == transport:destination()
and n.dst == transport:source()
then
n.rsec = pcap.ts.sec
n.rnsec = pcap.ts.nsec
n.rcode = dns.rcode
qrout(n)
inflight[hkey].queries[k] = nil
inflight[hkey].size = inflight[hkey].size - 1
if inflight[hkey].size < 1 then
inflight[hkey] = nil
end
break
end
end
else
print("== dropped",
tonumber(pcap.ts.sec) + (tonumber(pcap.ts.nsec) / 1000000000),
transport:source(),
transport:destination(),
dns.id,
label.tooffstr(dns, labels, 16),
dns.type_tostring(q.type)
)
stat.dropped = stat.dropped + 1
end
else
stat.queries = stat.queries + 1
if dns.qdcount > 0 and dns:parse_q(q, labels, 16) == 0 then
if not inflight[hkey] then
inflight[hkey] = {
queries = {},
size = 0,
}
end
table.insert(inflight[hkey].queries, {
qsec = pcap.ts.sec,
qnsec = pcap.ts.nsec,
rsec = -1,
rnsec = -1,
src = transport:source(),
sport = protocol.sport,
dst = transport:destination(),
dport = protocol.dport,
id = dns.id,
qname = label.tooffstr(dns, labels, 16),
qtype = dns.type_tostring(q.type),
rcode = -1,
})
inflight[hkey].size = inflight[hkey].size + 1
end
end
end
end
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print("== runtime", runtime)
print("== packets", stat.packets, stat.packets/runtime)
print("== queries", stat.queries, stat.queries/runtime)
print("== responses", stat.responses, stat.responses/runtime)
print("== dropped", stat.dropped, stat.dropped/runtime)
if getopt:val("write-state") > "" then
local f, _ = io.open(getopt:val("write-state"), "w+")
local inflights = 0
if f ~= nil then
for hkey, unanswered in pairs(inflight) do
for _, query in pairs(unanswered.queries) do
f:write(dump_inflight(hkey, query), "\n")
inflights = inflights + 1
end
end
f:close()
print(string.format("== wrote %d inflight states to %q", inflights, getopt:val("write-state")))
end
else
inflights = 0
for hkey, unanswered in pairs(inflight) do
inflights = inflights + unanswered.size
end
if inflights > 0 then
print("== inflight queries (tsq, src, dst, id, qname, qtype)")
for hkey, unanswered in pairs(inflight) do
for _, query in pairs(unanswered.queries) do
print(tonumber(query.qsec) + (tonumber(query.qnsec)/1000000000), query.src, query.dst, query.id, query.qname, query.qtype)
end
end
end
end

20
examples/readme.lua Executable file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env dnsjit
require("dnsjit.core.objects")
local input = require("dnsjit.input.pcap").new()
local layer = require("dnsjit.filter.layer").new()
local dns = require("dnsjit.core.object.dns").new()
input:open_offline(arg[2])
layer:producer(input)
local producer, ctx = layer:produce()
while true do
local object = producer(ctx)
if object == nil then break end
if object:type() == "payload" then
dns.obj_prev = object
if dns:parse_header() == 0 then
print(dns.id)
end
end
end

119
examples/replay.lua Executable file
View file

@ -0,0 +1,119 @@
#!/usr/bin/env dnsjit
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
local getopt = require("dnsjit.lib.getopt").new({
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ "R", "responses", false, "Wait for responses to the queries and print both", "?" },
{ "t", "tcp", false, "Use TCP instead of UDP", "?"},
{ "T", "tls", false, "Use TLS instead of UDP/TCP", "?"},
})
local pcap, host, port = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if pcap == nil or host == nil or port == nil then
print("usage: "..arg[1].." <pcap> <host> <port>")
return
end
local ffi = require("ffi")
require("dnsjit.core.objects")
local input = require("dnsjit.input.mmpcap").new()
local layer = require("dnsjit.filter.layer").new()
input:open(pcap)
layer:producer(input)
local query = require("dnsjit.core.object.dns").new()
local response = require("dnsjit.core.object.dns").new()
local dnscli = require("dnsjit.output.dnscli")
local output
if getopt:val("t") then
output = dnscli.new(dnscli.TCP)
response.includes_dnslen = 1
elseif getopt:val("T") then
output = dnscli.new(dnscli.TLS)
response.includes_dnslen = 1
else
output = dnscli.new(dnscli.UDP)
end
output:connect(host, port)
local printdns = false
if getopt:val("responses") then
printdns = true
end
local prod, pctx = layer:produce()
local recv, rctx = output:receive()
local oprod, opctx = output:produce()
local start_sec, start_nsec = clock:monotonic()
while true do
local obj = prod(pctx)
if obj == nil then break end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
query.obj_prev = obj
local trs = pl.obj_prev:cast()
if trs:type() == "tcp" then
query.includes_dnslen = 1
else
query.includes_dnslen = 0
end
if query:parse_header() == 0 and query.qr == 0 then
recv(rctx, query:uncast())
if printdns then
print("query:")
query:print()
local pobj = oprod(opctx)
if pobj == nil then
log.fatal("producer error")
end
local rpl = pobj:cast()
if rpl.len == 0 then
print("timed out")
else
response.obj_prev = pobj
print("response:")
response:print()
end
end
end
end
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print("runtime", runtime)
print("packets", input:packets(), input:packets()/runtime, "/pps")
print("queries", output:packets(), output:packets()/runtime, "/qps")
print("errors", output:errors())

192
examples/replay_multicli.lua Executable file
View file

@ -0,0 +1,192 @@
#!/usr/bin/env dnsjit
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
local getopt = require("dnsjit.lib.getopt").new({
{ "c", "clients", 10, "Number of clients run", "?" },
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ "R", "responses", false, "Wait for responses to the queries and print both", "?" },
{ "t", "tcp", false, "Use TCP instead of UDP", "?"},
{ "T", "tls", false, "Use TLS instead of UDP/TCP", "?"},
})
local pcap, host, port = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if pcap == nil or host == nil or port == nil then
print("usage: "..arg[1].." <pcap> <host> <port>")
return
end
local ffi = require("ffi")
require("dnsjit.core.objects")
local input = require("dnsjit.input.mmpcap").new()
local layer = require("dnsjit.filter.layer").new()
input:open(pcap)
layer:producer(input)
local query = require("dnsjit.core.object.dns").new()
local response = require("dnsjit.core.object.dns").new()
local dnscli = require("dnsjit.output.dnscli")
local clients = {}
local last_client = nil
local num_clients = getopt:val("c")
for n = 1, num_clients do
local output
if getopt:val("t") then
output = dnscli.new(dnscli.TCP + dnscli.NONBLOCKING)
elseif getopt:val("T") then
output = dnscli.new(dnscli.TLS + dnscli.NONBLOCKING)
else
output = dnscli.new(dnscli.UDP + dnscli.NONBLOCKING)
end
output:connect(host, port)
local recv, rctx = output:receive()
local prod, pctx = output:produce()
local client = {
output = output,
last = last_client,
busy = false,
recv = recv, rctx = rctx,
prod = prod, pctx = pctx,
id = nil,
done = false,
}
table.insert(clients, client)
last_client = client
end
local output = clients[1]
output.last = last_client
if getopt:val("t") then
response.includes_dnslen = 1
elseif getopt:val("T") then
response.includes_dnslen = 1
end
local printdns = false
if getopt:val("responses") then
printdns = true
end
local prod, pctx = layer:produce()
local start_sec, start_nsec = clock:monotonic()
local done = false
while true do
output = output.last
if printdns and output.busy then
local pobj = output.prod(output.pctx)
if pobj == nil then
log.fatal("producer error")
end
local rpl = pobj:cast()
if rpl.len == 0 then
-- print(output, "busy")
else
response.obj_prev = pobj
if response:parse_header() == 0 and response.qr == 1 and response.id == output.id then
print("response:")
response:print()
output.busy = false
end
end
end
if not output.busy then
while true do
local obj = prod(pctx)
if obj == nil then
done = true
break
end
local pl = obj:cast()
if obj:type() == "payload" and pl.len > 0 then
query.obj_prev = obj
local trs = pl.obj_prev:cast()
if trs:type() == "tcp" then
query.includes_dnslen = 1
else
query.includes_dnslen = 0
end
if query:parse_header() == 0 and query.qr == 0 then
output.recv(output.rctx, query:uncast())
if printdns then
print("query:")
query:print()
output.busy = true
output.id = query.id
end
break
end
end
end
end
if done then break end
end
local queries, timeouts, errors = 0, 0, 0
done = 0
while true do
output = output.last
if printdns and output.busy then
local pobj = output.prod(output.pctx)
if pobj == nil then
log.fatal("producer error")
end
local rpl = pobj:cast()
if rpl.len == 0 then
-- print(output, "busy")
else
response.obj_prev = pobj
if response:parse_header() == 0 and response.qr == 1 and response.id == output.id then
print("response:")
response:print()
output.busy = false
end
end
end
if not output.busy and not output.done then
output.done = true
done = done + 1
queries = queries + output.output:packets()
timeouts = timeouts + output.output:timeouts()
errors = errors + output.output:errors()
end
if done >= num_clients then break end
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print("runtime", runtime)
print("packets", input:packets(), input:packets()/runtime, "/pps")
print("queries", queries, queries/runtime, "/qps")
print("timeouts", timeouts)
print("errors", errors)

160
examples/respdiff.lua Executable file
View file

@ -0,0 +1,160 @@
#!/usr/bin/env dnsjit
local ffi = require("ffi")
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
log.display_file_line(true)
local getopt = require("dnsjit.lib.getopt").new({
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
})
local pcap, host, port, path, origname, recvname = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if pcap == nil or host == nil or port == nil or path == nil or origname == nil or recvname == nil then
print("usage: "..arg[1].." <pcap> <host> <port> <LMDB path> <origname> <recvname>")
return
end
local object = require("dnsjit.core.objects")
local dns = require("dnsjit.core.object.dns").new()
local input = require("dnsjit.input.mmpcap").new()
input:open(pcap)
local layer = require("dnsjit.filter.layer").new()
layer:producer(input)
local udpcli, tcpcli
local udprecv, udpctx, tcprecv, tcpctx
local udpprod, tcpprod
local prod, pctx = layer:produce()
local queries = {}
local clipayload = ffi.new("core_object_payload_t")
clipayload.obj_type = object.PAYLOAD
local cliobject = ffi.cast("core_object_t*", clipayload)
local respdiff = require("dnsjit.output.respdiff").new(path, origname, recvname)
local resprecv, respctx = respdiff:receive()
local query_payload, original_payload, response_payload = ffi.new("core_object_payload_t"), ffi.new("core_object_payload_t"), ffi.new("core_object_payload_t")
query_payload.obj_type = object.PAYLOAD
original_payload.obj_type = object.PAYLOAD
response_payload.obj_type = object.PAYLOAD
local query_payload_obj = ffi.cast("core_object_t*", query_payload)
query_payload.obj_prev = ffi.cast("core_object_t*", original_payload)
original_payload.obj_prev = ffi.cast("core_object_t*", response_payload)
local start_sec, start_nsec = clock:realtime()
while true do
local obj = prod(pctx)
if obj == nil then break end
local payload = obj:cast()
if obj:type() == "payload" and payload.len > 0 then
dns.obj_prev = obj
if dns:parse_header() == 0 then
local transport = obj.obj_prev
while transport ~= nil do
if transport.obj_type == object.IP or transport.obj_type == object.IP6 then
break
end
transport = transport.obj_prev
end
local protocol = obj.obj_prev
while protocol ~= nil do
if protocol.obj_type == object.UDP or protocol.obj_type == object.TCP then
break
end
protocol = protocol.obj_prev
end
if transport ~= nil and protocol ~= nil then
transport = transport:cast()
protocol = protocol:cast()
if dns.qr == 0 then
local k = string.format("%s %d %s %d", transport:source(), protocol.sport, transport:destination(), protocol.dport)
local q = {
id = dns.id,
proto = protocol:type(),
payload = ffi.new("uint8_t[?]", payload.len),
len = tonumber(payload.len)
}
ffi.copy(q.payload, payload.payload, payload.len)
queries[k] = q
else
local k = string.format("%s %d %s %d", transport:destination(), protocol.dport, transport:source(), protocol.sport)
local q = queries[k]
if q then
queries[k] = nil
clipayload.payload = q.payload
clipayload.len = q.len
local prod, pctx
if q.proto == "udp" then
if not udpcli then
udpcli = require("dnsjit.output.udpcli").new()
udpcli:connect(host, port)
udprecv, udpctx = udpcli:receive()
udpprod, _ = udpcli:produce()
end
udprecv(udpctx, cliobject)
prod = udpprod
pctx = udpctx
elseif q.proto == "tcp" then
if not tcpcli then
tcpcli = require("dnsjit.output.tcpcli").new()
tcpcli:connect(host, port)
tcprecv, tcpctx = tcpcli:receive()
tcpprod, _ = tcpcli:produce()
end
tcprecv(tcpctx, cliobject)
prod = tcpprod
pctx = tcpctx
end
while true do
local response = prod(pctx)
if response == nil then
log.fatal("producer error")
end
local rpl = response:cast()
if rpl.len == 0 then
log.info("timed out")
else
dns.obj_prev = response
if dns:parse_header() == 0 and dns.id == q.id then
query_payload.payload = q.payload
query_payload.len = q.len
original_payload.payload = payload.payload
original_payload.len = payload.len
response_payload.payload = rpl.payload
response_payload.len = rpl.len
resprecv(respctx, query_payload_obj)
break
end
end
end
end
end
end
end
end
end
local end_sec, end_nsec = clock:realtime()
respdiff:commit(start_sec, end_sec)

149
examples/test_pcap_read.lua Executable file
View file

@ -0,0 +1,149 @@
#!/usr/bin/env dnsjit
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
local getopt = require("dnsjit.lib.getopt").new({
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ "l", "layer", false, "Test also with dnsjit.filter.layer", "?" },
{ "p", "producer", false, "Test with the producer interface rather then receiver interface", "?" },
})
local pcap, runs = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if pcap == nil then
print("usage: "..arg[1].." <pcap> [runs]")
return
end
inputs = { "fpcap", "mmpcap", "pcap" }
result = {}
results = {}
highest = nil
if runs == nil then
runs = 10
else
runs = tonumber(runs)
end
if getopt:val("p") then
for _, name in pairs(inputs) do
rt = 0.0
p = 0
print("run", name)
for n = 1, runs do
o = require("dnsjit.output.null").new()
i = require("dnsjit.input."..name).new()
if name == "pcap" then
i:open_offline(pcap)
else
i:open(pcap)
end
if getopt:val("l") then
f = require("dnsjit.filter.layer").new()
f:producer(i)
o:producer(f)
else
o:producer(i)
end
ss, sns = clock:monotonic()
o:run()
es, ens = clock:monotonic()
if es > ss then
rt = rt + ((es - ss) - 1) + ((1000000000 - sns + ens)/1000000000)
elseif es == ss and ens > sns then
rt = rt + (ens - sns) / 1000000000
end
p = p + o:packets()
end
result[name] = {
rt = rt,
p = p
}
if highest == nil or rt > result[highest].rt then
highest = name
end
table.insert(results, name)
end
else
for _, name in pairs(inputs) do
rt = 0.0
p = 0
print("run", name)
for n = 1, runs do
o = require("dnsjit.output.null").new()
i = require("dnsjit.input."..name).new()
if name == "pcap" then
i:open_offline(pcap)
else
i:open(pcap)
end
if getopt:val("l") then
f = require("dnsjit.filter.layer").new()
f:receiver(o)
i:receiver(f)
else
i:receiver(o)
end
ss, sns = clock:monotonic()
if name == "pcap" then
i:dispatch()
else
i:run()
end
es, ens = clock:monotonic()
if es > ss then
rt = rt + ((es - ss) - 1) + ((1000000000 - sns + ens)/1000000000)
elseif es == ss and ens > sns then
rt = rt + (ens - sns) / 1000000000
end
p = p + o:packets()
end
result[name] = {
rt = rt,
p = p
}
if highest == nil or rt > result[highest].rt then
highest = name
end
table.insert(results, name)
end
end
print("name", "runtime", "pps", "x", "pkts")
print(highest, result[highest].rt, result[highest].p/result[highest].rt, 1.0, result[highest].p)
for _, name in pairs(results) do
if name ~= highest then
local f = result[name].p / result[highest].p
print(name, result[name].rt, result[name].p/result[name].rt, (result[highest].rt/result[name].rt)*f, result[name].p)
end
end

539
examples/test_throughput.lua Executable file
View file

@ -0,0 +1,539 @@
#!/usr/bin/env dnsjit
local ffi = require("ffi")
local object = require("dnsjit.core.objects")
local clock = require("dnsjit.lib.clock")
local log = require("dnsjit.core.log")
local getopt = require("dnsjit.lib.getopt").new({
{ "v", "verbose", 0, "Enable and increase verbosity for each time given", "?+" },
{ "s", "split", false, "Test also with dnsjit.filter.split", "?" },
{ "t", "thread", false, "Test also with dnsjit.core.thread using dnsjit.core.channel", "?" },
})
local num, runs = unpack(getopt:parse())
if getopt:val("help") then
getopt:usage()
return
end
local v = getopt:val("v")
if v > 0 then
log.enable("warning")
end
if v > 1 then
log.enable("notice")
end
if v > 2 then
log.enable("info")
end
if v > 3 then
log.enable("debug")
end
if num == nil then
print("usage: "..arg[1].." <num> [runs]")
return
else
num = tonumber(num)
end
if runs == nil then
runs = 1
else
runs = tonumber(runs)
end
print("zero:receiver() -> null:receive()")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local o = require("dnsjit.output.null").new()
i:receiver(o)
local start_sec, start_nsec = clock:monotonic()
i:run(num)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o:packets())
end
print("lua -> null:receive()")
local run
for run = 1, runs do
local o = require("dnsjit.output.null").new()
local recv, rctx = o:receive()
local pkt = ffi.new("core_object_null_t")
pkt.obj_type = object.NULL
local obj = ffi.cast("core_object_t*", pkt)
local start_sec, start_nsec = clock:monotonic()
for n = 1, num do
recv(rctx, obj)
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o:packets())
end
-- TODO: use core.thread
print("zero:produce() <- null:producer()")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local o = require("dnsjit.output.null").new()
local start_sec, start_nsec = clock:monotonic()
o:producer(i)
o:run(num)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o:packets())
end
print("zero:produce() <- lua")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local prod, pctx = i:produce()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num do
prod(pctx)
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", num)
end
print("zero:produce() <- lua -> null:receive()")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local o = require("dnsjit.output.null").new()
local prod, pctx = i:produce()
local recv, rctx = o:receive()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num do
recv(rctx, prod(pctx))
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", num)
end
if getopt:val("s") then
print("zero:receiver() -> split:receiver() -> null:receive() x1")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local s = require("dnsjit.filter.split").new()
local o1 = require("dnsjit.output.null").new()
s:receiver(o1)
i:receiver(s)
local start_sec, start_nsec = clock:monotonic()
i:run(num)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o1:packets(), o1:packets())
end
print("zero:receiver() -> split:receiver() -> null:receive() x2")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local s = require("dnsjit.filter.split").new()
local o1 = require("dnsjit.output.null").new()
local o2 = require("dnsjit.output.null").new()
s:receiver(o1)
s:receiver(o2)
i:receiver(s)
local start_sec, start_nsec = clock:monotonic()
i:run(num)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o1:packets() + o2:packets(), o1:packets(), o2:packets())
end
print("zero:receiver() -> split:receiver() -> null:receive() x4")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local s = require("dnsjit.filter.split").new()
local o1 = require("dnsjit.output.null").new()
local o2 = require("dnsjit.output.null").new()
local o3 = require("dnsjit.output.null").new()
local o4 = require("dnsjit.output.null").new()
s:receiver(o1)
s:receiver(o2)
s:receiver(o3)
s:receiver(o4)
i:receiver(s)
local start_sec, start_nsec = clock:monotonic()
i:run(num)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o1:packets() + o2:packets() + o3:packets() + o4:packets(), o1:packets(), o2:packets(), o3:packets(), o4:packets())
end
print("zero:receiver() -> lua split table -> null:receive() x4")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local o1 = require("dnsjit.output.null").new()
local o2 = require("dnsjit.output.null").new()
local o3 = require("dnsjit.output.null").new()
local o4 = require("dnsjit.output.null").new()
local prod, pctx = i:produce()
local recv, rctx = {}, {}
local f, c = o1:receive()
table.insert(recv, f)
table.insert(rctx, c)
f, c = o2:receive()
table.insert(recv, f)
table.insert(rctx, c)
f, c = o3:receive()
table.insert(recv, f)
table.insert(rctx, c)
f, c = o4:receive()
table.insert(recv, f)
table.insert(rctx, c)
local start_sec, start_nsec = clock:monotonic()
local idx = 1
for n = 1, num do
local f, c = recv[idx], rctx[idx]
if not f then
idx = 1
f, c = recv[1], rctx[1]
end
f(c, prod(pctx))
idx = idx + 1
end
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o1:packets() + o2:packets() + o3:packets() + o4:packets(), o1:packets(), o2:packets(), o3:packets(), o4:packets())
end
print("zero:receiver() -> lua split gen code -> null:receive() x4")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local o1 = require("dnsjit.output.null").new()
local o2 = require("dnsjit.output.null").new()
local o3 = require("dnsjit.output.null").new()
local o4 = require("dnsjit.output.null").new()
local prod, pctx = i:produce()
local f1, c1 = o1:receive()
local f2, c2 = o2:receive()
local f3, c3 = o3:receive()
local f4, c4 = o4:receive()
local code = "return function (num, prod, pctx, f1, c1, f2, c2, f3, c3, f4, c4)\nlocal n = 0\nwhile n < num do\n"
code = code .. "f1(c1,prod(pctx))\n"
code = code .. "n = n + 1\n"
code = code .. "f2(c2,prod(pctx))\n"
code = code .. "n = n + 1\n"
code = code .. "f3(c3,prod(pctx))\n"
code = code .. "n = n + 1\n"
code = code .. "f4(c4,prod(pctx))\n"
code = code .. "n = n + 1\n"
code = code .. "end\n"
code = code .. "end"
local f = assert(loadstring(code))()
local start_sec, start_nsec = clock:monotonic()
f(num, prod, pctx, f1, c1, f2, c2, f3, c3, f4, c4)
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec", o1:packets() + o2:packets() + o3:packets() + o4:packets(), o1:packets(), o2:packets(), o3:packets(), o4:packets())
end
end
if getopt:val("t") then
print("zero:receiver() -> thread lua x1")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local c = require("dnsjit.core.channel").new()
local t = require("dnsjit.core.thread").new()
t:start(function(t)
local c = t:pop()
while true do
local o = c:get()
if o == nil then break end
end
end)
t:push(c)
local prod, pctx = i:produce()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num do
c:put(prod(pctx))
end
c:close()
t:stop()
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec")
end
print("zero:receiver() -> thread lua x2")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local c = require("dnsjit.core.channel").new()
local c2 = require("dnsjit.core.channel").new()
local t = require("dnsjit.core.thread").new()
local t2 = require("dnsjit.core.thread").new()
local f = function(t)
local c = t:pop()
while true do
local o = c:get()
if o == nil then break end
end
end
t:start(f)
t2:start(f)
t:push(c)
t2:push(c2)
local prod, pctx = i:produce()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num/2 do
c:put(prod(pctx))
c2:put(prod(pctx))
end
c:close()
c2:close()
t:stop()
t2:stop()
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec")
end
print("zero:receiver() -> thread lua x4")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local c = require("dnsjit.core.channel").new()
local c2 = require("dnsjit.core.channel").new()
local c3 = require("dnsjit.core.channel").new()
local c4 = require("dnsjit.core.channel").new()
local t = require("dnsjit.core.thread").new()
local t2 = require("dnsjit.core.thread").new()
local t3 = require("dnsjit.core.thread").new()
local t4 = require("dnsjit.core.thread").new()
local f = function(t)
local c = t:pop()
while true do
local o = c:get()
if o == nil then break end
end
end
t:start(f)
t2:start(f)
t3:start(f)
t4:start(f)
t:push(c)
t2:push(c2)
t3:push(c3)
t4:push(c4)
local prod, pctx = i:produce()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num/4 do
c:put(prod(pctx))
c2:put(prod(pctx))
c3:put(prod(pctx))
c4:put(prod(pctx))
end
c:close()
c2:close()
c3:close()
c4:close()
t:stop()
t2:stop()
t3:stop()
t4:stop()
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec")
end
print("zero:receiver() -> thread lua x1 -> null:receiver()")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local c = require("dnsjit.core.channel").new()
local t = require("dnsjit.core.thread").new()
t:start(function(t)
local c = t:pop()
local o = require("dnsjit.output.null").new()
local recv, rctx = o:receive()
while true do
local obj = c:get()
if obj == nil then break end
recv(rctx, obj)
end
end)
t:push(c)
local prod, pctx = i:produce()
local start_sec, start_nsec = clock:monotonic()
for n = 1, num do
c:put(prod(pctx))
end
c:close()
t:stop()
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec")
end
print("zero:receiver() -> thread x1 -> null:receiver()")
local run
for run = 1, runs do
local i = require("dnsjit.input.zero").new()
local c = require("dnsjit.core.channel").new()
local t = require("dnsjit.core.thread").new()
t:start(function(t)
local c = t:pop()
local o = require("dnsjit.output.null").new()
c:receiver(o)
c:run()
end)
t:push(c)
i:receiver(c)
local start_sec, start_nsec = clock:monotonic()
i:run(num)
c:close()
t:stop()
local end_sec, end_nsec = clock:monotonic()
local runtime = 0
if end_sec > start_sec then
runtime = ((end_sec - start_sec) - 1) + ((1000000000 - start_nsec + end_nsec)/1000000000)
elseif end_sec == start_sec and end_nsec > start_nsec then
runtime = (end_nsec - start_nsec) / 1000000000
end
print(run, "runtime", runtime, num/runtime, "/sec")
end
end

26
fmt.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
clang-format \
-style=file \
-i \
src/*.c \
`find src/core src/input src/filter src/output src/lib -name '*.c'` \
`find src/core src/input src/filter src/output src/lib -name '*.h'` \
`find src/core src/input src/filter src/output src/lib -name '*.hh'`

50
m4/ax_append_flag.m4 Normal file
View file

@ -0,0 +1,50 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
# added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
AC_DEFUN([AX_APPEND_FLAG],
[dnl
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
AS_VAR_SET_IF(FLAGS,[
AS_CASE([" AS_VAR_GET(FLAGS) "],
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
[
AS_VAR_APPEND(FLAGS,[" $1"])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
],
[
AS_VAR_SET(FLAGS,[$1])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_APPEND_FLAG

158
m4/ax_cflags_warn_all.m4 Normal file
View file

@ -0,0 +1,158 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
# AX_CXXFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
# AX_FCFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
#
# DESCRIPTION
#
# Specify compiler options that enable most reasonable warnings. For the
# GNU Compiler Collection (GCC), for example, it will be "-Wall". The
# result is added to shellvar, one of CFLAGS, CXXFLAGS or FCFLAGS if the
# first parameter is not specified.
#
# Each of these macros accepts the following optional arguments:
#
# - $1 - shellvar
# shell variable to use (CFLAGS, CXXFLAGS or FCFLAGS if not
# specified, depending on macro)
#
# - $2 - default
# value to use for flags if compiler vendor cannot be determined (by
# default, "")
#
# - $3 - action-if-found
# action to take if the compiler vendor has been successfully
# determined (by default, add the appropriate compiler flags to
# shellvar)
#
# - $4 - action-if-not-found
# action to take if the compiler vendor has not been determined or
# is unknown (by default, add the default flags, or "" if not
# specified, to shellvar)
#
# These macros use AX_COMPILER_VENDOR to determine which flags should be
# returned for a given compiler. Not all compilers currently have flags
# defined for them; patches are welcome. If need be, compiler flags may
# be made language-dependent: use a construct like the following:
#
# [vendor_name], [m4_if(_AC_LANG_PREFIX,[C], VAR="--relevant-c-flags",dnl
# m4_if(_AC_LANG_PREFIX,[CXX], VAR="--relevant-c++-flags",dnl
# m4_if(_AC_LANG_PREFIX,[FC], VAR="--relevant-fortran-flags",dnl
# VAR="$2"; FOUND="no")))],
#
# Note: These macros also depend on AX_PREPEND_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
# Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 25
AC_DEFUN([AX_FLAGS_WARN_ALL], [
AX_REQUIRE_DEFINED([AX_PREPEND_FLAG])dnl
AC_REQUIRE([AX_COMPILER_VENDOR])dnl
AS_VAR_PUSHDEF([FLAGS], [m4_default($1,_AC_LANG_PREFIX[]FLAGS)])dnl
AS_VAR_PUSHDEF([VAR], [ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
AS_VAR_PUSHDEF([FOUND], [ac_save_[]_AC_LANG_ABBREV[]flags_warn_all_found])dnl
AC_CACHE_CHECK([FLAGS for most reasonable warnings], VAR, [
VAR=""
FOUND="yes"
dnl Cases are listed in the order found in ax_compiler_vendor.m4
AS_CASE("$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor",
[intel], [VAR="-w2"],
[ibm], [VAR="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd"],
[pathscale], [],
[clang], [VAR="-Wall"],
[cray], [VAR="-h msglevel 2"],
[fujitsu], [],
[sdcc], [],
[sx], [VAR="-pvctl[,]fullmsg"],
[portland], [],
[gnu], [VAR="-Wall"],
[sun], [VAR="-v"],
[hp], [VAR="+w1"],
[dec], [VAR="-verbose -w0 -warnprotos"],
[borland], [],
[comeau], [],
[kai], [],
[lcc], [],
[sgi], [VAR="-fullwarn"],
[microsoft], [],
[metrowerks], [],
[watcom], [],
[tcc], [],
[unknown], [
VAR="$2"
FOUND="no"
],
[
AC_MSG_WARN([Unknown compiler vendor returned by [AX_COMPILER_VENDOR]])
VAR="$2"
FOUND="no"
]
)
AS_IF([test "x$FOUND" = "xyes"], [dnl
m4_default($3, [AS_IF([test "x$VAR" != "x"], [AX_PREPEND_FLAG([$VAR], [FLAGS])])])
], [dnl
m4_default($4, [m4_ifval($2, [AX_PREPEND_FLAG([$VAR], [FLAGS])], [true])])
])dnl
])dnl
AS_VAR_POPDEF([FOUND])dnl
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_FLAGS_WARN_ALL
AC_DEFUN([AX_CFLAGS_WARN_ALL], [dnl
AC_LANG_PUSH([C])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C])
])dnl
AC_DEFUN([AX_CXXFLAGS_WARN_ALL], [dnl
AC_LANG_PUSH([C++])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([C++])
])dnl
AC_DEFUN([AX_FCFLAGS_WARN_ALL], [dnl
AC_LANG_PUSH([Fortran])
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
AC_LANG_POP([Fortran])
])dnl

View file

@ -0,0 +1,53 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 6
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

117
m4/ax_compiler_vendor.m4 Normal file
View file

@ -0,0 +1,117 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPILER_VENDOR
#
# DESCRIPTION
#
# Determine the vendor of the C, C++ or Fortran compiler. The vendor is
# returned in the cache variable $ax_cv_c_compiler_vendor for C,
# $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for
# (modern) Fortran. The value is one of "intel", "ibm", "pathscale",
# "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "portland" (PGI), "gnu"
# (GCC), "sun" (Oracle Developer Studio), "hp", "dec", "borland",
# "comeau", "kai", "lcc", "sgi", "microsoft", "metrowerks", "watcom",
# "tcc" (Tiny CC) or "unknown" (if the compiler cannot be determined).
#
# To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT
# with an appropriate preprocessor-enabled extension. For example:
#
# AC_LANG_PUSH([Fortran])
# AC_PROG_FC
# AC_FC_PP_SRCEXT([F])
# AX_COMPILER_VENDOR
# AC_LANG_POP([Fortran])
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
# Copyright (c) 2018-19 John Zaitseff <J.Zaitseff@zap.org.au>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 30
AC_DEFUN([AX_COMPILER_VENDOR], [dnl
AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl
dnl If you modify this list of vendors, please add similar support
dnl to ax_compiler_version.m4 if at all possible.
dnl
dnl Note: Do NOT check for GCC first since some other compilers
dnl define __GNUC__ to remain compatible with it. Compilers that
dnl are very slow to start (such as Intel) are listed first.
vendors="
intel: __ICC,__ECC,__INTEL_COMPILER
ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__
pathscale: __PATHCC__,__PATHSCALE__
clang: __clang__
cray: _CRAYC
fujitsu: __FUJITSU
sdcc: SDCC,__SDCC
sx: _SX
portland: __PGI
gnu: __GNUC__
sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95
hp: __HP_cc,__HP_aCC
dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
comeau: __COMO__
kai: __KCC
lcc: __LCC__
sgi: __sgi,sgi
microsoft: _MSC_VER
metrowerks: __MWERKS__
watcom: __WATCOMC__
tcc: __TINYC__
unknown: UNKNOWN
"
for ventest in $vendors; do
case $ventest in
*:)
vendor=$ventest
continue
;;
*)
vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")"
;;
esac
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
#if !($vencpp)
thisisanerror;
#endif
]])], [break])
done
ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
])
])dnl

328
m4/ax_ext.m4 Normal file
View file

@ -0,0 +1,328 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_ext.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_EXT
#
# DESCRIPTION
#
# Find supported SIMD extensions by requesting cpuid. When a SIMD
# extension is found, the -m"simdextensionname" is added to SIMD_FLAGS if
# compiler supports it. For example, if "sse2" is available then "-msse2"
# is added to SIMD_FLAGS.
#
# Find other supported CPU extensions by requesting cpuid. When a
# processor extension is found, the -m"extensionname" is added to
# CPUEXT_FLAGS if compiler supports it. For example, if "bmi2" is
# available then "-mbmi2" is added to CPUEXT_FLAGS.
#
# This macro calls:
#
# AC_SUBST(SIMD_FLAGS)
# AC_SUBST(CPUEXT_FLAGS)
#
# And defines:
#
# HAVE_RDRND / HAVE_BMI1 / HAVE_BMI2 / HAVE_ADX / HAVE_MPX
# HAVE_PREFETCHWT1 / HAVE_ABM / HAVE_MMX / HAVE_SSE / HAVE_SSE2
# HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4_1 / HAVE_SSE4_2 / HAVE_SSE4a
# HAVE_SHA / HAVE_AES / HAVE_AVX / HAVE_FMA3 / HAVE_FMA4 / HAVE_XOP
# HAVE_AVX2 / HAVE_AVX512_F / HAVE_AVX512_CD / HAVE_AVX512_PF
# HAVE_AVX512_ER / HAVE_AVX512_VL / HAVE_AVX512_BW / HAVE_AVX512_DQ
# HAVE_AVX512_IFMA / HAVE_AVX512_VBMI / HAVE_ALTIVEC / HAVE_VSX
#
# LICENSE
#
# Copyright (c) 2007 Christophe Tournayre <turn3r@users.sourceforge.net>
# Copyright (c) 2013,2015 Michael Petch <mpetch@capp-sysware.com>
# Copyright (c) 2017 Rafael de Lucena Valle <rafaeldelucena@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 18
AC_DEFUN([AX_EXT],
[
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
CPUEXT_FLAGS=""
SIMD_FLAGS=""
case $host_cpu in
powerpc*)
AC_CACHE_CHECK([whether altivec is supported for old distros], [ax_cv_have_altivec_old_ext],
[
if test `/usr/sbin/sysctl -a 2>/dev/null| grep -c hw.optional.altivec` != 0; then
if test `/usr/sbin/sysctl -n hw.optional.altivec` = 1; then
ax_cv_have_altivec_old_ext=yes
fi
fi
])
if test "$ax_cv_have_altivec_old_ext" = yes; then
AC_DEFINE(HAVE_ALTIVEC,,[Support Altivec instructions])
AX_CHECK_COMPILE_FLAG(-faltivec, SIMD_FLAGS="$SIMD_FLAGS -faltivec", [])
fi
AC_CACHE_CHECK([whether altivec is supported], [ax_cv_have_altivec_ext],
[
if test `LD_SHOW_AUXV=1 /bin/true 2>/dev/null|grep -c altivec` != 0; then
ax_cv_have_altivec_ext=yes
fi
])
if test "$ax_cv_have_altivec_ext" = yes; then
AC_DEFINE(HAVE_ALTIVEC,,[Support Altivec instructions])
AX_CHECK_COMPILE_FLAG(-maltivec, SIMD_FLAGS="$SIMD_FLAGS -maltivec", [])
fi
AC_CACHE_CHECK([whether vsx is supported], [ax_cv_have_vsx_ext],
[
if test `LD_SHOW_AUXV=1 /bin/true 2>/dev/null|grep -c vsx` != 0; then
ax_cv_have_vsx_ext=yes
fi
])
if test "$ax_cv_have_vsx_ext" = yes; then
AC_DEFINE(HAVE_VSX,,[Support VSX instructions])
AX_CHECK_COMPILE_FLAG(-mvsx, SIMD_FLAGS="$SIMD_FLAGS -mvsx", [])
fi
;;
i[[3456]]86*|x86_64*|amd64*)
AC_REQUIRE([AX_GCC_X86_CPUID])
AC_REQUIRE([AX_GCC_X86_CPUID_COUNT])
AC_REQUIRE([AX_GCC_X86_AVX_XGETBV])
eax_cpuid0=0
AX_GCC_X86_CPUID(0x00000000)
if test "$ax_cv_gcc_x86_cpuid_0x00000000" != "unknown";
then
eax_cpuid0=`echo $ax_cv_gcc_x86_cpuid_0x00000000 | cut -d ":" -f 1`
fi
eax_cpuid80000000=0
AX_GCC_X86_CPUID(0x80000000)
if test "$ax_cv_gcc_x86_cpuid_0x80000000" != "unknown";
then
eax_cpuid80000000=`echo $ax_cv_gcc_x86_cpuid_0x80000000 | cut -d ":" -f 1`
fi
ecx_cpuid1=0
edx_cpuid1=0
if test "$((0x$eax_cpuid0))" -ge 1 ; then
AX_GCC_X86_CPUID(0x00000001)
if test "$ax_cv_gcc_x86_cpuid_0x00000001" != "unknown";
then
ecx_cpuid1=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 3`
edx_cpuid1=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 4`
fi
fi
ebx_cpuid7=0
ecx_cpuid7=0
if test "$((0x$eax_cpuid0))" -ge 7 ; then
AX_GCC_X86_CPUID_COUNT(0x00000007, 0x00)
if test "$ax_cv_gcc_x86_cpuid_0x00000007" != "unknown";
then
ebx_cpuid7=`echo $ax_cv_gcc_x86_cpuid_0x00000007 | cut -d ":" -f 2`
ecx_cpuid7=`echo $ax_cv_gcc_x86_cpuid_0x00000007 | cut -d ":" -f 3`
fi
fi
ecx_cpuid80000001=0
edx_cpuid80000001=0
if test "$((0x$eax_cpuid80000000))" -ge "$((0x80000001))" ; then
AX_GCC_X86_CPUID(0x80000001)
if test "$ax_cv_gcc_x86_cpuid_0x80000001" != "unknown";
then
ecx_cpuid80000001=`echo $ax_cv_gcc_x86_cpuid_0x80000001 | cut -d ":" -f 3`
edx_cpuid80000001=`echo $ax_cv_gcc_x86_cpuid_0x80000001 | cut -d ":" -f 4`
fi
fi
AC_CACHE_VAL([ax_cv_have_mmx_os_support_ext],
[
ax_cv_have_mmx_os_support_ext=yes
])
ax_cv_have_none_os_support_ext=yes
AC_CACHE_VAL([ax_cv_have_sse_os_support_ext],
[
ax_cv_have_sse_os_support_ext=no,
if test "$((0x$edx_cpuid1>>25&0x01))" = 1; then
AC_LANG_PUSH([C])
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <signal.h>
#include <stdlib.h>
/* No way at ring1 to ring3 in protected mode to check the CR0 and CR4
control registers directly. Execute an SSE instruction.
If it raises SIGILL then OS doesn't support SSE based instructions */
void sig_handler(int signum){ exit(1); }
int main(){
signal(SIGILL, sig_handler);
/* SSE instruction xorps %xmm0,%xmm0 */
__asm__ __volatile__ (".byte 0x0f, 0x57, 0xc0");
return 0;
}]])],
[ax_cv_have_sse_os_support_ext=yes],
[ax_cv_have_sse_os_support_ext=no],
[ax_cv_have_sse_os_support_ext=no])
AC_LANG_POP([C])
fi
])
xgetbv_eax=0
if test "$((0x$ecx_cpuid1>>28&0x01))" = 1; then
AX_GCC_X86_AVX_XGETBV(0x00000000)
if test x"$ax_cv_gcc_x86_avx_xgetbv_0x00000000" != x"unknown"; then
xgetbv_eax=`echo $ax_cv_gcc_x86_avx_xgetbv_0x00000000 | cut -d ":" -f 1`
fi
AC_CACHE_VAL([ax_cv_have_avx_os_support_ext],
[
ax_cv_have_avx_os_support_ext=no
if test "$((0x$ecx_cpuid1>>27&0x01))" = 1; then
if test "$((0x$xgetbv_eax&0x6))" = 6; then
ax_cv_have_avx_os_support_ext=yes
fi
fi
])
fi
AC_CACHE_VAL([ax_cv_have_avx512_os_support_ext],
[
ax_cv_have_avx512_os_support_ext=no
if test "$ax_cv_have_avx_os_support_ext" = yes; then
if test "$((0x$xgetbv_eax&0xe6))" = "$((0xe6))"; then
ax_cv_have_avx512_os_support_ext=yes
fi
fi
])
for ac_instr_info dnl
in "none;rdrnd;RDRND;ecx_cpuid1,30;-mrdrnd;HAVE_RDRND;CPUEXT_FLAGS" dnl
"none;bmi1;BMI1;ebx_cpuid7,3;-mbmi;HAVE_BMI1;CPUEXT_FLAGS" dnl
"none;bmi2;BMI2;ebx_cpuid7,8;-mbmi2;HAVE_BMI2;CPUEXT_FLAGS" dnl
"none;adx;ADX;ebx_cpuid7,19;-madx;HAVE_ADX;CPUEXT_FLAGS" dnl
"none;mpx;MPX;ebx_cpuid7,14;-mmpx;HAVE_MPX;CPUEXT_FLAGS" dnl
"none;prefetchwt1;PREFETCHWT1;ecx_cpuid7,0;-mprefetchwt1;HAVE_PREFETCHWT1;CPUEXT_FLAGS" dnl
"none;abm;ABM;ecx_cpuid80000001,5;-mabm;HAVE_ABM;CPUEXT_FLAGS" dnl
"mmx;mmx;MMX;edx_cpuid1,23;-mmmx;HAVE_MMX;SIMD_FLAGS" dnl
"sse;sse;SSE;edx_cpuid1,25;-msse;HAVE_SSE;SIMD_FLAGS" dnl
"sse;sse2;SSE2;edx_cpuid1,26;-msse2;HAVE_SSE2;SIMD_FLAGS" dnl
"sse;sse3;SSE3;ecx_cpuid1,1;-msse3;HAVE_SSE3;SIMD_FLAGS" dnl
"sse;ssse3;SSSE3;ecx_cpuid1,9;-mssse3;HAVE_SSSE3;SIMD_FLAGS" dnl
"sse;sse41;SSE4.1;ecx_cpuid1,19;-msse4.1;HAVE_SSE4_1;SIMD_FLAGS" dnl
"sse;sse42;SSE4.2;ecx_cpuid1,20;-msse4.2;HAVE_SSE4_2;SIMD_FLAGS" dnl
"sse;sse4a;SSE4a;ecx_cpuid80000001,6;-msse4a;HAVE_SSE4a;SIMD_FLAGS" dnl
"sse;sha;SHA;ebx_cpuid7,29;-msha;HAVE_SHA;SIMD_FLAGS" dnl
"sse;aes;AES;ecx_cpuid1,25;-maes;HAVE_AES;SIMD_FLAGS" dnl
"avx;avx;AVX;ecx_cpuid1,28;-mavx;HAVE_AVX;SIMD_FLAGS" dnl
"avx;fma3;FMA3;ecx_cpuid1,12;-mfma;HAVE_FMA3;SIMD_FLAGS" dnl
"avx;fma4;FMA4;ecx_cpuid80000001,16;-mfma4;HAVE_FMA4;SIMD_FLAGS" dnl
"avx;xop;XOP;ecx_cpuid80000001,11;-mxop;HAVE_XOP;SIMD_FLAGS" dnl
"avx;avx2;AVX2;ebx_cpuid7,5;-mavx2;HAVE_AVX2;SIMD_FLAGS" dnl
"avx512;avx512f;AVX512-F;ebx_cpuid7,16;-mavx512f;HAVE_AVX512_F;SIMD_FLAGS" dnl
"avx512;avx512cd;AVX512-CD;ebx_cpuid7,28;-mavx512cd;HAVE_AVX512_CD;SIMD_FLAGS" dnl
"avx512;avx512pf;AVX512-PF;ebx_cpuid7,26;-mavx512pf;HAVE_AVX512_PF;SIMD_FLAGS" dnl
"avx512;avx512er;AVX512-ER;ebx_cpuid7,27;-mavx512er;HAVE_AVX512_ER;SIMD_FLAGS" dnl
"avx512;avx512vl;AVX512-VL;ebx_cpuid7,31;-mavx512vl;HAVE_AVX512_VL;SIMD_FLAGS" dnl
"avx512;avx512bw;AVX512-BW;ebx_cpuid7,30;-mavx512bw;HAVE_AVX512_BW;SIMD_FLAGS" dnl
"avx512;avx512dq;AVX512-DQ;ebx_cpuid7,17;-mavx512dq;HAVE_AVX512_DQ;SIMD_FLAGS" dnl
"avx512;avx512ifma;AVX512-IFMA;ebx_cpuid7,21;-mavx512ifma;HAVE_AVX512_IFMA;SIMD_FLAGS" dnl
"avx512;avx512vbmi;AVX512-VBMI;ecx_cpuid7,1;-mavx512vbmi;HAVE_AVX512_VBMI;SIMD_FLAGS" dnl
#
do ac_instr_os_support=$(eval echo \$ax_cv_have_$(echo $ac_instr_info | cut -d ";" -f 1)_os_support_ext)
ac_instr_acvar=$(echo $ac_instr_info | cut -d ";" -f 2)
ac_instr_shortname=$(echo $ac_instr_info | cut -d ";" -f 3)
ac_instr_chk_loc=$(echo $ac_instr_info | cut -d ";" -f 4)
ac_instr_chk_reg=0x$(eval echo \$$(echo $ac_instr_chk_loc | cut -d "," -f 1))
ac_instr_chk_bit=$(echo $ac_instr_chk_loc | cut -d "," -f 2)
ac_instr_compiler_flags=$(echo $ac_instr_info | cut -d ";" -f 5)
ac_instr_have_define=$(echo $ac_instr_info | cut -d ";" -f 6)
ac_instr_flag_type=$(echo $ac_instr_info | cut -d ";" -f 7)
AC_CACHE_CHECK([whether ${ac_instr_shortname} is supported by the processor], [ax_cv_have_${ac_instr_acvar}_cpu_ext],
[
eval ax_cv_have_${ac_instr_acvar}_cpu_ext=no
if test "$((${ac_instr_chk_reg}>>${ac_instr_chk_bit}&0x01))" = 1 ; then
eval ax_cv_have_${ac_instr_acvar}_cpu_ext=yes
fi
])
if test x"$(eval echo \$ax_cv_have_${ac_instr_acvar}_cpu_ext)" = x"yes"; then
AC_CACHE_CHECK([whether ${ac_instr_shortname} is supported by the processor and OS], [ax_cv_have_${ac_instr_acvar}_ext],
[
eval ax_cv_have_${ac_instr_acvar}_ext=no
if test x"${ac_instr_os_support}" = x"yes"; then
eval ax_cv_have_${ac_instr_acvar}_ext=yes
fi
])
if test "$(eval echo \$ax_cv_have_${ac_instr_acvar}_ext)" = yes; then
AX_CHECK_COMPILE_FLAG(${ac_instr_compiler_flags}, eval ax_cv_support_${ac_instr_acvar}_ext=yes,
eval ax_cv_support_${ac_instr_acvar}_ext=no)
if test x"$(eval echo \$ax_cv_support_${ac_instr_acvar}_ext)" = x"yes"; then
eval ${ac_instr_flag_type}=\"\$${ac_instr_flag_type} ${ac_instr_compiler_flags}\"
AC_DEFINE_UNQUOTED([${ac_instr_have_define}])
else
AC_MSG_WARN([Your processor and OS supports ${ac_instr_shortname} instructions but not your compiler, can you try another compiler?])
fi
else
if test x"${ac_instr_os_support}" = x"no"; then
AC_CACHE_VAL(ax_cv_support_${ac_instr_acvar}_ext, eval ax_cv_support_${ac_instr_acvar}_ext=no)
AC_MSG_WARN([Your processor supports ${ac_instr_shortname}, but your OS doesn't])
fi
fi
else
AC_CACHE_VAL(ax_cv_have_${ac_instr_acvar}_ext, eval ax_cv_have_${ac_instr_acvar}_ext=no)
AC_CACHE_VAL(ax_cv_support_${ac_instr_acvar}_ext, eval ax_cv_support_${ac_instr_acvar}_ext=no)
fi
done
;;
esac
AH_TEMPLATE([HAVE_RDRND],[Define to 1 to support Digital Random Number Generator])
AH_TEMPLATE([HAVE_BMI1],[Define to 1 to support Bit Manipulation Instruction Set 1])
AH_TEMPLATE([HAVE_BMI2],[Define to 1 to support Bit Manipulation Instruction Set 2])
AH_TEMPLATE([HAVE_ADX],[Define to 1 to support Multi-Precision Add-Carry Instruction Extensions])
AH_TEMPLATE([HAVE_MPX],[Define to 1 to support Memory Protection Extensions])
AH_TEMPLATE([HAVE_PREFETCHWT1],[Define to 1 to support Prefetch Vector Data Into Caches WT1])
AH_TEMPLATE([HAVE_ABM],[Define to 1 to support Advanced Bit Manipulation])
AH_TEMPLATE([HAVE_MMX],[Define to 1 to support Multimedia Extensions])
AH_TEMPLATE([HAVE_SSE],[Define to 1 to support Streaming SIMD Extensions])
AH_TEMPLATE([HAVE_SSE2],[Define to 1 to support Streaming SIMD Extensions])
AH_TEMPLATE([HAVE_SSE3],[Define to 1 to support Streaming SIMD Extensions 3])
AH_TEMPLATE([HAVE_SSSE3],[Define to 1 to support Supplemental Streaming SIMD Extensions 3])
AH_TEMPLATE([HAVE_SSE4_1],[Define to 1 to support Streaming SIMD Extensions 4.1])
AH_TEMPLATE([HAVE_SSE4_2],[Define to 1 to support Streaming SIMD Extensions 4.2])
AH_TEMPLATE([HAVE_SSE4a],[Define to 1 to support AMD Streaming SIMD Extensions 4a])
AH_TEMPLATE([HAVE_SHA],[Define to 1 to support Secure Hash Algorithm Extension])
AH_TEMPLATE([HAVE_AES],[Define to 1 to support Advanced Encryption Standard New Instruction Set (AES-NI)])
AH_TEMPLATE([HAVE_AVX],[Define to 1 to support Advanced Vector Extensions])
AH_TEMPLATE([HAVE_FMA3],[Define to 1 to support Fused Multiply-Add Extensions 3])
AH_TEMPLATE([HAVE_FMA4],[Define to 1 to support Fused Multiply-Add Extensions 4])
AH_TEMPLATE([HAVE_XOP],[Define to 1 to support eXtended Operations Extensions])
AH_TEMPLATE([HAVE_AVX2],[Define to 1 to support Advanced Vector Extensions 2])
AH_TEMPLATE([HAVE_AVX512_F],[Define to 1 to support AVX-512 Foundation Extensions])
AH_TEMPLATE([HAVE_AVX512_CD],[Define to 1 to support AVX-512 Conflict Detection Instructions])
AH_TEMPLATE([HAVE_AVX512_PF],[Define to 1 to support AVX-512 Conflict Prefetch Instructions])
AH_TEMPLATE([HAVE_AVX512_ER],[Define to 1 to support AVX-512 Exponential & Reciprocal Instructions])
AH_TEMPLATE([HAVE_AVX512_VL],[Define to 1 to support AVX-512 Vector Length Extensions])
AH_TEMPLATE([HAVE_AVX512_BW],[Define to 1 to support AVX-512 Byte and Word Instructions])
AH_TEMPLATE([HAVE_AVX512_DQ],[Define to 1 to support AVX-512 Doubleword and Quadword Instructions])
AH_TEMPLATE([HAVE_AVX512_IFMA],[Define to 1 to support AVX-512 Integer Fused Multiply Add Instructions])
AH_TEMPLATE([HAVE_AVX512_VBMI],[Define to 1 to support AVX-512 Vector Byte Manipulation Instructions])
AC_SUBST(SIMD_FLAGS)
AC_SUBST(CPUEXT_FLAGS)
])

View file

@ -0,0 +1,79 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_avx_xgetbv.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_X86_AVX_XGETBV
#
# DESCRIPTION
#
# On later x86 processors with AVX SIMD support, with gcc or a compiler
# that has a compatible syntax for inline assembly instructions, run a
# small program that executes the xgetbv instruction with input OP. This
# can be used to detect if the OS supports AVX instruction usage.
#
# On output, the values of the eax and edx registers are stored as
# hexadecimal strings as "eax:edx" in the cache variable
# ax_cv_gcc_x86_avx_xgetbv.
#
# If the xgetbv instruction fails (because you are running a
# cross-compiler, or because you are not using gcc, or because you are on
# a processor that doesn't have this instruction),
# ax_cv_gcc_x86_avx_xgetbv_OP is set to the string "unknown".
#
# This macro mainly exists to be used in AX_EXT.
#
# LICENSE
#
# Copyright (c) 2013 Michael Petch <mpetch@capp-sysware.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 3
AC_DEFUN([AX_GCC_X86_AVX_XGETBV],
[AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
AC_CACHE_CHECK(for x86-AVX xgetbv $1 output, ax_cv_gcc_x86_avx_xgetbv_$1,
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int op = $1, eax, edx;
FILE *f;
/* Opcodes for xgetbv */
__asm__ __volatile__ (".byte 0x0f, 0x01, 0xd0"
: "=a" (eax), "=d" (edx)
: "c" (op));
f = fopen("conftest_xgetbv", "w"); if (!f) return 1;
fprintf(f, "%x:%x\n", eax, edx);
fclose(f);
return 0;
])],
[ax_cv_gcc_x86_avx_xgetbv_$1=`cat conftest_xgetbv`; rm -f conftest_xgetbv],
[ax_cv_gcc_x86_avx_xgetbv_$1=unknown; rm -f conftest_xgetbv],
[ax_cv_gcc_x86_avx_xgetbv_$1=unknown])])
AC_LANG_POP([C])
])

89
m4/ax_gcc_x86_cpuid.m4 Normal file
View file

@ -0,0 +1,89 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_X86_CPUID(OP)
# AX_GCC_X86_CPUID_COUNT(OP, COUNT)
#
# DESCRIPTION
#
# On Pentium and later x86 processors, with gcc or a compiler that has a
# compatible syntax for inline assembly instructions, run a small program
# that executes the cpuid instruction with input OP. This can be used to
# detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT
# parameter that gets passed into register ECX before calling cpuid.
#
# On output, the values of the eax, ebx, ecx, and edx registers are stored
# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
# ax_cv_gcc_x86_cpuid_OP.
#
# If the cpuid instruction fails (because you are running a
# cross-compiler, or because you are not using gcc, or because you are on
# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
# is set to the string "unknown".
#
# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
# Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 10
AC_DEFUN([AX_GCC_X86_CPUID],
[AX_GCC_X86_CPUID_COUNT($1, 0)
])
AC_DEFUN([AX_GCC_X86_CPUID_COUNT],
[AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int op = $1, level = $2, eax, ebx, ecx, edx;
FILE *f;
__asm__ __volatile__ ("xchg %%ebx, %1\n"
"cpuid\n"
"xchg %%ebx, %1\n"
: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
: "a" (op), "2" (level));
f = fopen("conftest_cpuid", "w"); if (!f) return 1;
fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
fclose(f);
return 0;
])],
[ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown])])
AC_LANG_POP([C])
])

51
m4/ax_prepend_flag.m4 Normal file
View file

@ -0,0 +1,51 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_prepend_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PREPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is added to the front of the FLAGS-VARIABLE shell variable, with a
# space added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_APPEND_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
# Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_PREPEND_FLAG],
[dnl
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
AS_VAR_SET_IF(FLAGS,[
AS_CASE([" AS_VAR_GET(FLAGS) "],
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
[
FLAGS="$1 $FLAGS"
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
],
[
AS_VAR_SET(FLAGS,[$1])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_PREPEND_FLAG

507
m4/ax_pthread.m4 Normal file
View file

@ -0,0 +1,507 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also to link with them as well. For example, you might link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threaded programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 27
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_SED])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on Tru64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CC="$CC"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = "xno"; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
CC="$ax_pthread_save_CC"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items with a "," contain both
# C compiler flags (before ",") and linker flags (after ","). Other items
# starting with a "-" are C compiler flags, and remaining items are
# library names, except for "none" which indicates that we try without
# any flags at all, and "pthread-config" which is a program returning
# the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
# (Note: HP C rejects this with "bad form for `-t' option")
# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads and
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
# is present but should not be used directly; and before -mthreads,
# because the compiler interprets this as "-mt" + "-hreads")
# -mthreads: Mingw32/gcc, Lynx/gcc
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case $host_os in
freebsd*)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
;;
hpux*)
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
# multi-threading and also sets -lpthread."
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
;;
openedition*)
# IBM z/OS requires a feature-test macro to be defined in order to
# enable POSIX threads at all, so give the user a hint if this is
# not set. (We don't define these ourselves, as they can affect
# other portions of the system API in unpredictable ways.)
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
[
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
AX_PTHREAD_ZOS_MISSING
# endif
],
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
;;
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (N.B.: The stubs are missing
# pthread_cleanup_push, or rather a function called by this macro,
# so we could check for that, but who knows whether they'll stub
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
;;
esac
# Are we compiling with Clang?
AC_CACHE_CHECK([whether $CC is Clang],
[ax_cv_PTHREAD_CLANG],
[ax_cv_PTHREAD_CLANG=no
# Note that Autoconf sets GCC=yes for Clang as well as GCC
if test "x$GCC" = "xyes"; then
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
# if defined(__clang__) && defined(__llvm__)
AX_PTHREAD_CC_IS_CLANG
# endif
],
[ax_cv_PTHREAD_CLANG=yes])
fi
])
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
# Note that for GCC and Clang -pthread generally implies -lpthread,
# except when -nostdlib is passed.
# This is problematic using libtool to build C++ shared libraries with pthread:
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
# To solve this, first try -pthread together with -lpthread for GCC
AS_IF([test "x$GCC" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
AS_IF([test "x$ax_pthread_clang" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread"])
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
# correctly enabled
case $host_os in
darwin* | hpux* | linux* | osf* | solaris*)
ax_pthread_check_macro="_REENTRANT"
;;
aix*)
ax_pthread_check_macro="_THREAD_SAFE"
;;
*)
ax_pthread_check_macro="--"
;;
esac
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
if test "x$ax_pthread_ok" = "xno"; then
for ax_pthread_try_flag in $ax_pthread_flags; do
case $ax_pthread_try_flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
*,*)
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
PTHREAD_CFLAGS="$ax_pthread_try_flag"
;;
pthread-config)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
PTHREAD_LIBS="-l$ax_pthread_try_flag"
;;
esac
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
# if $ax_pthread_check_cond
# error "$ax_pthread_check_macro must be defined"
# endif
static void *some_global = NULL;
static void routine(void *a)
{
/* To avoid any unused-parameter or
unused-but-set-parameter warning. */
some_global = a;
}
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
AC_MSG_RESULT([$ax_pthread_ok])
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
if test "x$ax_pthread_clang" = "xyes"; then
# Clang takes -pthread; it has never supported any other flag
# (Note 1: This will need to be revisited if a system that Clang
# supports has POSIX threads in a separate library. This tends not
# to be the way of modern systems, but it's conceivable.)
# (Note 2: On some systems, notably Darwin, -pthread is not needed
# to get POSIX threads support; the API is always present and
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
# during compilation"). They expect -pthread to be passed in only
# when source code is being compiled.
#
# Problem is, this is at odds with the way Automake and most other
# C build frameworks function, which is that the same flags used in
# compilation (CFLAGS) are also used in linking. Many systems
# supported by AX_PTHREAD require exactly this for POSIX threads
# support, and in fact it is often not straightforward to specify a
# flag that is used only in the compilation phase and not in
# linking. Such a scenario is extremely rare in practice.
#
# Even though use of the -pthread flag in linking would only print
# a warning, this can be a nuisance for well-run software projects
# that build with -Werror. So if the active version of Clang has
# this misfeature, we search for an option to squash it.
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
# Create an alternate version of $ac_link that compiles and
# links in two steps (.c -> .o, .o -> exe) instead of one
# (.c -> exe), because the warning occurs only in the second
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
ac_link="$ax_pthread_save_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[ac_link="$ax_pthread_2step_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[break])
])
done
ac_link="$ax_pthread_save_ac_link"
CFLAGS="$ax_pthread_save_CFLAGS"
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
])
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
no | unknown) ;;
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
esac
fi # $ax_pthread_clang = yes
# Various other checks:
if test "x$ax_pthread_ok" = "xyes"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_CACHE_CHECK([for joinable pthread attribute],
[ax_cv_PTHREAD_JOINABLE_ATTR],
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $ax_pthread_attr; return attr /* ; */])],
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
[])
done
])
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
[$ax_cv_PTHREAD_JOINABLE_ATTR],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
ax_pthread_joinable_attr_defined=yes
])
AC_CACHE_CHECK([whether more special flags are required for pthreads],
[ax_cv_PTHREAD_SPECIAL_FLAGS],
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
case $host_os in
solaris*)
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
;;
esac
])
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
test "x$ax_pthread_special_flags_added" != "xyes"],
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
ax_pthread_special_flags_added=yes])
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;
return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
ax_pthread_prio_inherit_defined=yes
])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
# More AIX lossage: compile with *_r variant
if test "x$GCC" != "xyes"; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "x$ax_pthread_ok" = "xyes"; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD

37
m4/ax_require_defined.m4 Normal file
View file

@ -0,0 +1,37 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_REQUIRE_DEFINED(MACRO)
#
# DESCRIPTION
#
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
# been defined and thus are available for use. This avoids random issues
# where a macro isn't expanded. Instead the configure script emits a
# non-fatal:
#
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
#
# It's like AC_REQUIRE except it doesn't expand the required macro.
#
# Here's an example:
#
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
#
# LICENSE
#
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
])dnl AX_REQUIRE_DEFINED

27
m4/dl.sh Executable file
View file

@ -0,0 +1,27 @@
#!/bin/sh -e
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
m4_files="ax_append_flag.m4 ax_cflags_warn_all.m4 ax_ext.m4 ax_pthread.m4
ax_require_defined.m4 ax_gcc_x86_avx_xgetbv.m4 ax_gcc_x86_cpuid.m4
ax_check_compile_flag.m4 ax_prepend_flag.m4 ax_compiler_vendor.m4"
for ax in $m4_files; do
rm -f "$ax"
wget -O "$ax" "http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/$ax"
done

168
rpm/dnsjit.spec Normal file
View file

@ -0,0 +1,168 @@
Name: dnsjit
Version: 1.1.0
Release: 1%{?dist}
Summary: Engine for capturing, parsing and replaying DNS
Group: Productivity/Networking/DNS/Utilities
License: GPL-3.0-or-later
URL: https://github.com/DNS-OARC/dnsjit
# Source needs to be generated by dist-tools/create-source-packages, see
# https://github.com/jelu/dist-tools
Source0: https://github.com/DNS-OARC/dnsjit/archive/v%{version}.tar.gz?/%{name}_%{version}.orig.tar.gz
BuildRequires: libpcap-devel
%if 0%{?suse_version} || 0%{?sle_version}
BuildRequires: moonjit-devel >= 2.0.0
%else
BuildRequires: luajit-devel >= 2.0.0
%endif
BuildRequires: lmdb-devel
BuildRequires: ck-devel
BuildRequires: gnutls-devel
BuildRequires: libuv-devel
BuildRequires: libnghttp2-devel
BuildRequires: autoconf >= 2.64
BuildRequires: automake
BuildRequires: libtool
%description
dnsjit is a combination of parts taken from dsc, dnscap, drool,
and put together around Lua to create a script-based engine for easy
capturing, parsing and statistics gathering of DNS message while also
providing facilities for replaying DNS traffic.
%prep
%setup -q -n %{name}_%{version}
%build
sh autogen.sh
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%check
make test
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{_bindir}/*
%{_datadir}/doc/*
%{_mandir}/man1/*
%{_mandir}/man3/*
%changelog
* Wed Feb 03 2021 Jerry Lundström <lundstrom.jerry@gmail.com> 1.1.0-1
- Release 1.1.0
* This releases adds a new module for handling Base64 URLs and new calls
for error handling and opening PCAPs using file descriptors, along with
a bug fix in `lib.getopt` and other changes.
* The `dnssim` module has also gotten its own version and changelog, this
is to prepare it for being moved outside of dnsjit's repository in the
future.
* New modules, calls, features:
- New `lib.base64url`: Utility library to convert data to base64url format
- `core.log`: New call `Log.errstr()`: Convert error number to its text representation
- `input.fpcap`: New call `Fpcap.openfp()`: Open a PCAP file for processing using a file descriptor, for example `io.stdin`
- `output.dnssim`: Support for DNS-over-HTTPS
* Bug fixes:
- `lib.getopt`: Fix bug where `-` and `--` could not be used as arguments to options
* Other changes:
- Fix typo in configure help text
- Add coverage
- `filter.ipsplit`: Extend PRNG modulus to 2^31, new implementation is the same as glibc's `rand()`
- `lib.ip`: Fix typo in documentation
- `output.dnssim`:
- This module now has it's own changelog
- Updated to v20210129
- Depend on libhttp2 for dnssim DNS-over-HTTPS capabilities
- `output.pcap`: Log libpcap error when failing to open
- SUSE packages now depend on moonjit because of lack of LuaJIT support
* Commits:
d001ccb m4
4b63bce output/dnssim: add changelog
7355810 output/dnssim: add version checks
95fa6a9 input pcap/fpcap, getopt
99c3d9f test/test_ipsplit: update to use new PRNG
3235b09 filter/ipsplit: extend PRNG modulus to 2^31
8ff81a0 fixup! input.fpcap: filename "-" reads from stdin
63cf0a4 output/dnssim: fix regression in DoH GET
367d0b8 input.pcap: document stdin feature of open_offline()
8d94504 input.fpcap: filename "-" reads from stdin
617058e getopt: accept singleton - also as option value
7d7f17c output/dnssim: unify failed to bind error messages
bdf1517 output/dnssim: add IPv4 support
15a21da Sonarcloud
ceeea1d SUSE
1fc3c82 PR179
2f5d38f output/dnssim: allow user-set instance log name
b036c68 Info
0af1ffb Travis, configure
49bdc08 output/dnssim: implement udp(tcp_fallback) method
b4f9cf9 man: update gitlab.labs.nic.cz to gitlab.nic.cz
45b977d output/dnssim: update man page
4184090 output/dnssim: https2 - fix connection closure issues
342f33e output/dnssim: https2 - omit closing connection inside callback
67a76d5 output/dnssim: handle all states when closing connection
41f04d8 output/dnssim: document importance of conn state enum ordering
795ab6f output/dnssim: tls - fix handling of CONGESTED connections
8792b32 output/dnssim: match QUESTION section of received responses
3a88f5b Coverage
4f611c8 dnssim
6e35d5b Compile
63faa44 README, format code, man-page
925f85e lib: add missing man reference
9239087 output/dnssim: fix man formatting
bd7bee5 fix lua log levels
4083efd output/dnssim: fix doc typo
24c22b8 lib/base64url: add lua bindings
69be2a1 core/log: add errstr() utility function
0c14d74 output/dnssim: improve https2() documentation and behaviour
f74e19c output/pcap: log errors when opening output PCAP
6fe699a output/dnssim: cleanup and nitpicks
96db8a9 output/https2: handle max_concurrent_streams similar to nghttp2
15ea609 output/dnssim: https2 - ensure uri authority is always set
fad3ed6 output/dnssim: https2 - fix some TODOs
0bee6d8 output/dnssim: https2 - lua documentation
e83e010 output/dnssim: https2 - implement GET method
b553e0f output/dnssim: https2 - configure method
a431a0d contrib: add base64url functions
c753097 output/dnssim: https2 - set default concurrent stream limit
d49f275 output/dnssim: https2 - track number of open streams
2f7217f output/dnssim: https2 - improve data send edge cases
c0abebc output/dnssim: https2 - return correct error code on send failure
5b1f6c3 output/dnssim: conn - avoid assert when tearing down failed connections
5c42266 output/dnssim: exit when file descriptors run out
1ab2ab6 output/dnssim: https2 - additional asserts to detect invalid data
4424eb3 output/dnssim: https2 - check response code
303f2cd output/dnssim: https2 - improve QID mismatch debug msg
86e3761 output/dnssim: https2 - bugfixes
4a52f47 output/dnssim: https2 - use more consistent code style for pointers
c8d853e output/dnssim: conn - fix potential memory leak
3e6038b output/dnssim: https2 - enable zero-ing out msgid
712634c output/dnssim: https2 - properly match dnsmsg to query from http request
5abe943 output/dnssim: https2 - free memory on teardown
39a9e9e output/dnssim: https2 - initial implementation
058aee2 output/dnssim: https2 - initialize and setup session
85eb4a3 output/dnssim: https2 - add libnghttp2 dependency
6712bd6 output/dnssim: https2 - add skeleton
* Thu Jul 23 2020 Jerry Lundström <lundstrom.jerry@gmail.com> 1.0.0-1
- Release 1.0.0
* Tue Jun 04 2019 Jerry Lundström <lundstrom.jerry@gmail.com> 0.9.8-1
- Alpha release 0.9.8
* Fri Jan 25 2019 Jerry Lundström <lundstrom.jerry@gmail.com> 0.9.7-1
- Alpha release 0.9.7
* Wed Aug 01 2018 Jerry Lundström <lundstrom.jerry@gmail.com> 0.9.6-1
- Alpha release 0.9.6

280
src/Makefile.am Normal file
View file

@ -0,0 +1,280 @@
# Copyright (c) 2018-2021, OARC, Inc.
# All rights reserved.
#
# This file is part of dnsjit.
#
# dnsjit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = *.gcda *.gcno *.gcov
SUBDIRS = test
AM_CFLAGS = -Werror=attributes \
-I$(srcdir) \
-I$(top_srcdir) \
$(SIMD_FLAGS) $(CPUEXT_FLAGS) \
$(PTHREAD_CFLAGS) \
$(luajit_CFLAGS) \
$(libuv_CFLAGS) \
$(libnghttp2_CFLAGS)
EXTRA_DIST = gen-manpage.lua gen-compat.lua gen-errno.sh dnsjit.1in
BUILT_SOURCES = core/compat.hh core/log_errstr.c
bin_PROGRAMS = dnsjit
dnsjit_SOURCES = dnsjit.c globals.c
dist_dnsjit_SOURCES = core.lua lib.lua input.lua filter.lua globals.h \
output.lua
lua_hobjects = core/compat.luaho
lua_objects = core.luao lib.luao input.luao filter.luao output.luao
dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS) $(libuv_LIBS) $(libnghttp2_LIBS)
# C source and headers
dnsjit_SOURCES += core/channel.c core/compat.c core/log.c core/object.c core/object/dns.c core/object/ether.c core/object/gre.c core/object/icmp6.c core/object/icmp.c core/object/ieee802.c core/object/ip6.c core/object/ip.c core/object/linuxsll.c core/object/loop.c core/object/null.c core/object/payload.c core/object/pcap.c core/object/tcp.c core/object/udp.c core/producer.c core/receiver.c core/thread.c filter/copy.c filter/ipsplit.c filter/layer.c filter/split.c filter/timing.c input/fpcap.c input/mmpcap.c input/pcap.c input/zero.c lib/base64url.c lib/clock.c lib/trie.c output/dnscli.c output/dnssim.c output/dnssim/common.c output/dnssim/connection.c output/dnssim/https2.c output/dnssim/tcp.c output/dnssim/tls.c output/dnssim/udp.c output/null.c output/pcap.c output/respdiff.c output/tcpcli.c output/tlscli.c output/udpcli.c
dist_dnsjit_SOURCES += core/assert.h core/channel.h core/compat.h core/log.h core/object/dns.h core/object/ether.h core/object/gre.h core/object.h core/object/icmp6.h core/object/icmp.h core/object/ieee802.h core/object/ip6.h core/object/ip.h core/object/linuxsll.h core/object/loop.h core/object/null.h core/object/payload.h core/object/pcap.h core/object/tcp.h core/object/udp.h core/producer.h core/receiver.h core/thread.h core/timespec.h filter/copy.h filter/ipsplit.h filter/layer.h filter/split.h filter/timing.h input/fpcap.h input/mmpcap.h input/pcap.h input/zero.h lib/base64url.h lib/clock.h lib/trie.h output/dnscli.h output/dnssim.h output/dnssim/internal.h output/dnssim/ll.h output/null.h output/pcap.h output/respdiff.h output/tcpcli.h output/tlscli.h output/udpcli.h
# Lua headers
dist_dnsjit_SOURCES += core/channel.hh core/log.hh core/object/dns.hh core/object/ether.hh core/object/gre.hh core/object.hh core/object/icmp6.hh core/object/icmp.hh core/object/ieee802.hh core/object/ip6.hh core/object/ip.hh core/object/linuxsll.hh core/object/loop.hh core/object/null.hh core/object/payload.hh core/object/pcap.hh core/object/tcp.hh core/object/udp.hh core/producer.hh core/receiver.hh core/thread.hh core/timespec.hh filter/copy.hh filter/ipsplit.hh filter/layer.hh filter/split.hh filter/timing.hh input/fpcap.hh input/mmpcap.hh input/pcap.hh input/zero.hh lib/base64url.hh lib/clock.hh lib/trie.hh output/dnscli.hh output/dnssim.hh output/null.hh output/pcap.hh output/respdiff.hh output/tcpcli.hh output/tlscli.hh output/udpcli.hh
lua_hobjects += core/channel.luaho core/log.luaho core/object/dns.luaho core/object/ether.luaho core/object/gre.luaho core/object/icmp6.luaho core/object/icmp.luaho core/object/ieee802.luaho core/object/ip6.luaho core/object/ip.luaho core/object/linuxsll.luaho core/object/loop.luaho core/object.luaho core/object/null.luaho core/object/payload.luaho core/object/pcap.luaho core/object/tcp.luaho core/object/udp.luaho core/producer.luaho core/receiver.luaho core/thread.luaho core/timespec.luaho filter/copy.luaho filter/ipsplit.luaho filter/layer.luaho filter/split.luaho filter/timing.luaho input/fpcap.luaho input/mmpcap.luaho input/pcap.luaho input/zero.luaho lib/base64url.luaho lib/clock.luaho lib/trie.luaho output/dnscli.luaho output/dnssim.luaho output/null.luaho output/pcap.luaho output/respdiff.luaho output/tcpcli.luaho output/tlscli.luaho output/udpcli.luaho
# Lua sources
dist_dnsjit_SOURCES += core/channel.lua core/compat.lua core/log.lua core/object/dns/label.lua core/object/dns.lua core/object/dns/q.lua core/object/dns/rr.lua core/object/ether.lua core/object/gre.lua core/object/icmp6.lua core/object/icmp.lua core/object/ieee802.lua core/object/ip6.lua core/object/ip.lua core/object/linuxsll.lua core/object/loop.lua core/object.lua core/object/null.lua core/object/payload.lua core/object/pcap.lua core/objects.lua core/object/tcp.lua core/object/udp.lua core/producer.lua core/receiver.lua core/thread.lua core/timespec.lua filter/copy.lua filter/ipsplit.lua filter/layer.lua filter/split.lua filter/timing.lua input/fpcap.lua input/mmpcap.lua input/pcap.lua input/zero.lua lib/base64url.lua lib/clock.lua lib/getopt.lua lib/ip.lua lib/parseconf.lua lib/trie/iter.lua lib/trie.lua lib/trie/node.lua output/dnscli.lua output/dnssim.lua output/null.lua output/pcap.lua output/respdiff.lua output/tcpcli.lua output/tlscli.lua output/udpcli.lua
lua_objects += core/channel.luao core/compat.luao core/log.luao core/object/dns/label.luao core/object/dns.luao core/object/dns/q.luao core/object/dns/rr.luao core/object/ether.luao core/object/gre.luao core/object/icmp6.luao core/object/icmp.luao core/object/ieee802.luao core/object/ip6.luao core/object/ip.luao core/object/linuxsll.luao core/object/loop.luao core/object.luao core/object/null.luao core/object/payload.luao core/object/pcap.luao core/objects.luao core/object/tcp.luao core/object/udp.luao core/producer.luao core/receiver.luao core/thread.luao core/timespec.luao filter/copy.luao filter/ipsplit.luao filter/layer.luao filter/split.luao filter/timing.luao input/fpcap.luao input/mmpcap.luao input/pcap.luao input/zero.luao lib/base64url.luao lib/clock.luao lib/getopt.luao lib/ip.luao lib/parseconf.luao lib/trie/iter.luao lib/trie.luao lib/trie/node.luao output/dnscli.luao output/dnssim.luao output/null.luao output/pcap.luao output/respdiff.luao output/tcpcli.luao output/tlscli.luao output/udpcli.luao
dnsjit_LDFLAGS = -Wl,-E
dnsjit_LDADD += $(lua_hobjects) $(lua_objects)
CLEANFILES += $(lua_hobjects) $(lua_objects)
man1_MANS = dnsjit.1
CLEANFILES += $(man1_MANS)
man3_MANS = dnsjit.core.3 dnsjit.lib.3 dnsjit.input.3 dnsjit.filter.3 dnsjit.output.3
man3_MANS += dnsjit.core.channel.3 dnsjit.core.compat.3 dnsjit.core.log.3 dnsjit.core.object.3 dnsjit.core.object.dns.3 dnsjit.core.object.dns.label.3 dnsjit.core.object.dns.q.3 dnsjit.core.object.dns.rr.3 dnsjit.core.object.ether.3 dnsjit.core.object.gre.3 dnsjit.core.object.icmp.3 dnsjit.core.object.icmp6.3 dnsjit.core.object.ieee802.3 dnsjit.core.object.ip.3 dnsjit.core.object.ip6.3 dnsjit.core.object.linuxsll.3 dnsjit.core.object.loop.3 dnsjit.core.object.null.3 dnsjit.core.object.payload.3 dnsjit.core.object.pcap.3 dnsjit.core.objects.3 dnsjit.core.object.tcp.3 dnsjit.core.object.udp.3 dnsjit.core.producer.3 dnsjit.core.receiver.3 dnsjit.core.thread.3 dnsjit.core.timespec.3 dnsjit.filter.copy.3 dnsjit.filter.ipsplit.3 dnsjit.filter.layer.3 dnsjit.filter.split.3 dnsjit.filter.timing.3 dnsjit.input.fpcap.3 dnsjit.input.mmpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 dnsjit.lib.base64url.3 dnsjit.lib.clock.3 dnsjit.lib.getopt.3 dnsjit.lib.ip.3 dnsjit.lib.parseconf.3 dnsjit.lib.trie.3 dnsjit.lib.trie.iter.3 dnsjit.lib.trie.node.3 dnsjit.output.dnscli.3 dnsjit.output.dnssim.3 dnsjit.output.null.3 dnsjit.output.pcap.3 dnsjit.output.respdiff.3 dnsjit.output.tcpcli.3 dnsjit.output.tlscli.3 dnsjit.output.udpcli.3
CLEANFILES += *.3in $(man3_MANS)
.lua.luao:
@mkdir -p `dirname "$@"`
$(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed 's%\..*%%' | sed 's%/%.%g'`" -t o "$<" "$@"
.luah.luaho:
@mkdir -p `dirname "$@"`
$(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed 's%\..*%%' | sed 's%/%.%g'`_h" -t o "$<" "$@"
.hh.luah:
@mkdir -p `dirname "$@"`
@echo 'module(...,package.seeall);' > "$@"
@cat "$<" | grep '^//lua:' | sed 's%^//lua:%%' >> "$@"
@echo 'require("ffi").cdef[[' >> "$@"
@cat "$<" | grep -v '^#' >> "$@"
@echo ']]' >> "$@"
.1in.1:
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
< "$<" > "$@"
.3in.3:
sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
-e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
< "$<" > "$@"
if ENABLE_GCOV
gcov-local:
for src in $(dnsjit_SOURCES); do \
gcov -x -l -r -s "$(srcdir)" "$$src"; \
done
endif
core/compat.hh: gen-compat.lua
$(LUAJIT) "$(srcdir)/gen-compat.lua" > "$@"
core/log_errstr.c: gen-errno.sh
"$(srcdir)/gen-errno.sh" > "$@"
dnsjit.core.3in: core.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core.lua" > "$@"
dnsjit.lib.3in: lib.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib.lua" > "$@"
dnsjit.input.3in: input.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input.lua" > "$@"
dnsjit.filter.3in: filter.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter.lua" > "$@"
dnsjit.output.3in: output.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output.lua" > "$@"
dnsjit.core.channel.3in: core/channel.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/channel.lua" > "$@"
dnsjit.core.compat.3in: core/compat.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/compat.lua" > "$@"
dnsjit.core.log.3in: core/log.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/log.lua" > "$@"
dnsjit.core.object.dns.label.3in: core/object/dns/label.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/label.lua" > "$@"
dnsjit.core.object.dns.3in: core/object/dns.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns.lua" > "$@"
dnsjit.core.object.dns.q.3in: core/object/dns/q.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/q.lua" > "$@"
dnsjit.core.object.dns.rr.3in: core/object/dns/rr.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/rr.lua" > "$@"
dnsjit.core.object.ether.3in: core/object/ether.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ether.lua" > "$@"
dnsjit.core.object.gre.3in: core/object/gre.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/gre.lua" > "$@"
dnsjit.core.object.icmp6.3in: core/object/icmp6.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/icmp6.lua" > "$@"
dnsjit.core.object.icmp.3in: core/object/icmp.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/icmp.lua" > "$@"
dnsjit.core.object.ieee802.3in: core/object/ieee802.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ieee802.lua" > "$@"
dnsjit.core.object.ip6.3in: core/object/ip6.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ip6.lua" > "$@"
dnsjit.core.object.ip.3in: core/object/ip.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ip.lua" > "$@"
dnsjit.core.object.linuxsll.3in: core/object/linuxsll.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/linuxsll.lua" > "$@"
dnsjit.core.object.loop.3in: core/object/loop.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/loop.lua" > "$@"
dnsjit.core.object.3in: core/object.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object.lua" > "$@"
dnsjit.core.object.null.3in: core/object/null.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/null.lua" > "$@"
dnsjit.core.object.payload.3in: core/object/payload.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/payload.lua" > "$@"
dnsjit.core.object.pcap.3in: core/object/pcap.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/pcap.lua" > "$@"
dnsjit.core.objects.3in: core/objects.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/objects.lua" > "$@"
dnsjit.core.object.tcp.3in: core/object/tcp.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/tcp.lua" > "$@"
dnsjit.core.object.udp.3in: core/object/udp.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/udp.lua" > "$@"
dnsjit.core.producer.3in: core/producer.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/producer.lua" > "$@"
dnsjit.core.receiver.3in: core/receiver.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/receiver.lua" > "$@"
dnsjit.core.thread.3in: core/thread.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/thread.lua" > "$@"
dnsjit.core.timespec.3in: core/timespec.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/timespec.lua" > "$@"
dnsjit.filter.copy.3in: filter/copy.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/copy.lua" > "$@"
dnsjit.filter.ipsplit.3in: filter/ipsplit.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/ipsplit.lua" > "$@"
dnsjit.filter.layer.3in: filter/layer.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/layer.lua" > "$@"
dnsjit.filter.split.3in: filter/split.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/split.lua" > "$@"
dnsjit.filter.timing.3in: filter/timing.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/timing.lua" > "$@"
dnsjit.input.fpcap.3in: input/fpcap.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/fpcap.lua" > "$@"
dnsjit.input.mmpcap.3in: input/mmpcap.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/mmpcap.lua" > "$@"
dnsjit.input.pcap.3in: input/pcap.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/pcap.lua" > "$@"
dnsjit.input.zero.3in: input/zero.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/zero.lua" > "$@"
dnsjit.lib.base64url.3in: lib/base64url.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/base64url.lua" > "$@"
dnsjit.lib.clock.3in: lib/clock.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/clock.lua" > "$@"
dnsjit.lib.getopt.3in: lib/getopt.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/getopt.lua" > "$@"
dnsjit.lib.ip.3in: lib/ip.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/ip.lua" > "$@"
dnsjit.lib.parseconf.3in: lib/parseconf.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/parseconf.lua" > "$@"
dnsjit.lib.trie.iter.3in: lib/trie/iter.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie/iter.lua" > "$@"
dnsjit.lib.trie.3in: lib/trie.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie.lua" > "$@"
dnsjit.lib.trie.node.3in: lib/trie/node.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie/node.lua" > "$@"
dnsjit.output.dnscli.3in: output/dnscli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/dnscli.lua" > "$@"
dnsjit.output.dnssim.3in: output/dnssim.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/dnssim.lua" > "$@"
dnsjit.output.null.3in: output/null.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/null.lua" > "$@"
dnsjit.output.pcap.3in: output/pcap.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/pcap.lua" > "$@"
dnsjit.output.respdiff.3in: output/respdiff.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/respdiff.lua" > "$@"
dnsjit.output.tcpcli.3in: output/tcpcli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/tcpcli.lua" > "$@"
dnsjit.output.tlscli.3in: output/tlscli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/tlscli.lua" > "$@"
dnsjit.output.udpcli.3in: output/udpcli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/udpcli.lua" > "$@"

45
src/core.lua Normal file
View file

@ -0,0 +1,45 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core
-- Core modules for dnsjit
--
-- Core modules for handling things like logging, DNS messages and
-- receiver/receive functionality.
-- .SS Global Variables
-- The following global variables exists in
-- .IR dnsjit .
-- .TP
-- .B arg
-- A table with the arguments given on the command line, the first will be
-- the path to the
-- .I dnsjit
-- binary, second will be the path to the
-- .IR script .
module(...,package.seeall)
-- dnsjit.core.channel (3),
-- dnsjit.core.compat (3),
-- dnsjit.core.log (3),
-- dnsjit.core.object (3),
-- dnsjit.core.objects (3),
-- dnsjit.core.producer (3),
-- dnsjit.core.receiver (3),
-- dnsjit.core.thread (3),
-- dnsjit.core.timespec (3)
return

46
src/core/assert.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __dnsjit_core_assert_h
#define __dnsjit_core_assert_h
#include "core/log.h"
#define mlassert_self() \
if (!self) \
core_log_fatal(&_log, __FILE__, __LINE__, "self is nil")
#define glassert_self() \
if (!self) \
core_log_fatal(0, __FILE__, __LINE__, "self is nil")
#define lassert(expression, msg...) \
if (!(expression)) \
core_log_fatal(&self->_log, __FILE__, __LINE__, msg)
#define lpassert(expression, msg...) \
if (!(expression)) \
core_log_fatal(self->_log, __FILE__, __LINE__, msg)
#define mlassert(expression, msg...) \
if (!(expression)) \
core_log_fatal(&_log, __FILE__, __LINE__, msg)
#define glassert(expression, msg...) \
if (!(expression)) \
core_log_fatal(0, __FILE__, __LINE__, msg)
#endif

169
src/core/channel.c Normal file
View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/channel.h"
#include "core/assert.h"
#include <sched.h>
static core_log_t _log = LOG_T_INIT("core.channel");
static core_channel_t _defaults = {
LOG_T_INIT_OBJ("core.channel"),
0, { 0 }, 0, 0,
0, 0
};
core_log_t* core_channel_log()
{
return &_log;
}
static inline bool _is_pow2(size_t num)
{
while (num != 1) {
if (num % 2 != 0)
return false;
num = num / 2;
}
return true;
}
void core_channel_init(core_channel_t* self, size_t capacity)
{
mlassert_self();
if (capacity < 4 || !_is_pow2(capacity)) {
mlfatal("invalid capacity");
}
*self = _defaults;
self->capacity = capacity;
lfatal_oom(self->ring_buf = malloc(sizeof(ck_ring_buffer_t) * capacity));
ck_ring_init(&self->ring, capacity);
}
void core_channel_destroy(core_channel_t* self)
{
mlassert_self();
free(self->ring_buf);
}
void core_channel_put(core_channel_t* self, const void* obj)
{
mlassert_self();
lassert(self->ring_buf, "ring_buf is nil");
while (!ck_ring_enqueue_spsc(&self->ring, self->ring_buf, (void*)obj)) {
sched_yield();
}
}
int core_channel_try_put(core_channel_t* self, const void* obj)
{
mlassert_self();
lassert(self->ring_buf, "ring_buf is nil");
if (!ck_ring_enqueue_spsc(&self->ring, self->ring_buf, (void*)obj)) {
return -1;
}
return 0;
}
void* core_channel_get(core_channel_t* self)
{
void* obj = 0;
mlassert_self();
lassert(self->ring_buf, "ring_buf is nil");
while (!ck_ring_dequeue_spsc(&self->ring, self->ring_buf, &obj)) {
sched_yield();
if (ck_pr_load_int(&self->closed)) {
linfo("channel closed");
return 0;
}
}
return obj;
}
void* core_channel_try_get(core_channel_t* self)
{
void* obj = 0;
mlassert_self();
lassert(self->ring_buf, "ring_buf is nil");
if (!ck_ring_dequeue_spsc(&self->ring, self->ring_buf, &obj)) {
return 0;
}
return obj;
}
int core_channel_size(core_channel_t* self)
{
mlassert_self();
return ck_ring_size(&self->ring);
}
bool core_channel_full(core_channel_t* self)
{
mlassert_self();
/* ck_ring can only hold capacity minus one enties at a time */
if (ck_ring_size(&self->ring) < (self->capacity - 1)) {
return false;
}
return true;
}
void core_channel_close(core_channel_t* self)
{
mlassert_self();
ck_pr_store_int(&self->closed, 1);
}
core_receiver_t core_channel_receiver()
{
return (core_receiver_t)core_channel_put;
}
void core_channel_run(core_channel_t* self)
{
void* obj = 0;
mlassert_self();
lassert(self->ring_buf, "ring_buf is nil");
if (!self->recv) {
lfatal("no receiver set");
}
for (;;) {
while (!ck_ring_dequeue_spsc(&self->ring, self->ring_buf, &obj)) {
sched_yield();
if (ck_pr_load_int(&self->closed)) {
linfo("channel closed");
return;
}
}
self->recv(self->ctx, obj);
}
}

41
src/core/channel.h Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/log.h"
#include "core/receiver.h"
#ifndef __dnsjit_core_channel_h
#define __dnsjit_core_channel_h
#if defined(__GNUC__) || defined(__SUNPRO_C)
#include "gcc/ck_cc.h"
#ifdef CK_CC_RESTRICT
#undef CK_CC_RESTRICT
#define CK_CC_RESTRICT __restrict__
#endif
#endif
#include <ck_ring.h>
#include <ck_pr.h>
#include <stdbool.h>
#include "core/channel.hh"
#endif

49
src/core/channel.hh Normal file
View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.compat_h")
//lua:require("dnsjit.core.log")
//lua:require("dnsjit.core.receiver_h")
typedef struct core_channel {
core_log_t _log;
ck_ring_buffer_t* ring_buf;
ck_ring_t ring;
int closed;
size_t capacity;
core_receiver_t recv;
void* ctx;
} core_channel_t;
core_log_t* core_channel_log();
void core_channel_init(core_channel_t* self, size_t capacity);
void core_channel_destroy(core_channel_t* self);
void core_channel_put(core_channel_t* self, const void* obj);
int core_channel_try_put(core_channel_t* self, const void* obj);
void* core_channel_get(core_channel_t* self);
void* core_channel_try_get(core_channel_t* self);
int core_channel_size(core_channel_t* self);
bool core_channel_full(core_channel_t* self);
void core_channel_close(core_channel_t* self);
core_receiver_t core_channel_receiver();
void core_channel_run(core_channel_t* self);

142
src/core/channel.lua Normal file
View file

@ -0,0 +1,142 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.channel
-- Send data to another thread
-- local chan = require("dnsjit.core.channel").new()
-- local thr = require("dnsjit.core.thread").new()
-- thr:start(function(thr)
-- local chan = thr:pop()
-- local obj = chan:get()
-- ...
-- end)
-- thr:push(chan)
-- chan:put(...)
-- chan:close()
-- thr:stop()
--
-- A channel can be used to send data to another thread, this is done by
-- putting a pointer to the data into a wait-free and lock-free ring buffer
-- (concurrency kit).
-- The channel uses the single producer, single consumer model (SPSC) so
-- there can only be one writer and one reader.
-- .SS Attributes
-- .TP
-- int closed
-- Is 1 if the channel has been closed.
module(...,package.seeall)
require("dnsjit.core.channel_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_channel_t"
local core_channel_t
local Channel = {}
-- Create a new Channel, use the optional
-- .I capacity
-- to specify the capacity of the channel (buffer).
-- Capacity must be a power-of-two greater than or equal to 4.
-- Default capacity is 2048.
function Channel.new(capacity)
if capacity == nil then
capacity = 2048
end
local self = core_channel_t()
C.core_channel_init(self, capacity)
ffi.gc(self, C.core_channel_destroy)
return self
end
-- Return the Log object to control logging of this instance or module.
function Channel:log()
if self == nil then
return C.core_channel_log()
end
return self._log
end
-- Return information to use when sharing this object between threads.
function Channel:share()
return ffi.cast("void*", self), t_name.."*", "dnsjit.core.channel"
end
-- Put an object into the channel, if the channel is full then it will
-- stall and wait until space becomes available.
-- Object may be nil.
function Channel:put(obj)
C.core_channel_put(self, obj)
end
-- Try and put an object into the channel.
-- Returns 0 on success.
function Channel:put(obj)
C.core_channel_try_put(self, obj)
end
-- Get an object from the channel, if the channel is empty it will wait until
-- an object is available.
-- Returns nil if the channel is closed or if a nil object was explicitly put
-- into the channel.
function Channel:get()
return C.core_channel_get(self)
end
-- Try and get an object from the channel.
-- Returns nil if there was no objects to get.
function Channel:try_get()
return C.core_channel_try_get(self)
end
-- Return number of enqueued objects.
function Channel:size()
return C.core_channel_size(self)
end
-- Returns true when channel is full.
function Channel:full()
return C.core_channel_full(self)
end
-- Close the channel.
function Channel:close()
C.core_channel_close(self)
end
-- Return the C functions and context for receiving objects.
function Channel:receive()
return C.core_channel_receiver(), self
end
-- Set the receiver to pass objects to.
-- NOTE; The channel keeps no reference of the receiver, it needs to live as
-- long as the channel does.
function Channel:receiver(o)
self.recv, self.ctx = o:receive()
end
-- Retrieve all objects from the channel and send it to the receiver.
function Channel:run()
C.core_channel_run(self)
end
core_channel_t = ffi.metatype(t_name, { __index = Channel })
-- dnsjit.core.thread (3)
return Channel

25
src/core/compat.c Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdint.h>
#include "core/compat.hh"

32
src/core/compat.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __dnsjit_core_compat_h
#define __dnsjit_core_compat_h
#include <unistd.h>
#ifdef __ssize_t_defined
typedef ssize_t luajit_ssize_t;
#else
typedef long luajit_ssize_t;
#endif
#endif

41
src/core/compat.lua Normal file
View file

@ -0,0 +1,41 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.compat
-- Cross platform compatibility support
-- require("dnsjit.core.compat_h")
--
-- This module defines various system structures so they can be exposed into
-- Lua but not really used. The size is generated at compile time to match
-- that of the structures on the platform.
-- .SS Structures
-- .TP
-- pthread_t
-- .TP
-- pthread_cond_t
-- .TP
-- pthread_mutex_t
-- .TP
-- struct sockaddr_storage
-- .TP
-- ck_ring_t
-- .TP
-- ck_ring_buffer_t
module(...,package.seeall)
require("dnsjit.core.compat_h")

399
src/core/log.c Normal file
View file

@ -0,0 +1,399 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/log.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
static core_log_t _log = LOG_T_INIT("core");
void core_log_debug(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
if (!l) {
if (_log.settings.debug != 3) {
return;
}
} else {
if (l->settings.debug) {
if (l->settings.debug != 3) {
return;
}
} else if (l->module && l->module->debug) {
if (l->module->debug != 3) {
return;
}
} else if (_log.settings.debug != 3) {
return;
}
}
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] debug: %s\n", file, line, l->name, l, buf);
return;
}
fprintf(stderr, "%s[%zu] %s debug: %s\n", file, line, l->name, buf);
return;
}
fprintf(stderr, "%s[%zu] %s debug: %s\n", file, line, _log.name, buf);
return;
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] debug: %s\n", l->name, l, buf);
return;
}
fprintf(stderr, "%s debug: %s\n", l->name, buf);
return;
}
fprintf(stderr, "%s debug: %s\n", _log.name, buf);
}
void core_log_info(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
if (!l) {
if (_log.settings.info != 3) {
return;
}
} else {
if (l->settings.info) {
if (l->settings.info != 3) {
return;
}
} else if (l->module && l->module->info) {
if (l->module->info != 3) {
return;
}
} else if (_log.settings.info != 3) {
return;
}
}
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] info: %s\n", file, line, l->name, l, buf);
return;
}
fprintf(stderr, "%s[%zu] %s info: %s\n", file, line, l->name, buf);
return;
}
fprintf(stderr, "%s[%zu] %s info: %s\n", file, line, _log.name, buf);
return;
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] info: %s\n", l->name, l, buf);
return;
}
fprintf(stderr, "%s info: %s\n", l->name, buf);
return;
}
fprintf(stderr, "%s info: %s\n", _log.name, buf);
}
void core_log_notice(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
if (!l) {
if (_log.settings.notice != 3) {
return;
}
} else {
if (l->settings.notice) {
if (l->settings.notice != 3) {
return;
}
} else if (l->module && l->module->notice) {
if (l->module->notice != 3) {
return;
}
} else if (_log.settings.notice != 3) {
return;
}
}
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] notice: %s\n", file, line, l->name, l, buf);
return;
}
fprintf(stderr, "%s[%zu] %s notice: %s\n", file, line, l->name, buf);
return;
}
fprintf(stderr, "%s[%zu] %s notice: %s\n", file, line, _log.name, buf);
return;
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] notice: %s\n", l->name, l, buf);
return;
}
fprintf(stderr, "%s notice: %s\n", l->name, buf);
return;
}
fprintf(stderr, "%s notice: %s\n", _log.name, buf);
}
void core_log_warning(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
if (!l) {
if (_log.settings.warning != 3) {
return;
}
} else {
if (l->settings.warning) {
if (l->settings.warning != 3) {
return;
}
} else if (l->module && l->module->warning) {
if (l->module->warning != 3) {
return;
}
} else if (_log.settings.warning != 3) {
return;
}
}
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] warning: %s\n", file, line, l->name, l, buf);
return;
}
fprintf(stderr, "%s[%zu] %s warning: %s\n", file, line, l->name, buf);
return;
}
fprintf(stderr, "%s[%zu] %s warning: %s\n", file, line, _log.name, buf);
return;
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] warning: %s\n", l->name, l, buf);
return;
}
fprintf(stderr, "%s warning: %s\n", l->name, buf);
return;
}
fprintf(stderr, "%s warning: %s\n", _log.name, buf);
}
void core_log_critical(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] critical: %s\n", file, line, l->name, l, buf);
return;
}
fprintf(stderr, "%s[%zu] %s critical: %s\n", file, line, l->name, buf);
return;
}
fprintf(stderr, "%s[%zu] %s critical: %s\n", file, line, _log.name, buf);
return;
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] critical: %s\n", l->name, l, buf);
return;
}
fprintf(stderr, "%s critical: %s\n", l->name, buf);
return;
}
fprintf(stderr, "%s critical: %s\n", _log.name, buf);
}
void core_log_fatal(const core_log_t* l, const char* file, size_t line, const char* msg, ...)
{
char buf[512];
va_list ap;
va_start(ap, msg);
vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
buf[sizeof(buf) - 1] = 0;
for (;;) {
if (!l) {
if (_log.settings.display_file_line != 3) {
break;
}
} else {
if (l->settings.display_file_line) {
if (l->settings.display_file_line != 3) {
break;
}
} else if (l->module && l->module->display_file_line) {
if (l->module->display_file_line != 3) {
break;
}
} else if (_log.settings.display_file_line != 3) {
break;
}
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%zu] %s[%p] fatal: %s\n", file, line, l->name, l, buf);
exit(1);
}
fprintf(stderr, "%s[%zu] %s fatal: %s\n", file, line, l->name, buf);
exit(1);
}
fprintf(stderr, "%s[%zu] %s fatal: %s\n", file, line, _log.name, buf);
exit(1);
}
if (l) {
if (l->is_obj) {
fprintf(stderr, "%s[%p] fatal: %s\n", l->name, l, buf);
exit(1);
}
fprintf(stderr, "%s fatal: %s\n", l->name, buf);
exit(1);
}
fprintf(stderr, "%s fatal: %s\n", _log.name, buf);
exit(1);
}
core_log_t* core_log_log()
{
return &_log;
}
#include "core/log_errstr.c"

105
src/core/log.h Normal file
View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __dnsjit_core_log_h
#define __dnsjit_core_log_h
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>
#define LOG_SETTINGS_T_INIT \
{ \
0, 0, 0, 0, 0 \
}
#define LOG_T_INIT(name) \
{ \
name, 0, LOG_SETTINGS_T_INIT, 0 \
}
#define LOG_T_INIT_OBJ(name) \
{ \
name, 1, LOG_SETTINGS_T_INIT, &_log.settings \
}
#include "core/log.hh"
#ifdef DNSJIT_NO_LOGGING
#define ldebug(msg...)
#define linfo(msg...)
#define lnotice(msg...)
#define lwarning(msg...)
#define lcritical(msg...)
#define lpdebug(msg...)
#define lpinfo(msg...)
#define lpnotice(msg...)
#define lpwarning(msg...)
#define lpcritical(msg...)
#define mldebug(msg...)
#define mlinfo(msg...)
#define mlnotice(msg...)
#define mlwarning(msg...)
#define mlcritical(msg...)
#define gldebug(msg...)
#define glinfo(msg...)
#define glnotice(msg...)
#define glwarning(msg...)
#define glcritical(msg...)
#else
#define ldebug(msg...) core_log_debug(&self->_log, __FILE__, __LINE__, msg)
#define linfo(msg...) core_log_info(&self->_log, __FILE__, __LINE__, msg)
#define lnotice(msg...) core_log_notice(&self->_log, __FILE__, __LINE__, msg)
#define lwarning(msg...) core_log_warning(&self->_log, __FILE__, __LINE__, msg)
#define lcritical(msg...) core_log_critical(&self->_log, __FILE__, __LINE__, msg)
#define lpdebug(msg...) core_log_debug(self->_log, __FILE__, __LINE__, msg)
#define lpinfo(msg...) core_log_info(self->_log, __FILE__, __LINE__, msg)
#define lpnotice(msg...) core_log_notice(self->_log, __FILE__, __LINE__, msg)
#define lpwarning(msg...) core_log_warning(self->_log, __FILE__, __LINE__, msg)
#define lpcritical(msg...) core_log_critical(self->_log, __FILE__, __LINE__, msg)
#define mldebug(msg...) core_log_debug(&_log, __FILE__, __LINE__, msg)
#define mlinfo(msg...) core_log_info(&_log, __FILE__, __LINE__, msg)
#define mlnotice(msg...) core_log_notice(&_log, __FILE__, __LINE__, msg)
#define mlwarning(msg...) core_log_warning(&_log, __FILE__, __LINE__, msg)
#define mlcritical(msg...) core_log_critical(&_log, __FILE__, __LINE__, msg)
#define gldebug(msg...) core_log_debug(0, __FILE__, __LINE__, msg)
#define glinfo(msg...) core_log_info(0, __FILE__, __LINE__, msg)
#define glnotice(msg...) core_log_notice(0, __FILE__, __LINE__, msg)
#define glwarning(msg...) core_log_warning(0, __FILE__, __LINE__, msg)
#define glcritical(msg...) core_log_critical(0, __FILE__, __LINE__, msg)
#endif
#define lfatal(msg...) core_log_fatal(&self->_log, __FILE__, __LINE__, msg)
#define lpfatal(msg...) core_log_fatal(self->_log, __FILE__, __LINE__, msg)
#define mlfatal(msg...) core_log_fatal(&_log, __FILE__, __LINE__, msg)
#define glfatal(msg...) core_log_fatal(0, __FILE__, __LINE__, msg)
#define lfatal_oom(expression) \
if (!(expression)) \
core_log_fatal(&self->_log, __FILE__, __LINE__, "out of memory")
#define lpfatal_oom(expression) \
if (!(expression)) \
core_log_fatal(self->_log, __FILE__, __LINE__, "out of memory")
#define mlfatal_oom(expression) \
if (!(expression)) \
core_log_fatal(&_log, __FILE__, __LINE__, "out of memory")
#define glfatal_oom(expression) \
if (!(expression)) \
core_log_fatal(0, __FILE__, __LINE__, "out of memory")
#endif

44
src/core/log.hh Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
typedef struct core_log_settings {
uint8_t debug;
uint8_t info;
uint8_t notice;
uint8_t warning;
uint8_t display_file_line;
} core_log_settings_t;
typedef struct core_log {
char name[32];
uint8_t is_obj;
core_log_settings_t settings;
const core_log_settings_t* module;
} core_log_t;
void core_log_debug(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
void core_log_info(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
void core_log_notice(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
void core_log_warning(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
void core_log_critical(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
void core_log_fatal(const core_log_t* l, const char* file, size_t line, const char* msg, ...);
const char* core_log_errstr(int err);
core_log_t* core_log_log();

639
src/core/log.lua Normal file
View file

@ -0,0 +1,639 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.log
-- Core logging facility
-- .SS Usage to control global log level
-- local log = require("dnsjit.core.log")
-- log.enable("all")
-- log.disable("debug")
-- .SS Usage to control module log level
-- local example = require("example") -- Example as below
-- example.log():enable("all")
-- example.log():disable("debug")
-- .SS Usage to control object instance log level
-- local example = require("example") -- Example as below
-- local obj = example.new()
-- obj:log():enable("all")
-- obj:log():disable("debug")
-- .SS Usage in C module
-- .B NOTE
-- naming of variables and module only globals are required to exactly as
-- described in order for the macros to work;
-- .B self
-- is the pointer to the object instance,
-- .B self->_log
-- is the object instance logging configuration struct,
-- .B _log
-- is the module logging configuration struct.
-- .LP
-- Include logging:
-- #include "core/log.h"
-- .LP
-- Add the logging struct to the module struct:
-- typedef struct example {
-- core_log_t _log;
-- ...
-- } example_t;
-- .LP
-- Add a module logging configuration and a struct default:
-- static core_log_t _log = LOG_T_INIT("example");
-- static example_t _defaults = {
-- LOG_T_INIT_OBJ("example"),
-- ...
-- };
-- .LP
-- Use new/free and/or init/destroy functions (depends if you create the
-- object in Lua or not):
-- example_t* example_new() {
-- example_t* self = calloc(1, sizeof(example_t));
-- .
-- *self = _defaults;
-- ldebug("new()");
-- .
-- return self;
-- }
-- .
-- void example_free(example_t* self) {
-- ldebug("free()");
-- free(self);
-- }
-- .
-- int example_init(example_t* self) {
-- *self = _defaults;
-- .
-- ldebug("init()");
-- .
-- return 0;
-- }
-- .
-- void example_destroy(example_t* self) {
-- ldebug("destroy()");
-- ...
-- }
-- .LP
-- In the Lua part of the C module you need to create a function that
-- returns either the object instance Log or the modules Log.
-- .LP
-- Add C function to get module only Log:
-- core_log_t* example_log() {
-- return &_log;
-- }
-- .LP
-- For the structures metatable add the following function:
-- local ffi = require("ffi")
-- local C = ffi.C
-- .
-- function Example:log()
-- if self == nil then
-- return C.example_log()
-- end
-- return self._log
-- end
-- .SS Usage in pure Lua module
-- local log = require("dnsjit.core.log")
-- local ffi = require("ffi")
-- local C = ffi.C
-- .
-- local Example = {}
-- local module_log = log.new("example")
-- .
-- function Example.new()
-- local self = setmetatable({
-- _log = log.new("example", module_log),
-- }, { __index = Example })
-- .
-- self._log:debug("new()")
-- .
-- return self
-- end
-- .
-- function Example:log()
-- if self == nil then
-- return module_log
-- end
-- return self._log
-- end
--
-- Core logging facility used by all modules.
-- .SS Log levels
-- .TP
-- all
-- Keyword to enable/disable all changeable log levels.
-- .TP
-- debug
-- Used for debug information.
-- .TP
-- info
-- Used for informational processing messages.
-- .TP
-- notice
-- Used for messages of that may have impact on processing.
-- .TP
-- warning
-- Used for messages that has impact on processing.
-- .TP
-- critical
-- Used for messages that have severe impact on processing, this level can
-- not be disabled.
-- .TP
-- fatal
-- Used to display a message before stopping all processing and existing,
-- this level can not be disabled.
-- .SS C macros
-- .TP
-- Object instance macros
-- The following macros uses
-- .IR &self->_log :
-- .BR ldebug(msg...) ,
-- .BR linfo(msg...) ,
-- .BR lnotice(msg...) ,
-- .BR lwarning(msg...) ,
-- .BR lcritical(msg...) ,
-- .BR lfatal(msg...) .
-- .TP
-- Object pointer instance macros
-- The following macros uses
-- .IR self->_log :
-- .BR lpdebug(msg...) ,
-- .BR lpinfo(msg...) ,
-- .BR lpnotice(msg...) ,
-- .BR lpwarning(msg...) ,
-- .BR lpcritical(msg...) ,
-- .BR lpfatal(msg...) .
-- .TP
-- Module macros
-- The following macros uses
-- .IR &_log :
-- .BR mldebug(msg...) ,
-- .BR mlinfo(msg...) ,
-- .BR mlnotice(msg...) ,
-- .BR mlwarning(msg...) ,
-- .BR mlcritical(msg...) ,
-- .BR mlfatal(msg...) .
-- .TP
-- Global macros
-- The following macros uses the global logging configuration:
-- .BR gldebug(msg...) ,
-- .BR glinfo(msg...) ,
-- .BR glnotice(msg...) ,
-- .BR glwarning(msg...) ,
-- .BR glcritical(msg...) ,
-- .BR glfatal(msg...) .
module(...,package.seeall)
require("dnsjit.core.log_h")
local ffi = require("ffi")
local C = ffi.C
local L = C.core_log_log()
local t_name = "core_log_t"
local core_log_t
local Log = {}
-- Create a new Log object with the given module
-- .I name
-- and an optional shared
-- .I module
-- Log object.
function Log.new(name, module)
local self
if ffi.istype(t_name, module) then
self = core_log_t({ is_obj = 1, module = module.settings })
else
self = core_log_t()
end
local len = #name
if len > 31 then
len = 31
end
ffi.copy(self.name, name, len)
self.name[len] = 0
return self
end
-- Enable specified log level.
function Log:enable(level)
if not ffi.istype(t_name, self) then
level = self
self = L
end
if level == "all" then
self.settings.debug = 3
self.settings.info = 3
self.settings.notice = 3
self.settings.warning = 3
elseif level == "debug" then
self.settings.debug = 3
elseif level == "info" then
self.settings.info = 3
elseif level == "notice" then
self.settings.notice = 3
elseif level == "warning" then
self.settings.warning = 3
else
error("invalid log level: "..level)
end
end
-- Disable specified log level.
function Log:disable(level)
if not ffi.istype(t_name, self) then
level = self
self = L
end
if level == "all" then
self.settings.debug = 2
self.settings.info = 2
self.settings.notice = 2
self.settings.warning = 2
elseif level == "debug" then
self.settings.debug = 2
elseif level == "info" then
self.settings.info = 2
elseif level == "notice" then
self.settings.notice = 2
elseif level == "warning" then
self.settings.warning = 2
else
error("invalid log level: "..level)
end
end
-- Clear specified log level, which means it will revert back to default
-- or inherited settings.
function Log:clear(level)
if not ffi.istype(t_name, self) then
level = self
self = L
end
if level == "all" then
self.settings.debug = 0
self.settings.info = 0
self.settings.notice = 0
self.settings.warning = 0
elseif level == "debug" then
self.settings.debug = 0
elseif level == "info" then
self.settings.info = 0
elseif level == "notice" then
self.settings.notice = 0
elseif level == "warning" then
self.settings.warning = 0
else
error("invalid log level: "..level)
end
end
-- Enable or disable the displaying of file and line for messages.
function Log:display_file_line(bool)
if not ffi.istype(t_name, self) then
bool = self
self = L
end
if bool == true then
self.settings.display_file_line = 3
else
self.settings.display_file_line = 0
end
end
-- Convert error number to its text representation.
function Log.errstr(errno)
return ffi.string(C.core_log_errstr(errno))
end
-- Generate a debug message.
function Log.debug(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
if not self then
if L.settings.debug ~= 3 then
return
end
else
if self.settings.debug ~= 0 then
if self.settings.debug ~= 3 then
return
end
elseif self.module ~= nil and self.module.debug ~= 0 then
if self.module.debug ~= 3 then
return
end
elseif L.settings.debug ~= 3 then
return
end
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_debug(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_debug(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_debug(self, nil, 0, format, ...)
return
end
C.core_log_debug(self, nil, 0, ...)
end
-- Generate an info message.
function Log.info(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
if not self then
if L.settings.info ~= 3 then
return
end
else
if self.settings.info ~= 0 then
if self.settings.info ~= 3 then
return
end
elseif self.module ~= nil and self.module.info ~= 0 then
if self.module.info ~= 3 then
return
end
elseif L.settings.info ~= 3 then
return
end
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_info(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_info(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_info(self, nil, 0, format, ...)
return
end
C.core_log_info(self, nil, 0, ...)
end
-- Generate a notice message.
function Log.notice(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
if not self then
if L.settings.notice ~= 3 then
return
end
else
if self.settings.notice ~= 0 then
if self.settings.notice ~= 3 then
return
end
elseif self.module ~= nil and self.module.notice ~= 0 then
if self.module.notice ~= 3 then
return
end
elseif L.settings.notice ~= 3 then
return
end
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_notice(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_notice(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_notice(self, nil, 0, format, ...)
return
end
C.core_log_notice(self, nil, 0, ...)
end
-- Generate a warning message.
function Log.warning(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
if not self then
if L.settings.warning ~= 3 then
return
end
else
if self.settings.warning ~= 0 then
if self.settings.warning ~= 3 then
return
end
elseif self.module ~= nil and self.module.warning ~= 0 then
if self.module.warning ~= 3 then
return
end
elseif L.settings.warning ~= 3 then
return
end
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_warning(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_warning(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_warning(self, nil, 0, format, ...)
return
end
C.core_log_warning(self, nil, 0, ...)
end
-- Generate a critical message.
function Log.critical(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_critical(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_critical(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_critical(self, nil, 0, format, ...)
return
end
C.core_log_critical(self, nil, 0, ...)
end
-- Generate a fatal message.
function Log.fatal(self, ...)
local format
if not ffi.istype(t_name, self) then
format = self
self = nil
end
while true do
if not self then
if L.settings.display_file_line ~= 3 then
break
end
else
if self.settings.display_file_line ~= 0 then
if self.settings.display_file_line ~= 3 then
break
end
elseif self.module ~= nil and self.module.display_file_line ~= 0 then
if self.module.display_file_line ~= 3 then
break
end
elseif L.settings.display_file_line ~= 3 then
break
end
end
local info = debug.getinfo(2, "S")
if format then
C.core_log_fatal(self, info.source, info.linedefined, format, ...)
return
end
C.core_log_fatal(self, info.source, info.linedefined, ...)
return
end
if format then
C.core_log_fatal(self, nil, 0, format, ...)
return
end
C.core_log_fatal(self, nil, 0, ...)
end
core_log_t = ffi.metatype(t_name, { __index = Log })
return Log

135
src/core/object.c Normal file
View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object.h"
#include "core/assert.h"
#include "core/object/pcap.h"
#include "core/object/ether.h"
#include "core/object/null.h"
#include "core/object/loop.h"
#include "core/object/linuxsll.h"
#include "core/object/ieee802.h"
#include "core/object/gre.h"
#include "core/object/ip.h"
#include "core/object/ip6.h"
#include "core/object/icmp.h"
#include "core/object/icmp6.h"
#include "core/object/udp.h"
#include "core/object/tcp.h"
#include "core/object/payload.h"
#include "core/object/dns.h"
core_object_t* core_object_copy(const core_object_t* self)
{
glassert_self();
switch (self->obj_type) {
case CORE_OBJECT_PCAP:
return (core_object_t*)core_object_pcap_copy((core_object_pcap_t*)self);
case CORE_OBJECT_ETHER:
return (core_object_t*)core_object_ether_copy((core_object_ether_t*)self);
case CORE_OBJECT_NULL:
return (core_object_t*)core_object_null_copy((core_object_null_t*)self);
case CORE_OBJECT_LOOP:
return (core_object_t*)core_object_loop_copy((core_object_loop_t*)self);
case CORE_OBJECT_LINUXSLL:
return (core_object_t*)core_object_linuxsll_copy((core_object_linuxsll_t*)self);
case CORE_OBJECT_IEEE802:
return (core_object_t*)core_object_ieee802_copy((core_object_ieee802_t*)self);
case CORE_OBJECT_GRE:
return (core_object_t*)core_object_gre_copy((core_object_gre_t*)self);
case CORE_OBJECT_IP:
return (core_object_t*)core_object_ip_copy((core_object_ip_t*)self);
case CORE_OBJECT_IP6:
return (core_object_t*)core_object_ip6_copy((core_object_ip6_t*)self);
case CORE_OBJECT_ICMP:
return (core_object_t*)core_object_icmp_copy((core_object_icmp_t*)self);
case CORE_OBJECT_ICMP6:
return (core_object_t*)core_object_icmp6_copy((core_object_icmp6_t*)self);
case CORE_OBJECT_UDP:
return (core_object_t*)core_object_udp_copy((core_object_udp_t*)self);
case CORE_OBJECT_TCP:
return (core_object_t*)core_object_tcp_copy((core_object_tcp_t*)self);
case CORE_OBJECT_PAYLOAD:
return (core_object_t*)core_object_payload_copy((core_object_payload_t*)self);
case CORE_OBJECT_DNS:
return (core_object_t*)core_object_dns_copy((core_object_dns_t*)self);
default:
glfatal("unknown type %d", self->obj_type);
}
return 0;
}
void core_object_free(core_object_t* self)
{
glassert_self();
switch (self->obj_type) {
case CORE_OBJECT_PCAP:
core_object_pcap_free((core_object_pcap_t*)self);
break;
case CORE_OBJECT_ETHER:
core_object_ether_free((core_object_ether_t*)self);
break;
case CORE_OBJECT_NULL:
core_object_null_free((core_object_null_t*)self);
break;
case CORE_OBJECT_LOOP:
core_object_loop_free((core_object_loop_t*)self);
break;
case CORE_OBJECT_LINUXSLL:
core_object_linuxsll_free((core_object_linuxsll_t*)self);
break;
case CORE_OBJECT_IEEE802:
core_object_ieee802_free((core_object_ieee802_t*)self);
break;
case CORE_OBJECT_GRE:
core_object_gre_free((core_object_gre_t*)self);
break;
case CORE_OBJECT_IP:
core_object_ip_free((core_object_ip_t*)self);
break;
case CORE_OBJECT_IP6:
core_object_ip6_free((core_object_ip6_t*)self);
break;
case CORE_OBJECT_ICMP:
core_object_icmp_free((core_object_icmp_t*)self);
break;
case CORE_OBJECT_ICMP6:
core_object_icmp6_free((core_object_icmp6_t*)self);
break;
case CORE_OBJECT_UDP:
core_object_udp_free((core_object_udp_t*)self);
break;
case CORE_OBJECT_TCP:
core_object_tcp_free((core_object_tcp_t*)self);
break;
case CORE_OBJECT_PAYLOAD:
core_object_payload_free((core_object_payload_t*)self);
break;
case CORE_OBJECT_DNS:
core_object_dns_free((core_object_dns_t*)self);
break;
default:
glfatal("unknown type %d", self->obj_type);
}
}

51
src/core/object.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __dnsjit_core_object_h
#define __dnsjit_core_object_h
#define CORE_OBJECT_NONE 0
#define CORE_OBJECT_PCAP 1
/* link level objects */
#define CORE_OBJECT_ETHER 10
#define CORE_OBJECT_NULL 11
#define CORE_OBJECT_LOOP 12
#define CORE_OBJECT_LINUXSLL 13
#define CORE_OBJECT_IEEE802 14
#define CORE_OBJECT_GRE 15
/* protocol objects */
#define CORE_OBJECT_IP 20
#define CORE_OBJECT_IP6 21
#define CORE_OBJECT_ICMP 22
#define CORE_OBJECT_ICMP6 23
/* payload carrying objects */
#define CORE_OBJECT_UDP 30
#define CORE_OBJECT_TCP 31
/* payload */
#define CORE_OBJECT_PAYLOAD 40
/* service object(s) */
#define CORE_OBJECT_DNS 50
#include <stdint.h>
#include "core/object.hh"
#define CORE_OBJECT_INIT(type, prev) (core_object_t*)prev, type
#endif

28
src/core/object.hh Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 objectd a copy of the GNU General Public License
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
typedef struct core_object core_object_t;
struct core_object {
const core_object_t* obj_prev;
int32_t obj_type;
};
core_object_t* core_object_copy(const core_object_t* self);
void core_object_free(core_object_t* self);

177
src/core/object.lua Normal file
View file

@ -0,0 +1,177 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object
-- Base object that is passed between receiver and receivee
-- require("dnsjit.core.object")
-- print(object:type())
-- packet = object:cast()
--
-- This is the base object that can be casted to other objects that to
-- describe a DNS message, how it was captured or generated.
-- Objects can be chained together, for example a DNS message is created
-- ontop of a packet.
-- .SS Attributes
-- .TP
-- obj_type
-- The enum of the object type.
-- .TP
-- obj_prev
-- The previous object in the object chain.
module(...,package.seeall)
require("dnsjit.core.object_h")
require("dnsjit.core.object.pcap_h")
require("dnsjit.core.object.ether_h")
require("dnsjit.core.object.null_h")
require("dnsjit.core.object.loop_h")
require("dnsjit.core.object.linuxsll_h")
require("dnsjit.core.object.ieee802_h")
require("dnsjit.core.object.gre_h")
require("dnsjit.core.object.ip_h")
require("dnsjit.core.object.ip6_h")
require("dnsjit.core.object.icmp_h")
require("dnsjit.core.object.icmp6_h")
require("dnsjit.core.object.udp_h")
require("dnsjit.core.object.tcp_h")
require("dnsjit.core.object.payload_h")
require("dnsjit.core.object.dns_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_t"
local core_object_t
local Object = {
NONE = 0,
PCAP = 1,
ETHER = 10,
NULL = 11,
LOOP = 12,
LINUXSLL = 13,
IEEE802 = 14,
GRE = 15,
IP = 20,
IP6 = 21,
ICMP = 22,
ICMP6 = 23,
UDP = 30,
TCP = 31,
PAYLOAD = 40,
DNS = 50
}
local _type = {}
_type[Object.PCAP] = "pcap"
_type[Object.ETHER] = "ether"
_type[Object.NULL] = "null"
_type[Object.LOOP] = "loop"
_type[Object.LINUXSLL] = "linuxsll"
_type[Object.IEEE802] = "ieee802"
_type[Object.GRE] = "gre"
_type[Object.IP] = "ip"
_type[Object.IP6] = "ip6"
_type[Object.ICMP] = "icmp"
_type[Object.ICMP6] = "icmp6"
_type[Object.UDP] = "udp"
_type[Object.TCP] = "tcp"
_type[Object.PAYLOAD] = "payload"
_type[Object.DNS] = "dns"
_type[Object.NONE] = "none"
-- Return the textual type of the object.
function Object:type()
return _type[self.obj_type]
end
-- Return the previous object.
function Object:prev()
return self.obj_prev
end
local _cast = {}
_cast[Object.PCAP] = "core_object_pcap_t*"
_cast[Object.ETHER] = "core_object_ether_t*"
_cast[Object.NULL] = "core_object_null_t*"
_cast[Object.LOOP] = "core_object_loop_t*"
_cast[Object.LINUXSLL] = "core_object_linuxsll_t*"
_cast[Object.IEEE802] = "core_object_ieee802_t*"
_cast[Object.GRE] = "core_object_gre_t*"
_cast[Object.IP] = "core_object_ip_t*"
_cast[Object.IP6] = "core_object_ip6_t*"
_cast[Object.ICMP] = "core_object_icmp_t*"
_cast[Object.ICMP6] = "core_object_icmp6_t*"
_cast[Object.UDP] = "core_object_udp_t*"
_cast[Object.TCP] = "core_object_tcp_t*"
_cast[Object.PAYLOAD] = "core_object_payload_t*"
_cast[Object.DNS] = "core_object_dns_t*"
-- Cast the object to the underlining object module and return it.
function Object:cast()
return ffi.cast(_cast[self.obj_type], self)
end
-- Cast the object to the specified object module and return it.
-- Returns nil if the object chain doesn't contained the specified object type.
function Object:cast_to(obj_type)
if obj_type == nil then
obj_type = self.obj_type
end
local obj = self
while obj.obj_type ~= obj_type do
obj = obj.obj_prev
if obj == nil then return nil end
end
return ffi.cast(_cast[obj_type], obj)
end
-- Cast the object to the generic object module and return it.
function Object:uncast()
return self
end
-- Make a copy of the object and return it.
function Object:copy()
return C.core_object_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Object:free()
C.core_object_free(self)
end
core_object_t = ffi.metatype(t_name, { __index = Object })
-- dnsjit.core.object.pcap (3),
-- dnsjit.core.object.ether (3),
-- dnsjit.core.object.null (3),
-- dnsjit.core.object.loop (3),
-- dnsjit.core.object.linuxsll (3),
-- dnsjit.core.object.ieee802 (3),
-- dnsjit.core.object.gre (3),
-- dnsjit.core.object.ip (3),
-- dnsjit.core.object.ip6 (3),
-- dnsjit.core.object.icmp (3),
-- dnsjit.core.object.icmp6 (3),
-- dnsjit.core.object.udp (3),
-- dnsjit.core.object.tcp (3),
-- dnsjit.core.object.payload (3),
-- dnsjit.core.object.dns (3)
return Object

471
src/core/object/dns.c Normal file
View file

@ -0,0 +1,471 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/dns.h"
#include "core/object/payload.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#else
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#else
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#endif
#endif
#endif
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifndef bswap_16
#ifndef bswap16
#define bswap_16(x) swap16(x)
#define bswap_32(x) swap32(x)
#define bswap_64(x) swap64(x)
#else
#define bswap_16(x) bswap16(x)
#define bswap_32(x) bswap32(x)
#define bswap_64(x) bswap64(x)
#endif
#endif
#define _ERR_MALFORMED -2
#define _ERR_NEEDLABELS -3
static core_log_t _log = LOG_T_INIT("core.object.dns");
static core_object_dns_t _defaults = CORE_OBJECT_DNS_INIT(0);
static core_object_dns_label_t _defaults_label = { 0 };
static core_object_dns_rr_t _defaults_rr = { 0 };
static core_object_dns_q_t _defaults_q = { 0 };
core_log_t* core_object_dns_log()
{
return &_log;
}
core_object_dns_t* core_object_dns_new()
{
core_object_dns_t* self;
mlfatal_oom(self = malloc(sizeof(core_object_dns_t)));
*self = _defaults;
return self;
}
core_object_dns_t* core_object_dns_copy(const core_object_dns_t* self)
{
core_object_dns_t* copy;
mlassert_self();
mlfatal_oom(copy = malloc(sizeof(core_object_dns_t)));
memcpy(copy, self, sizeof(core_object_dns_t));
copy->obj_prev = 0;
return (core_object_dns_t*)copy;
}
void core_object_dns_free(core_object_dns_t* self)
{
mlassert_self();
free(self);
}
#define need8(v, p, l) \
if (l < 1) { \
break; \
} \
v = *p; \
p += 1; \
l -= 1
static inline uint16_t _need16(const void* ptr)
{
uint16_t v;
memcpy(&v, ptr, sizeof(v));
return be16toh(v);
}
#define need16(v, p, l) \
if (l < 2) { \
break; \
} \
v = _need16(p); \
p += 2; \
l -= 2
static inline uint32_t _need32(const void* ptr)
{
uint32_t v;
memcpy(&v, ptr, sizeof(v));
return be32toh(v);
}
#define need32(v, p, l) \
if (l < 4) { \
break; \
} \
v = _need32(p); \
p += 4; \
l -= 4
#define needxb(b, x, p, l) \
if (l < x) { \
break; \
} \
memcpy(b, p, x); \
p += x; \
l -= x
#define advancexb(x, p, l) \
if (l < x) { \
break; \
} \
p += x; \
l -= x
int core_object_dns_parse_header(core_object_dns_t* self)
{
const core_object_payload_t* payload;
uint8_t byte;
mlassert_self();
if (!(payload = (core_object_payload_t*)self->obj_prev) || payload->obj_type != CORE_OBJECT_PAYLOAD) {
mlfatal("no obj_prev or invalid type");
}
if (!payload->payload || !payload->len) {
mlfatal("no payload set or zero length");
}
self->payload = self->at = payload->payload;
self->len = self->left = payload->len;
for (;;) {
if (self->includes_dnslen) {
need16(self->dnslen, self->at, self->left);
self->have_dnslen = 1;
}
need16(self->id, self->at, self->left);
self->have_id = 1;
need8(byte, self->at, self->left);
self->qr = byte & (1 << 7) ? 1 : 0;
self->opcode = (byte >> 3) & 0xf;
self->aa = byte & (1 << 2) ? 1 : 0;
self->tc = byte & (1 << 1) ? 1 : 0;
self->rd = byte & (1 << 0) ? 1 : 0;
self->have_qr = self->have_opcode = self->have_aa = self->have_tc = self->have_rd = 1;
need8(byte, self->at, self->left);
self->ra = byte & (1 << 7) ? 1 : 0;
self->z = byte & (1 << 6) ? 1 : 0;
self->ad = byte & (1 << 5) ? 1 : 0;
self->cd = byte & (1 << 4) ? 1 : 0;
self->rcode = byte & 0xf;
self->have_ra = self->have_z = self->have_ad = self->have_cd = self->have_rcode = 1;
need16(self->qdcount, self->at, self->left);
self->have_qdcount = 1;
need16(self->ancount, self->at, self->left);
self->have_ancount = 1;
need16(self->nscount, self->at, self->left);
self->have_nscount = 1;
need16(self->arcount, self->at, self->left);
self->have_arcount = 1;
return 0;
}
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
static inline size_t _rdata_labels(uint16_t type)
{
switch (type) {
case CORE_OBJECT_DNS_TYPE_NS:
case CORE_OBJECT_DNS_TYPE_MD:
case CORE_OBJECT_DNS_TYPE_MF:
case CORE_OBJECT_DNS_TYPE_CNAME:
case CORE_OBJECT_DNS_TYPE_MB:
case CORE_OBJECT_DNS_TYPE_MG:
case CORE_OBJECT_DNS_TYPE_MR:
case CORE_OBJECT_DNS_TYPE_PTR:
case CORE_OBJECT_DNS_TYPE_NXT:
case CORE_OBJECT_DNS_TYPE_DNAME:
case CORE_OBJECT_DNS_TYPE_NSEC:
case CORE_OBJECT_DNS_TYPE_TKEY:
case CORE_OBJECT_DNS_TYPE_TSIG:
return 1;
case CORE_OBJECT_DNS_TYPE_SOA:
case CORE_OBJECT_DNS_TYPE_MINFO:
case CORE_OBJECT_DNS_TYPE_RP:
case CORE_OBJECT_DNS_TYPE_TALINK:
return 2;
case CORE_OBJECT_DNS_TYPE_MX:
case CORE_OBJECT_DNS_TYPE_AFSDB:
case CORE_OBJECT_DNS_TYPE_RT:
case CORE_OBJECT_DNS_TYPE_KX:
case CORE_OBJECT_DNS_TYPE_LP:
return 1;
case CORE_OBJECT_DNS_TYPE_PX:
return 2;
case CORE_OBJECT_DNS_TYPE_SIG:
case CORE_OBJECT_DNS_TYPE_RRSIG:
return 1;
case CORE_OBJECT_DNS_TYPE_SRV:
return 1;
case CORE_OBJECT_DNS_TYPE_NAPTR:
return 1;
case CORE_OBJECT_DNS_TYPE_HIP:
return 1;
default:
break;
}
return 0;
}
static inline size_t _label(core_object_dns_t* self, core_object_dns_label_t* label, size_t labels)
{
size_t n;
for (n = 0; self->left && n < labels; n++) {
core_object_dns_label_t* l = &label[n];
*l = _defaults_label;
need8(l->length, self->at, self->left);
if ((l->length & 0xc0) == 0xc0) {
need8(l->offset, self->at, self->left);
l->offset |= (l->length & 0x3f) << 8;
l->have_offset = 1;
return n;
} else if (l->length & 0xc0) {
l->extension_bits = l->length >> 6;
l->have_extension_bits = 1;
return n;
} else if (l->length) {
l->have_length = 1;
l->offset = self->at - self->payload - 1;
advancexb(l->length, self->at, self->left);
l->have_dn = 1;
} else {
l->is_end = 1;
return n;
}
}
return n;
}
int core_object_dns_parse_q(core_object_dns_t* self, core_object_dns_q_t* q, core_object_dns_label_t* label, size_t labels)
{
mlassert_self();
mlassert(q, "q is nil");
mlassert(label, "label is nil");
mlassert(labels, "labels is zero");
mlassert(self->at, "at is nil");
for (;;) {
*q = _defaults_q;
q->labels = _label(self, label, labels);
if (q->labels < labels) {
core_object_dns_label_t* l = &label[q->labels];
if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
} else {
mlwarning("need more labels, aborting DNS parsing");
return _ERR_NEEDLABELS;
}
q->labels++;
need16(q->type, self->at, self->left);
q->have_type = 1;
need16(q->class, self->at, self->left);
q->have_class = 1;
return 0;
}
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
int core_object_dns_parse_rr(core_object_dns_t* self, core_object_dns_rr_t* rr, core_object_dns_label_t* label, size_t labels)
{
size_t rdata_label_sets;
mlassert_self();
mlassert(rr, "rr is nil");
mlassert(label, "label is nil");
mlassert(labels, "labels is zero");
mlassert(self->at, "at is nil");
for (;;) {
*rr = _defaults_rr;
rr->labels = _label(self, label, labels);
if (rr->labels < labels) {
core_object_dns_label_t* l = &label[rr->labels];
if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
} else {
mlwarning("need more labels, aborting DNS parsing");
return _ERR_NEEDLABELS;
}
rr->labels++;
need16(rr->type, self->at, self->left);
rr->have_type = 1;
need16(rr->class, self->at, self->left);
rr->have_class = 1;
need32(rr->ttl, self->at, self->left);
rr->have_ttl = 1;
need16(rr->rdlength, self->at, self->left);
rr->have_rdlength = 1;
rr->rdata_offset = self->at - self->payload;
if (!(rdata_label_sets = _rdata_labels(rr->type))) {
advancexb(rr->rdlength, self->at, self->left);
rr->have_rdata = 1;
return 0;
}
switch (rr->type) {
case CORE_OBJECT_DNS_TYPE_MX:
case CORE_OBJECT_DNS_TYPE_AFSDB:
case CORE_OBJECT_DNS_TYPE_RT:
case CORE_OBJECT_DNS_TYPE_KX:
case CORE_OBJECT_DNS_TYPE_LP:
case CORE_OBJECT_DNS_TYPE_PX:
advancexb(2, self->at, self->left);
break;
case CORE_OBJECT_DNS_TYPE_SIG:
case CORE_OBJECT_DNS_TYPE_RRSIG:
advancexb(18, self->at, self->left);
break;
case CORE_OBJECT_DNS_TYPE_SRV:
advancexb(6, self->at, self->left);
break;
case CORE_OBJECT_DNS_TYPE_NAPTR: {
uint8_t naptr_length;
advancexb(4, self->at, self->left);
need8(naptr_length, self->at, self->left);
advancexb(naptr_length, self->at, self->left);
need8(naptr_length, self->at, self->left);
advancexb(naptr_length, self->at, self->left);
need8(naptr_length, self->at, self->left);
advancexb(naptr_length, self->at, self->left);
} break;
case CORE_OBJECT_DNS_TYPE_HIP: {
uint8_t hit_length;
uint16_t pk_length;
need8(hit_length, self->at, self->left);
advancexb(1, self->at, self->left);
need16(pk_length, self->at, self->left);
advancexb(hit_length, self->at, self->left);
advancexb(pk_length, self->at, self->left);
if (self->at - self->payload >= rr->rdata_offset + rr->rdlength) {
rdata_label_sets = 0;
}
} break;
}
while (rdata_label_sets) {
rr->rdata_labels += _label(self, &label[rr->labels + rr->rdata_labels], labels - rr->labels - rr->rdata_labels);
if (rr->labels + rr->rdata_labels < labels) {
core_object_dns_label_t* l = &label[rr->labels + rr->rdata_labels];
if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
} else {
mlwarning("need more labels, aborting DNS parsing");
return _ERR_NEEDLABELS;
}
rr->rdata_labels++;
if (rr->type == CORE_OBJECT_DNS_TYPE_HIP && self->at - self->payload < rr->rdata_offset + rr->rdlength) {
continue;
}
rdata_label_sets--;
}
if (self->at - self->payload < rr->rdata_offset + rr->rdlength) {
rr->padding_offset = self->at - self->payload;
rr->padding_length = rr->rdlength - (rr->padding_offset - rr->rdata_offset);
advancexb(rr->padding_length, self->at, self->left);
/*
* TODO:
*
* This can indicate padding but we do not set that we have padding
* yet because we need to fully understand all record types before
* that and process valid data after the labels
*
rr->have_padding = 1;
*/
} else if (self->at - self->payload > rr->rdata_offset + rr->rdlength) {
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}
rr->have_rdata = 1;
return 0;
}
// TODO: error here on malformed/truncated? could be quite spammy
return _ERR_MALFORMED;
}

184
src/core/object/dns.h Normal file
View file

@ -0,0 +1,184 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/log.h"
#include "core/object.h"
#ifndef __dnsjit_core_object_dns_h
#define __dnsjit_core_object_dns_h
#include <netinet/in.h>
#include <sys/types.h>
#include "core/object/dns.hh"
#define CORE_OBJECT_DNS_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_DNS, prev) \
, \
0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
}
/*
* 2016-12-09 https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
*/
#define CORE_OBJECT_DNS_CLASS_IN 1
#define CORE_OBJECT_DNS_CLASS_CH 3
#define CORE_OBJECT_DNS_CLASS_HS 4
#define CORE_OBJECT_DNS_CLASS_NONE 254
#define CORE_OBJECT_DNS_CLASS_ANY 255
#define CORE_OBJECT_DNS_TYPE_A 1
#define CORE_OBJECT_DNS_TYPE_NS 2
#define CORE_OBJECT_DNS_TYPE_MD 3
#define CORE_OBJECT_DNS_TYPE_MF 4
#define CORE_OBJECT_DNS_TYPE_CNAME 5
#define CORE_OBJECT_DNS_TYPE_SOA 6
#define CORE_OBJECT_DNS_TYPE_MB 7
#define CORE_OBJECT_DNS_TYPE_MG 8
#define CORE_OBJECT_DNS_TYPE_MR 9
#define CORE_OBJECT_DNS_TYPE_NULL 10
#define CORE_OBJECT_DNS_TYPE_WKS 11
#define CORE_OBJECT_DNS_TYPE_PTR 12
#define CORE_OBJECT_DNS_TYPE_HINFO 13
#define CORE_OBJECT_DNS_TYPE_MINFO 14
#define CORE_OBJECT_DNS_TYPE_MX 15
#define CORE_OBJECT_DNS_TYPE_TXT 16
#define CORE_OBJECT_DNS_TYPE_RP 17
#define CORE_OBJECT_DNS_TYPE_AFSDB 18
#define CORE_OBJECT_DNS_TYPE_X25 19
#define CORE_OBJECT_DNS_TYPE_ISDN 20
#define CORE_OBJECT_DNS_TYPE_RT 21
#define CORE_OBJECT_DNS_TYPE_NSAP 22
#define CORE_OBJECT_DNS_TYPE_NSAP_PTR 23
#define CORE_OBJECT_DNS_TYPE_SIG 24
#define CORE_OBJECT_DNS_TYPE_KEY 25
#define CORE_OBJECT_DNS_TYPE_PX 26
#define CORE_OBJECT_DNS_TYPE_GPOS 27
#define CORE_OBJECT_DNS_TYPE_AAAA 28
#define CORE_OBJECT_DNS_TYPE_LOC 29
#define CORE_OBJECT_DNS_TYPE_NXT 30
#define CORE_OBJECT_DNS_TYPE_EID 31
#define CORE_OBJECT_DNS_TYPE_NIMLOC 32
#define CORE_OBJECT_DNS_TYPE_SRV 33
#define CORE_OBJECT_DNS_TYPE_ATMA 34
#define CORE_OBJECT_DNS_TYPE_NAPTR 35
#define CORE_OBJECT_DNS_TYPE_KX 36
#define CORE_OBJECT_DNS_TYPE_CERT 37
#define CORE_OBJECT_DNS_TYPE_A6 38
#define CORE_OBJECT_DNS_TYPE_DNAME 39
#define CORE_OBJECT_DNS_TYPE_SINK 40
#define CORE_OBJECT_DNS_TYPE_OPT 41
#define CORE_OBJECT_DNS_TYPE_APL 42
#define CORE_OBJECT_DNS_TYPE_DS 43
#define CORE_OBJECT_DNS_TYPE_SSHFP 44
#define CORE_OBJECT_DNS_TYPE_IPSECKEY 45
#define CORE_OBJECT_DNS_TYPE_RRSIG 46
#define CORE_OBJECT_DNS_TYPE_NSEC 47
#define CORE_OBJECT_DNS_TYPE_DNSKEY 48
#define CORE_OBJECT_DNS_TYPE_DHCID 49
#define CORE_OBJECT_DNS_TYPE_NSEC3 50
#define CORE_OBJECT_DNS_TYPE_NSEC3PARAM 51
#define CORE_OBJECT_DNS_TYPE_TLSA 52
#define CORE_OBJECT_DNS_TYPE_SMIMEA 53
#define CORE_OBJECT_DNS_TYPE_HIP 55
#define CORE_OBJECT_DNS_TYPE_NINFO 56
#define CORE_OBJECT_DNS_TYPE_RKEY 57
#define CORE_OBJECT_DNS_TYPE_TALINK 58
#define CORE_OBJECT_DNS_TYPE_CDS 59
#define CORE_OBJECT_DNS_TYPE_CDNSKEY 60
#define CORE_OBJECT_DNS_TYPE_OPENPGPKEY 61
#define CORE_OBJECT_DNS_TYPE_CSYNC 62
#define CORE_OBJECT_DNS_TYPE_SPF 99
#define CORE_OBJECT_DNS_TYPE_UINFO 100
#define CORE_OBJECT_DNS_TYPE_UID 101
#define CORE_OBJECT_DNS_TYPE_GID 102
#define CORE_OBJECT_DNS_TYPE_UNSPEC 103
#define CORE_OBJECT_DNS_TYPE_NID 104
#define CORE_OBJECT_DNS_TYPE_L32 105
#define CORE_OBJECT_DNS_TYPE_L64 106
#define CORE_OBJECT_DNS_TYPE_LP 107
#define CORE_OBJECT_DNS_TYPE_EUI48 108
#define CORE_OBJECT_DNS_TYPE_EUI64 109
#define CORE_OBJECT_DNS_TYPE_TKEY 249
#define CORE_OBJECT_DNS_TYPE_TSIG 250
#define CORE_OBJECT_DNS_TYPE_IXFR 251
#define CORE_OBJECT_DNS_TYPE_AXFR 252
#define CORE_OBJECT_DNS_TYPE_MAILB 253
#define CORE_OBJECT_DNS_TYPE_MAILA 254
#define CORE_OBJECT_DNS_TYPE_ANY 255
#define CORE_OBJECT_DNS_TYPE_URI 256
#define CORE_OBJECT_DNS_TYPE_CAA 257
#define CORE_OBJECT_DNS_TYPE_AVC 258
#define CORE_OBJECT_DNS_TYPE_TA 32768
#define CORE_OBJECT_DNS_TYPE_DLV 32769
#define CORE_OBJECT_DNS_OPCODE_QUERY 0
#define CORE_OBJECT_DNS_OPCODE_IQUERY 1
#define CORE_OBJECT_DNS_OPCODE_STATUS 2
#define CORE_OBJECT_DNS_OPCODE_NOTIFY 4
#define CORE_OBJECT_DNS_OPCODE_UPDATE 5
#define CORE_OBJECT_DNS_RCODE_NOERROR 0
#define CORE_OBJECT_DNS_RCODE_FORMERR 1
#define CORE_OBJECT_DNS_RCODE_SERVFAIL 2
#define CORE_OBJECT_DNS_RCODE_NXDOMAIN 3
#define CORE_OBJECT_DNS_RCODE_NOTIMP 4
#define CORE_OBJECT_DNS_RCODE_REFUSED 5
#define CORE_OBJECT_DNS_RCODE_YXDOMAIN 6
#define CORE_OBJECT_DNS_RCODE_YXRRSET 7
#define CORE_OBJECT_DNS_RCODE_NXRRSET 8
#define CORE_OBJECT_DNS_RCODE_NOTAUTH 9
#define CORE_OBJECT_DNS_RCODE_NOTZONE 10
#define CORE_OBJECT_DNS_RCODE_BADVERS 16
#define CORE_OBJECT_DNS_RCODE_BADSIG 16
#define CORE_OBJECT_DNS_RCODE_BADKEY 17
#define CORE_OBJECT_DNS_RCODE_BADTIME 18
#define CORE_OBJECT_DNS_RCODE_BADMODE 19
#define CORE_OBJECT_DNS_RCODE_BADNAME 20
#define CORE_OBJECT_DNS_RCODE_BADALG 21
#define CORE_OBJECT_DNS_RCODE_BADTRUNC 22
#define CORE_OBJECT_DNS_RCODE_BADCOOKIE 23
#define CORE_OBJECT_DNS_AFSDB_SUBTYPE_AFS3LOCSRV 1
#define CORE_OBJECT_DNS_AFSDB_SUBTYPE_DCENCA_ROOT 2
#define CORE_OBJECT_DNS_DHCID_TYPE_1OCTET 0
#define CORE_OBJECT_DNS_DHCID_TYPE_DATAOCTET 1
#define CORE_OBJECT_DNS_DHCID_TYPE_CLIENT_DUID 2
#define CORE_OBJECT_DNS_EDNS0_OPT_LLQ 1
#define CORE_OBJECT_DNS_EDNS0_OPT_UL 2
#define CORE_OBJECT_DNS_EDNS0_OPT_NSID 3
#define CORE_OBJECT_DNS_EDNS0_OPT_DAU 5
#define CORE_OBJECT_DNS_EDNS0_OPT_DHU 6
#define CORE_OBJECT_DNS_EDNS0_OPT_N3U 7
#define CORE_OBJECT_DNS_EDNS0_OPT_CLIENT_SUBNET 8
#define CORE_OBJECT_DNS_EDNS0_OPT_EXPIRE 9
#define CORE_OBJECT_DNS_EDNS0_OPT_COOKIE 10
#define CORE_OBJECT_DNS_EDNS0_OPT_TCP_KEEPALIVE 11
#define CORE_OBJECT_DNS_EDNS0_OPT_PADDING 12
#define CORE_OBJECT_DNS_EDNS0_OPT_CHAIN 13
#define CORE_OBJECT_DNS_EDNS0_OPT_DEVICEID 26946
#endif

119
src/core/object/dns.hh Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.log")
//lua:require("dnsjit.core.object_h")
typedef struct core_object_dns_label {
uint8_t is_end;
uint8_t have_length;
uint8_t have_offset;
uint8_t have_extension_bits;
uint8_t have_dn;
uint8_t extension_bits;
uint8_t length;
uint16_t offset;
} core_object_dns_label_t;
typedef struct core_object_dns_rr {
uint8_t have_type;
uint8_t have_class;
uint8_t have_ttl;
uint8_t have_rdlength;
uint8_t have_rdata;
uint8_t have_rdata_labels;
uint8_t have_padding;
uint16_t type;
uint16_t class;
uint32_t ttl;
uint16_t rdlength;
size_t labels;
size_t rdata_offset;
size_t rdata_labels;
size_t padding_offset;
size_t padding_length;
} core_object_dns_rr_t;
typedef struct core_object_dns_q {
uint8_t have_type;
uint8_t have_class;
uint16_t type;
uint16_t class;
size_t labels;
} core_object_dns_q_t;
typedef struct core_object_dns {
const core_object_t* obj_prev;
int32_t obj_type;
int includes_dnslen;
const uint8_t *payload, *at;
size_t len, left;
uint8_t have_dnslen;
uint8_t have_id;
uint8_t have_qr;
uint8_t have_opcode;
uint8_t have_aa;
uint8_t have_tc;
uint8_t have_rd;
uint8_t have_ra;
uint8_t have_z;
uint8_t have_ad;
uint8_t have_cd;
uint8_t have_rcode;
uint8_t have_qdcount;
uint8_t have_ancount;
uint8_t have_nscount;
uint8_t have_arcount;
uint16_t dnslen;
uint16_t id;
int8_t qr;
uint8_t opcode;
uint8_t aa;
uint8_t tc;
uint8_t rd;
uint8_t ra;
uint8_t z;
uint8_t ad;
uint8_t cd;
uint8_t rcode;
uint16_t qdcount;
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
} core_object_dns_t;
core_log_t* core_object_dns_log();
core_object_dns_t* core_object_dns_new();
core_object_dns_t* core_object_dns_copy(const core_object_dns_t* self);
void core_object_dns_free(core_object_dns_t* self);
void core_object_dns_reset(core_object_dns_t* self, const core_object_t* obj);
int core_object_dns_parse_header(core_object_dns_t* self);
int core_object_dns_parse_q(core_object_dns_t* self, core_object_dns_q_t* q, core_object_dns_label_t* label, size_t labels);
int core_object_dns_parse_rr(core_object_dns_t* self, core_object_dns_rr_t* rr, core_object_dns_label_t* label, size_t labels);

797
src/core/object/dns.lua Normal file
View file

@ -0,0 +1,797 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.dns
-- Container of a DNS message
-- .SS Parse DNS header and check if query or response
-- local dns = require("dnsjit.core.object.dns").new(payload)
-- if dns:parse_header() == 0 then
-- if dns.qr == 0 then
-- print(dns.id, dns.opcode_tostring(dns.opcode))
-- else
-- print(dns.id, dns.rcode_tostring(dns.rcode))
-- end
-- end
-- .SS Print a DNS payload
-- local dns = require("dnsjit.core.object.dns").new(payload)
-- dns:print()
-- .SS Parse a DNS payload
-- local dns = require("dnsjit.core.object.dns").new(payload)
-- local qs, q_labels, rrs, rr_labels = dns:parse()
-- if qs and q_labels then
-- ...
-- if rrs and rr_labels then
-- ...
-- end
-- end
--
-- The object that describes a DNS message.
-- .SS Attributes
-- .TP
-- includes_dnslen
-- If non-zero then this indicates that the DNS length is included in the
-- payload (for example if the transport is TCP) and will affect parsing of it.
-- .TP
-- have_dnslen
-- Set if the dnslen was included in the payload and could be read.
-- .TP
-- have_id
-- Set if there is a DNS ID.
-- .TP
-- have_qr
-- Set if there is a QR flag.
-- .TP
-- have_opcode
-- Set if there is an OPCODE.
-- .TP
-- have_aa
-- Set if there is a AA flag.
-- .TP
-- have_tc
-- Set if there is a TC flag.
-- .TP
-- have_rd
-- Set if there is a RD flag.
-- .TP
-- have_ra
-- Set if there is a RA flag.
-- .TP
-- have_z
-- Set if there is a Z flag.
-- .TP
-- have_ad
-- Set if there is a AD flag.
-- .TP
-- have_cd
-- Set if there is a CD flag.
-- .TP
-- have_rcode
-- Set if there is a RCODE.
-- .TP
-- have_qdcount
-- Set if there is an QDCOUNT.
-- .TP
-- have_ancount
-- Set if there is an ANCOUNT.
-- .TP
-- have_nscount
-- Set if there is a NSCOUNT.
-- .TP
-- have_arcount
-- Set if there is an ARCOUNT.
-- .TP
-- dnslen
-- The DNS length found in the payload.
-- .TP
-- id
-- The DNS ID.
-- .TP
-- qr
-- The QR flag.
-- .TP
-- opcode
-- The OPCODE.
-- .TP
-- aa
-- The AA flag.
-- .TP
-- tc
-- The TC flag.
-- .TP
-- rd
-- The RD flag.
-- .TP
-- ra
-- The RA flag.
-- .TP
-- z
-- The Z flag.
-- .TP
-- ad
-- The AD flag.
-- .TP
-- cd
-- The CD flag.
-- .TP
-- rcode
-- The RCODE.
-- .TP
-- qdcount
-- The QDCOUNT.
-- .TP
-- ancount
-- The ANCOUNT.
-- .TP
-- nscount
-- The NSCOUNT.
-- .TP
-- arcount
-- The ARCOUNT.
-- .SS Constants
-- The following tables exists for DNS parameters, taken from
-- .I https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
-- on the 2016-12-09.
-- .LP
-- .IR CLASS ,
-- .IR CLASS_STR ,
-- .IR TYPE ,
-- .IR TYPE_STR ,
-- .IR OPCODE ,
-- .IR OPCODE_STR ,
-- .IR RCODE ,
-- .IR RCODE_STR ,
-- .IR AFSDB ,
-- .IR AFSDB_STR ,
-- .IR DHCID ,
-- .IR DHCID_STR ,
-- .IR ENDS0 ,
-- .IR ENDS0_STR
-- .LP
-- The
-- .I *_STR
-- tables can be used to get a textual representation of the numbers, see also
-- .IR class_tostring() ,
-- .IR type_tostring() ,
-- .IR opcode_tostring() ,
-- .IR rcode_tostring() ,
-- .IR afsdb_tostring() ,
-- .I dhcid_tostring()
-- and
-- .IR edns0_tostring() .
module(...,package.seeall)
require("dnsjit.core.object.dns_h")
local label = require("dnsjit.core.object.dns.label")
local Q = require("dnsjit.core.object.dns.q")
local RR = require("dnsjit.core.object.dns.rr")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_dns_t"
local core_object_dns_t
local Dns = {
CLASS = {
IN = 1,
CH = 3,
HS = 4,
NONE = 254,
ANY = 255,
},
TYPE = {
A = 1,
NS = 2,
MD = 3,
MF = 4,
CNAME = 5,
SOA = 6,
MB = 7,
MG = 8,
MR = 9,
NULL = 10,
WKS = 11,
PTR = 12,
HINFO = 13,
MINFO = 14,
MX = 15,
TXT = 16,
RP = 17,
AFSDB = 18,
X25 = 19,
ISDN = 20,
RT = 21,
NSAP = 22,
NSAP_PTR = 23,
SIG = 24,
KEY = 25,
PX = 26,
GPOS = 27,
AAAA = 28,
LOC = 29,
NXT = 30,
EID = 31,
NIMLOC = 32,
SRV = 33,
ATMA = 34,
NAPTR = 35,
KX = 36,
CERT = 37,
A6 = 38,
DNAME = 39,
SINK = 40,
OPT = 41,
APL = 42,
DS = 43,
SSHFP = 44,
IPSECKEY = 45,
RRSIG = 46,
NSEC = 47,
DNSKEY = 48,
DHCID = 49,
NSEC3 = 50,
NSEC3PARAM = 51,
TLSA = 52,
SMIMEA = 53,
HIP = 55,
NINFO = 56,
RKEY = 57,
TALINK = 58,
CDS = 59,
CDNSKEY = 60,
OPENPGPKEY = 61,
CSYNC = 62,
SPF = 99,
UINFO = 100,
UID = 101,
GID = 102,
UNSPEC = 103,
NID = 104,
L32 = 105,
L64 = 106,
LP = 107,
EUI48 = 108,
EUI64 = 109,
TKEY = 249,
TSIG = 250,
IXFR = 251,
AXFR = 252,
MAILB = 253,
MAILA = 254,
ANY = 255,
URI = 256,
CAA = 257,
AVC = 258,
TA = 32768,
DLV = 32769,
},
OPCODE = {
QUERY = 0,
IQUERY = 1,
STATUS = 2,
NOTIFY = 4,
UPDATE = 5,
},
RCODE = {
NOERROR = 0,
FORMERR = 1,
SERVFAIL = 2,
NXDOMAIN = 3,
NOTIMP = 4,
REFUSED = 5,
YXDOMAIN = 6,
YXRRSET = 7,
NXRRSET = 8,
NOTAUTH = 9,
NOTZONE = 10,
BADVERS = 16,
BADSIG = 16,
BADKEY = 17,
BADTIME = 18,
BADMODE = 19,
BADNAME = 20,
BADALG = 21,
BADTRUNC = 22,
BADCOOKIE = 23,
},
AFSDB = {
SUBTYPE_AFS3LOCSRV = 1,
SUBTYPE_DCENCA_ROOT = 2,
},
DHCID = {
TYPE_1OCTET = 0,
TYPE_DATAOCTET = 1,
TYPE_CLIENT_DUID = 2,
},
EDNS0 = {
OPT_LLQ = 1,
OPT_UL = 2,
OPT_NSID = 3,
OPT_DAU = 5,
OPT_DHU = 6,
OPT_N3U = 7,
OPT_CLIENT_SUBNET = 8,
OPT_EXPIRE = 9,
OPT_COOKIE = 10,
OPT_TCP_KEEPALIVE = 11,
OPT_PADDING = 12,
OPT_CHAIN = 13,
OPT_DEVICEID = 26946,
},
}
local _CLASS = {}
_CLASS[Dns.CLASS.IN] = "IN"
_CLASS[Dns.CLASS.CH] = "CH"
_CLASS[Dns.CLASS.HS] = "HS"
_CLASS[Dns.CLASS.NONE] = "NONE"
_CLASS[Dns.CLASS.ANY] = "ANY"
local _TYPE = {}
_TYPE[Dns.TYPE.A] = "A"
_TYPE[Dns.TYPE.NS] = "NS"
_TYPE[Dns.TYPE.MD] = "MD"
_TYPE[Dns.TYPE.MF] = "MF"
_TYPE[Dns.TYPE.CNAME] = "CNAME"
_TYPE[Dns.TYPE.SOA] = "SOA"
_TYPE[Dns.TYPE.MB] = "MB"
_TYPE[Dns.TYPE.MG] = "MG"
_TYPE[Dns.TYPE.MR] = "MR"
_TYPE[Dns.TYPE.NULL] = "NULL"
_TYPE[Dns.TYPE.WKS] = "WKS"
_TYPE[Dns.TYPE.PTR] = "PTR"
_TYPE[Dns.TYPE.HINFO] = "HINFO"
_TYPE[Dns.TYPE.MINFO] = "MINFO"
_TYPE[Dns.TYPE.MX] = "MX"
_TYPE[Dns.TYPE.TXT] = "TXT"
_TYPE[Dns.TYPE.RP] = "RP"
_TYPE[Dns.TYPE.AFSDB] = "AFSDB"
_TYPE[Dns.TYPE.X25] = "X25"
_TYPE[Dns.TYPE.ISDN] = "ISDN"
_TYPE[Dns.TYPE.RT] = "RT"
_TYPE[Dns.TYPE.NSAP] = "NSAP"
_TYPE[Dns.TYPE.NSAP_PTR] = "NSAP_PTR"
_TYPE[Dns.TYPE.SIG] = "SIG"
_TYPE[Dns.TYPE.KEY] = "KEY"
_TYPE[Dns.TYPE.PX] = "PX"
_TYPE[Dns.TYPE.GPOS] = "GPOS"
_TYPE[Dns.TYPE.AAAA] = "AAAA"
_TYPE[Dns.TYPE.LOC] = "LOC"
_TYPE[Dns.TYPE.NXT] = "NXT"
_TYPE[Dns.TYPE.EID] = "EID"
_TYPE[Dns.TYPE.NIMLOC] = "NIMLOC"
_TYPE[Dns.TYPE.SRV] = "SRV"
_TYPE[Dns.TYPE.ATMA] = "ATMA"
_TYPE[Dns.TYPE.NAPTR] = "NAPTR"
_TYPE[Dns.TYPE.KX] = "KX"
_TYPE[Dns.TYPE.CERT] = "CERT"
_TYPE[Dns.TYPE.A6] = "A6"
_TYPE[Dns.TYPE.DNAME] = "DNAME"
_TYPE[Dns.TYPE.SINK] = "SINK"
_TYPE[Dns.TYPE.OPT] = "OPT"
_TYPE[Dns.TYPE.APL] = "APL"
_TYPE[Dns.TYPE.DS] = "DS"
_TYPE[Dns.TYPE.SSHFP] = "SSHFP"
_TYPE[Dns.TYPE.IPSECKEY] = "IPSECKEY"
_TYPE[Dns.TYPE.RRSIG] = "RRSIG"
_TYPE[Dns.TYPE.NSEC] = "NSEC"
_TYPE[Dns.TYPE.DNSKEY] = "DNSKEY"
_TYPE[Dns.TYPE.DHCID] = "DHCID"
_TYPE[Dns.TYPE.NSEC3] = "NSEC3"
_TYPE[Dns.TYPE.NSEC3PARAM] = "NSEC3PARAM"
_TYPE[Dns.TYPE.TLSA] = "TLSA"
_TYPE[Dns.TYPE.SMIMEA] = "SMIMEA"
_TYPE[Dns.TYPE.HIP] = "HIP"
_TYPE[Dns.TYPE.NINFO] = "NINFO"
_TYPE[Dns.TYPE.RKEY] = "RKEY"
_TYPE[Dns.TYPE.TALINK] = "TALINK"
_TYPE[Dns.TYPE.CDS] = "CDS"
_TYPE[Dns.TYPE.CDNSKEY] = "CDNSKEY"
_TYPE[Dns.TYPE.OPENPGPKEY] = "OPENPGPKEY"
_TYPE[Dns.TYPE.CSYNC] = "CSYNC"
_TYPE[Dns.TYPE.SPF] = "SPF"
_TYPE[Dns.TYPE.UINFO] = "UINFO"
_TYPE[Dns.TYPE.UID] = "UID"
_TYPE[Dns.TYPE.GID] = "GID"
_TYPE[Dns.TYPE.UNSPEC] = "UNSPEC"
_TYPE[Dns.TYPE.NID] = "NID"
_TYPE[Dns.TYPE.L32] = "L32"
_TYPE[Dns.TYPE.L64] = "L64"
_TYPE[Dns.TYPE.LP] = "LP"
_TYPE[Dns.TYPE.EUI48] = "EUI48"
_TYPE[Dns.TYPE.EUI64] = "EUI64"
_TYPE[Dns.TYPE.TKEY] = "TKEY"
_TYPE[Dns.TYPE.TSIG] = "TSIG"
_TYPE[Dns.TYPE.IXFR] = "IXFR"
_TYPE[Dns.TYPE.AXFR] = "AXFR"
_TYPE[Dns.TYPE.MAILB] = "MAILB"
_TYPE[Dns.TYPE.MAILA] = "MAILA"
_TYPE[Dns.TYPE.ANY] = "ANY"
_TYPE[Dns.TYPE.URI] = "URI"
_TYPE[Dns.TYPE.CAA] = "CAA"
_TYPE[Dns.TYPE.AVC] = "AVC"
_TYPE[Dns.TYPE.TA] = "TA"
_TYPE[Dns.TYPE.DLV] = "DLV"
local _OPCODE = {}
_OPCODE[Dns.OPCODE.QUERY] = "QUERY"
_OPCODE[Dns.OPCODE.IQUERY] = "IQUERY"
_OPCODE[Dns.OPCODE.STATUS] = "STATUS"
_OPCODE[Dns.OPCODE.NOTIFY] = "NOTIFY"
_OPCODE[Dns.OPCODE.UPDATE] = "UPDATE"
local _RCODE = {}
_RCODE[Dns.RCODE.NOERROR] = "NOERROR"
_RCODE[Dns.RCODE.FORMERR] = "FORMERR"
_RCODE[Dns.RCODE.SERVFAIL] = "SERVFAIL"
_RCODE[Dns.RCODE.NXDOMAIN] = "NXDOMAIN"
_RCODE[Dns.RCODE.NOTIMP] = "NOTIMP"
_RCODE[Dns.RCODE.REFUSED] = "REFUSED"
_RCODE[Dns.RCODE.YXDOMAIN] = "YXDOMAIN"
_RCODE[Dns.RCODE.YXRRSET] = "YXRRSET"
_RCODE[Dns.RCODE.NXRRSET] = "NXRRSET"
_RCODE[Dns.RCODE.NOTAUTH] = "NOTAUTH"
_RCODE[Dns.RCODE.NOTZONE] = "NOTZONE"
_RCODE[Dns.RCODE.BADVERS] = "BADVERS"
_RCODE[Dns.RCODE.BADSIG] = "BADSIG"
_RCODE[Dns.RCODE.BADKEY] = "BADKEY"
_RCODE[Dns.RCODE.BADTIME] = "BADTIME"
_RCODE[Dns.RCODE.BADMODE] = "BADMODE"
_RCODE[Dns.RCODE.BADNAME] = "BADNAME"
_RCODE[Dns.RCODE.BADALG] = "BADALG"
_RCODE[Dns.RCODE.BADTRUNC] = "BADTRUNC"
_RCODE[Dns.RCODE.BADCOOKIE] = "BADCOOKIE"
local _AFSDB = {}
_AFSDB[Dns.AFSDB.SUBTYPE_AFS3LOCSRV] = "SUBTYPE_AFS3LOCSRV"
_AFSDB[Dns.AFSDB.SUBTYPE_DCENCA_ROOT] = "SUBTYPE_DCENCA_ROOT"
local _DHCID = {}
_DHCID[Dns.DHCID.TYPE_1OCTET] = "TYPE_1OCTET"
_DHCID[Dns.DHCID.TYPE_DATAOCTET] = "TYPE_DATAOCTET"
_DHCID[Dns.DHCID.TYPE_CLIENT_DUID] = "TYPE_CLIENT_DUID"
local _EDNS0 = {}
_EDNS0[Dns.EDNS0.OPT_LLQ] = "OPT_LLQ"
_EDNS0[Dns.EDNS0.OPT_UL] = "OPT_UL"
_EDNS0[Dns.EDNS0.OPT_NSID] = "OPT_NSID"
_EDNS0[Dns.EDNS0.OPT_DAU] = "OPT_DAU"
_EDNS0[Dns.EDNS0.OPT_DHU] = "OPT_DHU"
_EDNS0[Dns.EDNS0.OPT_N3U] = "OPT_N3U"
_EDNS0[Dns.EDNS0.OPT_CLIENT_SUBNET] = "OPT_CLIENT_SUBNET"
_EDNS0[Dns.EDNS0.OPT_EXPIRE] = "OPT_EXPIRE"
_EDNS0[Dns.EDNS0.OPT_COOKIE] = "OPT_COOKIE"
_EDNS0[Dns.EDNS0.OPT_TCP_KEEPALIVE] = "OPT_TCP_KEEPALIVE"
_EDNS0[Dns.EDNS0.OPT_PADDING] = "OPT_PADDING"
_EDNS0[Dns.EDNS0.OPT_CHAIN] = "OPT_CHAIN"
_EDNS0[Dns.EDNS0.OPT_DEVICEID] = "OPT_DEVICEID"
Dns.CLASS_STR = _CLASS
Dns.TYPE_STR = _TYPE
Dns.OPCODE_STR = _OPCODE
Dns.RCODE_STR = _RCODE
Dns.AFSDB_STR = _AFSDB
Dns.DHCID_STR = _DHCID
Dns.EDNS0_STR = _EDNS0
-- Create a new DNS object, optionally on-top of another object.
function Dns.new(obj)
local self = C.core_object_dns_new()
self.obj_prev = obj
ffi.gc(self, C.core_object_dns_free)
return self
end
-- Return the textual type of the object.
function Dns:type()
return "dns"
end
-- Return the previous object.
function Dns:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Dns:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Dns:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Dns:copy()
return C.core_object_dns_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Dns:free()
C.core_object_dns_free(self)
end
-- Return the Log object to control logging of this module.
function Dns:log()
return C.core_object_dns_log()
end
-- Begin parsing the underlaying object, first the header is parsed then
-- optionally continue calling
-- .IR parse_q ()
-- for the number of questions (see
-- .IR qdcount ).
-- After that continue calling
-- .IR parse_rr ()
-- for the number of answers, authorities and additionals resource records
-- (see
-- .IR ancount ", "
-- .I nscount
-- and
-- .IR arcount ).
-- Returns 0 on success or negative integer on error which can be for
-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
function Dns:parse_header()
return C.core_object_dns_parse_header(self)
end
-- Parse the next resource record as a question.
-- Returns 0 on success or negative integer on error which can be for
-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
function Dns:parse_q(q, labels, num_labels)
return C.core_object_dns_parse_q(self, q, labels, num_labels)
end
-- Parse the next resource record.
-- Returns 0 on success or negative integer on error which can be for
-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
function Dns:parse_rr(rr, labels, num_labels)
return C.core_object_dns_parse_rr(self, rr, labels, num_labels)
end
-- Begin parsing the underlaying object using
-- .IR parse_header "(), "
-- .IR parse_q ()
-- and
-- .IR parse_rr ().
-- The optional
-- .I num_labels
-- can be used to set a specific number of labels used for each question
-- and resource record (default 16).
-- Returns result code, an array of questions, an array of question labels,
-- an array of resource records and an array of resource records labels.
-- Result code is 0 on success or negative integer on error which can be for
-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
function Dns:parse(num_labels)
local qs, qls, rrs, rrls = {}, {}, {}, {}
if num_labels == nil then
num_labels = 16
end
ret = self:parse_header()
if ret ~= 0 then
return ret, qs, qls, rrs, rrls
end
for n = 1, self.qdcount do
local labels = label.new(num_labels)
local q = Q.new()
local ret = C.core_object_dns_parse_q(self, q, labels, num_labels)
if ret ~= 0 then
return ret, qs, qls, rrs, rrls
end
table.insert(qs, q)
table.insert(qls, labels)
end
for n = 1, self.ancount do
local labels = label.new(num_labels)
local rr = RR.new()
local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
if ret ~= 0 then
return ret, qs, qls, rrs, rrls
end
table.insert(rrs, rr)
table.insert(rrls, labels)
end
for n = 1, self.nscount do
local labels = label.new(num_labels)
local rr = RR.new()
local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
if ret ~= 0 then
return ret, qs, qls, rrs, rrls
end
table.insert(rrs, rr)
table.insert(rrls, labels)
end
for n = 1, self.arcount do
local labels = label.new(num_labels)
local rr = RR.new()
local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
if ret ~= 0 then
return ret, qs, qls, rrs, rrls
end
table.insert(rrs, rr)
table.insert(rrls, labels)
end
return 0, qs, qls, rrs, rrls
end
-- Begin parsing the underlaying object using
-- .IR parse_header "(), "
-- .IR parse_q ()
-- and
-- .IR parse_rr (),
-- and print it's content.
-- The optional
-- .I num_labels
-- can be used to set a specific number of labels used for each question
-- and resource record (default 16).
function Dns:print(num_labels)
if num_labels == nil then
num_labels = 16
end
local labels = label.new(num_labels)
local q = Q.new()
local rr = RR.new()
if self:parse_header() ~= 0 then
return
end
local flags = {}
if self.have_aa and self.aa == 1 then
table.insert(flags, "AA")
end
if self.have_tc and self.tc == 1 then
table.insert(flags, "TC")
end
if self.have_rd and self.rd == 1 then
table.insert(flags, "RD")
end
if self.have_ra and self.ra == 1 then
table.insert(flags, "RA")
end
if self.have_z and self.z == 1 then
table.insert(flags, "Z")
end
if self.have_ad and self.ad == 1 then
table.insert(flags, "AD")
end
if self.have_cd and self.cd == 1 then
table.insert(flags, "CD")
end
print("id:", self.id)
print("", "qr:", self.qr)
print("", "opcode:", Dns.opcode_tostring(self.opcode))
print("", "flags:", table.concat(flags, " "))
print("", "rcode:", Dns.rcode_tostring(self.rcode))
print("", "qdcount:", self.qdcount)
print("", "ancount:", self.ancount)
print("", "nscount:", self.nscount)
print("", "arcount:", self.arcount)
if self.qdcount > 0 then
print("questions:", "class", "type", "labels")
for n = 1, self.qdcount do
if C.core_object_dns_parse_q(self, q, labels, num_labels) ~= 0 then
return
end
print("", Dns.class_tostring(q.class), Dns.type_tostring(q.type), label.tooffstr(self, labels, num_labels))
end
end
if self.ancount > 0 then
print("answers:", "class", "type", "ttl", "labels", "RR labels")
for n = 1, self.ancount do
if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
return
end
if rr.rdata_labels == 0 then
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
else
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
end
end
end
if self.nscount > 0 then
print("authorities:", "class", "type", "ttl", "labels", "RR labels")
for n = 1, self.nscount do
if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
return
end
if rr.rdata_labels == 0 then
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
else
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
end
end
end
if self.arcount > 0 then
print("additionals:", "class", "type", "ttl", "labels", "RR labels")
for n = 1, self.arcount do
if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
return
end
if rr.rdata_labels == 0 then
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
else
print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
end
end
end
end
-- Return the textual name for a class.
function Dns.class_tostring(class)
if Dns.CLASS_STR[class] == nil then
return "UNKNOWN("..class..")"
end
return Dns.CLASS_STR[class]
end
-- Return the textual name for a type.
function Dns.type_tostring(type)
if Dns.TYPE_STR[type] == nil then
return "UNKNOWN("..type..")"
end
return Dns.TYPE_STR[type]
end
-- Return the textual name for an opcode.
function Dns.opcode_tostring(opcode)
if Dns.OPCODE_STR[opcode] == nil then
return "UNKNOWN("..opcode..")"
end
return Dns.OPCODE_STR[opcode]
end
-- Return the textual name for a rcode.
function Dns.rcode_tostring(rcode)
if Dns.RCODE_STR[rcode] == nil then
return "UNKNOWN("..rcode..")"
end
return Dns.RCODE_STR[rcode]
end
-- Return the textual name for an afsdb subtype.
function Dns.afsdb_tostring(afsdb)
if Dns.AFSDB_STR[afsdb] == nil then
return "UNKNOWN("..afsdb..")"
end
return Dns.AFSDB_STR[afsdb]
end
-- Return the textual name for a dhcid type.
function Dns.dhcid_tostring(dhcid)
if Dns.DHCID_STR[dhcid] == nil then
return "UNKNOWN("..dhcid..")"
end
return Dns.DHCID_STR[dhcid]
end
-- Return the textual name for an EDNS0 OPT record.
function Dns.edns0_tostring(edns0)
if Dns.EDNS0_STR[edns0] == nil then
return "UNKNOWN("..edns0..")"
end
return Dns.EDNS0_STR[edns0]
end
core_object_dns_t = ffi.metatype(t_name, { __index = Dns })
-- dnsjit.core.object (3),
-- dnsjit.core.object.payload (3),
-- dnsjit.core.object.dns.label (3),
-- dnsjit.core.object.dns.q (3),
-- dnsjit.core.object.dns.rr (3)
return Dns

View file

@ -0,0 +1,118 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.dns.label
-- Container of a DNS label
--
-- The object that describes a DNS label.
-- To extract a domain name label first check that
-- .I have_dn
-- is set, then use
-- .I "offset + 1"
-- to indicate where in the payload the label start and
-- .I length
-- for how many bytes long it is.
-- .SS Attributes
-- .TP
-- is_end
-- .TP
-- have_length
-- Set if there is a length.
-- .TP
-- have_offset
-- Set if there is an offset.
-- .TP
-- have_extension_bits
-- Set if there is extension bits.
-- .TP
-- have_dn
-- Set if the label contained a domain name.
-- .TP
-- extension_bits
-- The extension bits.
-- .TP
-- length
-- The length of the domain name.
-- .TP
-- offset
-- If
-- .I have_dn
-- is set then this contains the offset within the payload to where this label
-- start otherwise it contains the offset to another label.
module(...,package.seeall)
require("dnsjit.core.object.dns_h")
local ffi = require("ffi")
local Label = {}
-- Create a new array of labels.
function Label.new(size)
return ffi.new("core_object_dns_label_t[?]", size)
end
-- Returns labels as a string and an offset to the next label.
-- The string may be nil if the first label was an offset.
-- The offset may be nil if the last label was an extension bits or end marker.
function Label.tostring(dns, labels, num_labels, offset_labels)
if offset_labels == nil then
offset_labels = 0
end
local dn
for n = 1, tonumber(num_labels) do
local label = labels[n - 1 + offset_labels]
if label.have_dn == 1 then
if dn == nil then
dn = ""
end
dn = dn .. ffi.string(dns.payload + label.offset + 1, label.length) .. "."
elseif label.have_offset == 1 then
return dn, label.offset
else
return dn, nil
end
end
return dn, nil
end
-- Returns labels as a string which also includes a textual notation of the
-- offset in the form of
-- .IR "<offset>label" .
function Label.tooffstr(dns, labels, num_labels, offset_labels)
if offset_labels == nil then
offset_labels = 0
end
local dn = ""
for n = 1, tonumber(num_labels) do
local label = labels[n - 1 + offset_labels]
if label.have_dn == 1 then
dn = dn .. "<" .. tonumber(label.offset) .. ">" .. ffi.string(dns.payload + label.offset + 1, label.length) .. "."
elseif label.have_offset == 1 then
dn = dn .. "<" .. tonumber(label.offset) .. ">"
break
else
break
end
end
return dn
end
-- dnsjit.core.object.dns (3)
return Label

52
src/core/object/dns/q.lua Normal file
View file

@ -0,0 +1,52 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.dns.q
-- Container of a DNS question
--
-- The object that describes a DNS question.
-- .SS Attributes
-- .TP
-- have_type
-- Set if there is a type.
-- .TP
-- have_class
-- Set if there is a class.
-- .TP
-- type
-- The type.
-- .TP
-- class
-- The class.
-- .TP
-- labels
-- The number of labels found in the question.
module(...,package.seeall)
require("dnsjit.core.object.dns_h")
local ffi = require("ffi")
local Q = {}
-- Create a new question.
function Q.new(size)
return ffi.new("core_object_dns_q_t")
end
-- dnsjit.core.object.dns (3)
return Q

View file

@ -0,0 +1,85 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.dns.rr
-- Container of a DNS resource record
--
-- The object that describes a DNS resource record.
-- .SS Attributes
-- .TP
-- have_type
-- Set if there is a type.
-- .TP
-- have_class
-- Set if there is a class.
-- .TP
-- have_ttl
-- Set if there is a ttl.
-- .TP
-- have_rdlength
-- Set if there is a rdlength.
-- .TP
-- have_rdata
-- Set if there is resource record data.
-- .TP
-- have_rdata_labels
-- Set if there are any labels within the rdata.
-- .TP
-- have_padding
-- Set if there is padding.
-- .TP
-- type
-- The type.
-- .TP
-- class
-- The class.
-- .TP
-- ttl
-- The TTL.
-- .TP
-- rdlength
-- The resource record data length.
-- .TP
-- labels
-- The number of labels found in the record.
-- .TP
-- rdata_offset
-- The offset within the payload for the resource record data.
-- .TP
-- rdata_labels
-- The number of labels found inside the resource record data.
-- .TP
-- padding_offset
-- The offset within the payload where the padding starts.
-- .TP
-- padding_length
-- The length of the padding.
module(...,package.seeall)
require("dnsjit.core.object.dns_h")
local ffi = require("ffi")
local Rr = {}
-- Create a new resource record.
function Rr.new()
return ffi.new("core_object_dns_rr_t")
end
-- dnsjit.core.object.dns (3)
return Rr

45
src/core/object/ether.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/ether.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_ether_t* core_object_ether_copy(const core_object_ether_t* self)
{
core_object_ether_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_ether_t)));
memcpy(copy, self, sizeof(core_object_ether_t));
copy->obj_prev = 0;
return copy;
}
void core_object_ether_free(core_object_ether_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/ether.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_ether_h
#define __dnsjit_core_object_ether_h
#include <stddef.h>
#include "core/object/ether.hh"
#define CORE_OBJECT_ETHER_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_ETHER, prev) \
, \
{ 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, 0 \
}
#endif

33
src/core/object/ether.hh Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_ether {
const core_object_t* obj_prev;
int32_t obj_type;
uint8_t dhost[6];
uint8_t shost[6];
uint16_t type;
} core_object_ether_t;
core_object_ether_t* core_object_ether_copy(const core_object_ether_t* self);
void core_object_ether_free(core_object_ether_t* self);

78
src/core/object/ether.lua Normal file
View file

@ -0,0 +1,78 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.ether
-- Ether part of a packet
--
-- The ether part of a packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- dhost
-- The destination ether address.
-- .TP
-- shost
-- The source ether address.
-- .TP
-- type
-- The packet type ID field / EtherType field.
module(...,package.seeall)
require("dnsjit.core.object.ether_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_ether_t"
local core_object_ether_t
local Ether = {}
-- Return the textual type of the object.
function Ether:type()
return "ether"
end
-- Return the previous object.
function Ether:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Ether:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Ether:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Ether:copy()
return C.core_object_ether_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Ether:free()
C.core_object_ether_free(self)
end
core_object_ether_t = ffi.metatype(t_name, { __index = Ether })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Ether

45
src/core/object/gre.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/gre.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_gre_t* core_object_gre_copy(const core_object_gre_t* self)
{
core_object_gre_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_gre_t)));
memcpy(copy, self, sizeof(core_object_gre_t));
copy->obj_prev = 0;
return copy;
}
void core_object_gre_free(core_object_gre_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/gre.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_gre_h
#define __dnsjit_core_object_gre_h
#include <stddef.h>
#include "core/object/gre.hh"
#define CORE_OBJECT_GRE_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_GRE, prev) \
, \
0, 0, 0, 0, 0 \
}
#endif

37
src/core/object/gre.hh Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_gre {
const core_object_t* obj_prev;
int32_t obj_type;
uint16_t gre_flags;
uint16_t ether_type;
uint16_t checksum;
uint16_t offset;
uint32_t key;
uint32_t sequence;
// TODO: routing list, check RFC 1701.
} core_object_gre_t;
core_object_gre_t* core_object_gre_copy(const core_object_gre_t* self);
void core_object_gre_free(core_object_gre_t* self);

87
src/core/object/gre.lua Normal file
View file

@ -0,0 +1,87 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.gre
-- Generic Routing Encapsulation (GRE) part of a packet
--
-- The GRE part of a packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- See RFC 1701.
-- .SS Attributes
-- .TP
-- gre_flags
-- The GRE flags.
-- .TP
-- ether_type
-- The protocol type of the payload packet.
-- .TP
-- checksum
-- The checksum of the GRE header and the payload packet.
-- .TP
-- key
-- The Key field contains a four octet number which was inserted by
-- the encapsulator.
-- .TP
-- sequence
-- The Sequence Number field contains an unsigned 32 bit integer which is
-- inserted by the encapsulator.
module(...,package.seeall)
require("dnsjit.core.object.gre_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_gre_t"
local core_object_gre_t
local Gre = {}
-- Return the textual type of the object.
function Gre:type()
return "gre"
end
-- Return the previous object.
function Gre:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Gre:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Gre:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Gre:copy()
return C.core_object_gre_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Gre:free()
C.core_object_gre_free(self)
end
core_object_gre_t = ffi.metatype(t_name, { __index = Gre })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Gre

45
src/core/object/icmp.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/icmp.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_icmp_t* core_object_icmp_copy(const core_object_icmp_t* self)
{
core_object_icmp_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_icmp_t)));
memcpy(copy, self, sizeof(core_object_icmp_t));
copy->obj_prev = 0;
return copy;
}
void core_object_icmp_free(core_object_icmp_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/icmp.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_icmp_h
#define __dnsjit_core_object_icmp_h
#include <stddef.h>
#include "core/object/icmp.hh"
#define CORE_OBJECT_ICMP_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_ICMP, prev) \
, \
0, 0, 0 \
}
#endif

33
src/core/object/icmp.hh Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_icmp {
const core_object_t* obj_prev;
int32_t obj_type;
uint8_t type;
uint8_t code;
uint16_t cksum;
} core_object_icmp_t;
core_object_icmp_t* core_object_icmp_copy(const core_object_icmp_t* self);
void core_object_icmp_free(core_object_icmp_t* self);

78
src/core/object/icmp.lua Normal file
View file

@ -0,0 +1,78 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.icmp
-- An ICMP packet
--
-- An ICMP packet which is usually at the top of the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- type
-- The type of ICMP message.
-- .TP
-- code
-- The (response/error) code for the ICMP type message.
-- .TP
-- cksum
-- The ICMP checksum.
module(...,package.seeall)
require("dnsjit.core.object.icmp_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_icmp_t"
local core_object_icmp_t
local Icmp = {}
-- Return the textual type of the object.
function Icmp:type()
return "icmp"
end
-- Return the previous object.
function Icmp:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Icmp:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Icmp:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Icmp:copy()
return C.core_object_icmp_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Icmp:free()
C.core_object_icmp_free(self)
end
core_object_icmp_t = ffi.metatype(t_name, { __index = Icmp })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Icmp

45
src/core/object/icmp6.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/icmp6.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_icmp6_t* core_object_icmp6_copy(const core_object_icmp6_t* self)
{
core_object_icmp6_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_icmp6_t)));
memcpy(copy, self, sizeof(core_object_icmp6_t));
copy->obj_prev = 0;
return copy;
}
void core_object_icmp6_free(core_object_icmp6_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/icmp6.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_icmp6_h
#define __dnsjit_core_object_icmp6_h
#include <stddef.h>
#include "core/object/icmp6.hh"
#define CORE_OBJECT_ICMP6_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_ICMP6, prev) \
, \
0, 0, 0 \
}
#endif

33
src/core/object/icmp6.hh Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_icmp6 {
const core_object_t* obj_prev;
int32_t obj_type;
uint8_t type;
uint8_t code;
uint16_t cksum;
} core_object_icmp6_t;
core_object_icmp6_t* core_object_icmp6_copy(const core_object_icmp6_t* self);
void core_object_icmp6_free(core_object_icmp6_t* self);

78
src/core/object/icmp6.lua Normal file
View file

@ -0,0 +1,78 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.icmp6
-- An ICMPv6 packet
--
-- An ICMPv6 packet which is usually at the top of the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- type
-- The type of ICMPv6 message.
-- .TP
-- code
-- The (response/error) code for the ICMPv6 type message.
-- .TP
-- cksum
-- The ICMPv6 checksum.
module(...,package.seeall)
require("dnsjit.core.object.icmp6_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_icmp6_t"
local core_object_icmp6_t
local Icmp6 = {}
-- Return the textual type of the object.
function Icmp6:type()
return "icmp6"
end
-- Return the previous object.
function Icmp6:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Icmp6:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Icmp6:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Icmp6:copy()
return C.core_object_icmp6_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Icmp6:free()
C.core_object_icmp6_free(self)
end
core_object_icmp6_t = ffi.metatype(t_name, { __index = Icmp6 })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Icmp6

45
src/core/object/ieee802.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/ieee802.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_ieee802_t* core_object_ieee802_copy(const core_object_ieee802_t* self)
{
core_object_ieee802_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_ieee802_t)));
memcpy(copy, self, sizeof(core_object_ieee802_t));
copy->obj_prev = 0;
return copy;
}
void core_object_ieee802_free(core_object_ieee802_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/ieee802.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_ieee802_h
#define __dnsjit_core_object_ieee802_h
#include <stddef.h>
#include "core/object/ieee802.hh"
#define CORE_OBJECT_IEEE802_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_IEEE802, prev) \
, \
0, 0, 0, 0, 0 \
}
#endif

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_ieee802 {
const core_object_t* obj_prev;
int32_t obj_type;
uint16_t tpid;
uint8_t pcp;
uint8_t dei;
uint8_t vid;
uint16_t ether_type;
} core_object_ieee802_t;
core_object_ieee802_t* core_object_ieee802_copy(const core_object_ieee802_t* self);
void core_object_ieee802_free(core_object_ieee802_t* self);

View file

@ -0,0 +1,84 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.ieee802
-- IEEE802 part of a packet
--
-- The IEEE802 part of a packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- tpid
-- Tag protocol identifier.
-- .TP
-- pcp
-- Priority code point.
-- .TP
-- dei
-- Drop eligible indicator.
-- .TP
-- vid
-- VLAN identifier.
-- .TP
-- ether_type
-- The packet type ID field / EtherType field.
module(...,package.seeall)
require("dnsjit.core.object.ieee802_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_ieee802_t"
local core_object_ieee802_t
local Ieee802 = {}
-- Return the textual type of the object.
function Ieee802:type()
return "ieee802"
end
-- Return the previous object.
function Ieee802:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Ieee802:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Ieee802:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Ieee802:copy()
return C.core_object_ieee802_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Ieee802:free()
C.core_object_ieee802_free(self)
end
core_object_ieee802_t = ffi.metatype(t_name, { __index = Ieee802 })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Ieee802

45
src/core/object/ip.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/ip.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_ip_t* core_object_ip_copy(const core_object_ip_t* self)
{
core_object_ip_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_ip_t)));
memcpy(copy, self, sizeof(core_object_ip_t));
copy->obj_prev = 0;
return copy;
}
void core_object_ip_free(core_object_ip_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/ip.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_ip_h
#define __dnsjit_core_object_ip_h
#include <stddef.h>
#include "core/object/ip.hh"
#define CORE_OBJECT_IP_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_IP, prev) \
, \
0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, \
}
#endif

40
src/core/object/ip.hh Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_ip {
const core_object_t* obj_prev;
int32_t obj_type;
uint8_t v;
uint8_t hl;
uint8_t tos;
uint16_t len;
uint16_t id;
uint16_t off;
uint8_t ttl;
uint8_t p;
uint16_t sum;
uint8_t src[4], dst[4];
} core_object_ip_t;
core_object_ip_t* core_object_ip_copy(const core_object_ip_t* self);
void core_object_ip_free(core_object_ip_t* self);

122
src/core/object/ip.lua Normal file
View file

@ -0,0 +1,122 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.ip
-- An IP packet
--
-- An IP packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- v
-- Version.
-- .TP
-- hl
-- Header length.
-- .TP
-- tos
-- Type of service.
-- .TP
-- len
-- Total length.
-- .TP
-- id
-- Identification.
-- .TP
-- off
-- Fragment offset field.
-- .TP
-- ttl
-- Time to live.
-- .TP
-- p
-- Protocol.
-- .TP
-- sum
-- Checksum.
-- .TP
-- src
-- Source address.
-- .TP
-- dst
-- Destination address.
-- .TP
-- payload
-- A pointer to the payload.
-- .TP
-- plen
-- The length of the payload.
-- .TP
-- pad_len
-- The length of padding found, if any.
module(...,package.seeall)
require("dnsjit.core.object.ip_h")
local ffi = require("ffi")
local C = ffi.C
local libip = require("dnsjit.lib.ip")
local t_name = "core_object_ip_t"
local core_object_ip_t
local Ip = {}
-- Return the textual type of the object.
function Ip:type()
return "ip"
end
-- Return the previous object.
function Ip:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Ip:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Ip:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Ip:copy()
return C.core_object_ip_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Ip:free()
C.core_object_ip_free(self)
end
-- Return the IP source as a string.
function Ip:source()
return libip.ipstring(self.src)
end
-- Return the IP destination as a string.
function Ip:destination()
return libip.ipstring(self.dst)
end
core_object_ip_t = ffi.metatype(t_name, { __index = Ip })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Ip

45
src/core/object/ip6.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/ip6.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_ip6_t* core_object_ip6_copy(const core_object_ip6_t* self)
{
core_object_ip6_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_ip6_t)));
memcpy(copy, self, sizeof(core_object_ip6_t));
copy->obj_prev = 0;
return copy;
}
void core_object_ip6_free(core_object_ip6_t* self)
{
glassert_self();
free(self);
}

42
src/core/object/ip6.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_ip6_h
#define __dnsjit_core_object_ip6_h
#include <stddef.h>
#include "core/object/ip6.hh"
#define CORE_OBJECT_IP6_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_IP6, prev) \
, \
0, 0, 0, 0, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
0, 0, 0, 0, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
}
#endif

42
src/core/object/ip6.hh Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_ip6 {
const core_object_t* obj_prev;
int32_t obj_type;
uint32_t flow;
uint16_t plen;
uint8_t nxt;
uint8_t hlim;
uint8_t src[16];
uint8_t dst[16];
uint8_t is_frag;
uint8_t have_rtdst;
uint16_t frag_offlg;
uint16_t frag_ident;
uint8_t rtdst[16];
} core_object_ip6_t;
core_object_ip6_t* core_object_ip6_copy(const core_object_ip6_t* self);
void core_object_ip6_free(core_object_ip6_t* self);

130
src/core/object/ip6.lua Normal file
View file

@ -0,0 +1,130 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.ip6
-- An IPv6 packet
--
-- An IPv6 packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- flow
-- 4 bits version, 8 bits TC and 20 bits flow-ID.
-- .TP
-- plen
-- Payload length (as in the IPv6 header).
-- .TP
-- nxt
-- Next header.
-- .TP
-- hlim
-- Hop limit.
-- .TP
-- src
-- Source address.
-- .TP
-- dst
-- Destination address.
-- .TP
-- is_frag
-- 1 bit, set if packet is a fragment.
-- .TP
-- have_rtdst
-- 1 bit, set if
-- .I rtdst
-- is set.
-- .TP
-- frag_offlg
-- Offset, reserved, and flag taken from the fragment header.
-- .TP
-- frag_ident
-- Identification taken from the fragment header.
-- .TP
-- rtdst
-- Destination address found in the routing extension header.
-- .TP
-- payload
-- A pointer to the payload.
-- .TP
-- len
-- The length of the payload.
-- .TP
-- pad_len
-- The length of padding found, if any.
module(...,package.seeall)
require("dnsjit.core.object.ip6_h")
local ffi = require("ffi")
local C = ffi.C
local libip = require("dnsjit.lib.ip")
local t_name = "core_object_ip6_t"
local core_object_ip6_t
local Ip6 = {}
-- Return the textual type of the object.
function Ip6:type()
return "ip6"
end
-- Return the previous object.
function Ip6:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Ip6:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Ip6:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Ip6:copy()
return C.core_object_ip6_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Ip6:free()
C.core_object_ip6_free(self)
end
-- Return the IPv6 source as a string.
-- If
-- .I pretty
-- is true then return an easier to read IPv6 address.
function Ip6:source(pretty)
return libip.ip6string(self.src, pretty)
end
-- Return the IPv6 destination as a string.
-- If
-- .I pretty
-- is true then return an easier to read IPv6 address.
function Ip6:destination(pretty)
return libip.ip6string(self.dst, pretty)
end
core_object_ip6_t = ffi.metatype(t_name, { __index = Ip6 })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Ip6

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/linuxsll.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_linuxsll_t* core_object_linuxsll_copy(const core_object_linuxsll_t* self)
{
core_object_linuxsll_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_linuxsll_t)));
memcpy(copy, self, sizeof(core_object_linuxsll_t));
copy->obj_prev = 0;
return copy;
}
void core_object_linuxsll_free(core_object_linuxsll_t* self)
{
glassert_self();
free(self);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_linuxsll_h
#define __dnsjit_core_object_linuxsll_h
#include <stddef.h>
#include "core/object/linuxsll.hh"
#define CORE_OBJECT_LINUXSLL_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_LINUXSLL, prev) \
, \
0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 \
}
#endif

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_linuxsll {
const core_object_t* obj_prev;
int32_t obj_type;
uint16_t packet_type;
uint16_t arp_hardware;
uint16_t link_layer_address_length;
uint8_t link_layer_address[8];
uint16_t ether_type;
} core_object_linuxsll_t;
core_object_linuxsll_t* core_object_linuxsll_copy(const core_object_linuxsll_t* self);
void core_object_linuxsll_free(core_object_linuxsll_t* self);

View file

@ -0,0 +1,84 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.linuxsll
-- Linux cooked-mode capture (SLL) part of a packet
--
-- The SLL part of a packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- packet_type
-- The packet type.
-- .TP
-- arp_hardware
-- The link-layer device type.
-- .TP
-- link_layer_address_length
-- The length of the link-layer address.
-- .TP
-- link_layer_address
-- The link-layer address.
-- .TP
-- ether_type
-- An Ethernet protocol type.
module(...,package.seeall)
require("dnsjit.core.object.linuxsll_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_linuxsll_t"
local core_object_linuxsll_t
local Linuxsll = {}
-- Return the textual type of the object.
function Linuxsll:type()
return "linuxsll"
end
-- Return the previous object.
function Linuxsll:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Linuxsll:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Linuxsll:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Linuxsll:copy()
return C.core_object_linuxsll_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Linuxsll:free()
C.core_object_linuxsll_free(self)
end
core_object_linuxsll_t = ffi.metatype(t_name, { __index = Linuxsll })
-- dnsjit.core.object (3).
-- dnsjit.filter.layer (3)
return Linuxsll

45
src/core/object/loop.c Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/object/loop.h"
#include "core/assert.h"
#include <stdlib.h>
#include <string.h>
core_object_loop_t* core_object_loop_copy(const core_object_loop_t* self)
{
core_object_loop_t* copy;
glassert_self();
glfatal_oom(copy = malloc(sizeof(core_object_loop_t)));
memcpy(copy, self, sizeof(core_object_loop_t));
copy->obj_prev = 0;
return copy;
}
void core_object_loop_free(core_object_loop_t* self)
{
glassert_self();
free(self);
}

38
src/core/object/loop.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/object.h"
#include "core/timespec.h"
#ifndef __dnsjit_core_object_loop_h
#define __dnsjit_core_object_loop_h
#include <stddef.h>
#include "core/object/loop.hh"
#define CORE_OBJECT_LOOP_INIT(prev) \
{ \
CORE_OBJECT_INIT(CORE_OBJECT_LOOP, prev) \
, \
0 \
}
#endif

31
src/core/object/loop.hh Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2021, OARC, Inc.
* All rights reserved.
*
* This file is part of dnsjit.
*
* dnsjit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
//lua:require("dnsjit.core.object_h")
typedef struct core_object_loop {
const core_object_t* obj_prev;
int32_t obj_type;
uint32_t family;
} core_object_loop_t;
core_object_loop_t* core_object_loop_copy(const core_object_loop_t* self);
void core_object_loop_free(core_object_loop_t* self);

72
src/core/object/loop.lua Normal file
View file

@ -0,0 +1,72 @@
-- Copyright (c) 2018-2021, OARC, Inc.
-- All rights reserved.
--
-- This file is part of dnsjit.
--
-- dnsjit is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.core.object.loop
-- OpenBSD loopback encapsulation (loop) part of a packet
--
-- The loop part of a packet that usually can be found in the object chain
-- after parsing with, for example, Layer filter.
-- .SS Attributes
-- .TP
-- family
-- The link-layer header describing what type of packet is encapsulated.
module(...,package.seeall)
require("dnsjit.core.object.loop_h")
local ffi = require("ffi")
local C = ffi.C
local t_name = "core_object_loop_t"
local core_object_loop_t
local Loop = {}
-- Return the textual type of the object.
function Loop:type()
return "loop"
end
-- Return the previous object.
function Loop:prev()
return self.obj_prev
end
-- Cast the object to the underlining object module and return it.
function Loop:cast()
return self
end
-- Cast the object to the generic object module and return it.
function Loop:uncast()
return ffi.cast("core_object_t*", self)
end
-- Make a copy of the object and return it.
function Loop:copy()
return C.core_object_loop_copy(self)
end
-- Free the object, should only be used on copies or otherwise allocated.
function Loop:free()
C.core_object_loop_free(self)
end
core_object_loop_t = ffi.metatype(t_name, { __index = Loop })
-- dnsjit.core.object (3),
-- dnsjit.filter.layer (3)
return Loop

Some files were not shown because too many files have changed in this diff Show more