├── .gitignore ├── .travis.yml ├── COPYRIGHT ├── ChangeLog ├── LICENSE ├── Makefile.am ├── README.md ├── autogen.sh ├── configure.ac ├── debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── libwdns-dev.install ├── libwdns1.docs ├── libwdns1.install ├── libwdns1.symbols ├── not-installed ├── rules └── source │ ├── format │ └── local-options ├── examples ├── .gitignore ├── private.h ├── wdns-dump-file.c ├── wdns-dump-pcap.c ├── wdns-hex-driver.c ├── wdns-print-version.c ├── wdns-test-deserialize-rrset.c ├── wdns-test-downcase-rrset.c ├── wdns-test-print-message.c └── wdns-test-serialize-rrset.c ├── libmy ├── .gitignore ├── COPYRIGHT ├── LICENSE ├── argv.c ├── argv.h ├── argv_loc.h ├── atomic.h ├── atomic_64.h ├── atomic_ptr.h ├── b32_decode.c ├── b32_decode.h ├── b32_encode.c ├── b32_encode.h ├── b64_decode.c ├── b64_decode.h ├── b64_encode.c ├── b64_encode.h ├── crc32c-slicing.c ├── crc32c-sse42.c ├── crc32c.c ├── crc32c.h ├── crc32c_test.c ├── fast_inet_ntop.c ├── fast_inet_ntop.h ├── getenv_int.h ├── heap.c ├── heap.h ├── hex_decode.h ├── ip_arith.h ├── list.h ├── lookup3.c ├── lookup3.h ├── m4 │ ├── ax_compare_version.m4 │ ├── ax_define_dir.m4 │ ├── ax_prog_xsltproc.m4 │ ├── ax_pthread.m4 │ ├── ld-version-script.m4 │ ├── my_check_docbook_ns_xslt_min.m4 │ ├── my_pkg_config_files.m4 │ ├── pcap.m4 │ ├── pkg.m4 │ └── protobuf-c.m4 ├── my_alloc.h ├── my_byteorder.h ├── my_fileset.c ├── my_fileset.h ├── my_format.c ├── my_format.h ├── my_memory_barrier.h ├── my_queue.c ├── my_queue.h ├── my_queue_mb.c ├── my_queue_mutex.c ├── my_rate.c ├── my_rate.h ├── my_time.h ├── print_string.h ├── read_bytes.h ├── spooldir.c ├── spooldir.h ├── string_replace.h ├── threadnum.c ├── threadnum.h ├── tree.h ├── ubuf-pb.h ├── ubuf.h ├── varint.c ├── varint.h ├── vector.h ├── zonefile.c └── zonefile.h ├── m4 ├── .gitignore ├── ld-version-script.m4 └── pkg.m4 ├── t ├── test-common.c ├── test-common.h ├── test-fast_inet_ntop.c ├── test-name_to_str.c ├── test-rdata.c ├── test-str_to_name.c ├── test-str_to_rcode.c ├── test-str_to_rdata.c └── test-str_to_rrtype.c ├── wdns.spec └── wdns ├── buf.h ├── clear.c ├── compare_rr_rrset.c ├── copy_uname.c ├── count_labels.c ├── deserialize_rrset.c ├── domain_to_str.c ├── downcase_name.c ├── downcase_rdata.c ├── downcase_rrset.c ├── edns_options.c ├── file_load_names.c ├── gen_rcode_to_str ├── gen_rrclass_to_str ├── gen_rrtype_to_str ├── insert_rr_rrset_array.c ├── is_subdomain.c ├── left_chop.c ├── len_uname.c ├── libwdns.pc.in ├── libwdns.sym ├── message_to_str.c ├── opcode_to_str.c ├── parse_edns.c ├── parse_header.c ├── parse_message.c ├── parse_message_rr.c ├── parse_rdata.c ├── print_message.c ├── print_rr.c ├── print_rrset.c ├── print_rrset_array.c ├── rdata_to_str.c ├── rdata_to_ubuf.c ├── record_descr.c ├── record_descr.h ├── res_to_str.c ├── reverse_name.c ├── rr_to_str.c ├── rr_to_ubuf.c ├── rrset_array_to_str.c ├── rrset_array_to_ubuf.c ├── rrset_to_str.c ├── rrset_to_ubuf.c ├── serialize_rrset.c ├── skip_name.c ├── sort_rrset.c ├── str_to_name.c ├── str_to_rdata_ubuf.c ├── svcparamkeys_to_str.c ├── unpack_name.c ├── version.c ├── wdns-private.h └── wdns.h.in /.gitignore: -------------------------------------------------------------------------------- 1 | .*swp 2 | *.gcda 3 | *.gcno 4 | *.la 5 | *.lo 6 | *.o 7 | *.tar.gz 8 | .deps/ 9 | .dirstamp 10 | .libs/ 11 | .gdb_history 12 | configure~ 13 | /aclocal.m4 14 | /autom4te.cache 15 | /build-aux 16 | /config.* 17 | /configure 18 | /coverage-html 19 | /coverage.info 20 | /coveragereport 21 | /libtool 22 | /stamp-h1 23 | /test-suite.log 24 | Makefile 25 | Makefile.in 26 | TAGS 27 | tags 28 | cscope.out 29 | wdns/libwdns.pc 30 | wdns/rcode_to_str.c 31 | wdns/rrclass_to_str.c 32 | wdns/rrtype_to_str.c 33 | t/test-str_to_name 34 | t/test-str_to_rcode 35 | t/test-str_to_rdata 36 | t/test-str_to_rrtype 37 | t/test-rdata 38 | t/test-name_to_str 39 | t/*.log 40 | t/*.trs 41 | examples/wdns-print-version 42 | wdns/wdns.h 43 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | before_install: 8 | - sudo apt-get install -q libpcap0.8-dev 9 | 10 | script: 11 | - ./autogen.sh 12 | - ./configure 13 | - make 14 | - make distcheck 15 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 by DomainTools LLC 2 | Copyright (c) 2009-2021 by Farsight Security, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/farsightsec/wdns.png?branch=master)](https://travis-ci.org/farsightsec/wdns) 2 | 3 | Farsight wdns 4 | ============= 5 | 6 | `wdns` is a low-level C library for dealing with wire-format dns packets. 7 | 8 | Building and installing wdns 9 | ---------------------------- 10 | 11 | wdns has the following external dependencies: 12 | 13 | * [pcap](http://www.tcpdump.org/) 14 | 15 | * [pkg-config](https://wiki.freedesktop.org/www/Software/pkg-config/) 16 | 17 | On Debian systems, the following packages should be installed, if available: 18 | 19 | pkg-config libpcap0.8-dev 20 | 21 | Note that on Debian systems, binary packages of wdns are available from 22 | [a Debian package repository maintained by Farsight Security](https://archive.farsightsecurity.com/SIE_Software_Installation_Debian/). 23 | These packages should be used in preference to building from source on 24 | Debian-based systems. 25 | 26 | On FreeBSD systems, the following ports should be installed, if available: 27 | 28 | devel/pkgconf 29 | 30 | After satisfying the prerequisites, `./configure && make && make install` should 31 | compile and install `libwdns` in `/usr/local`. If building from a git checkout, 32 | run the `./autogen.sh` command first to generate the `configure` script. 33 | 34 | Examples 35 | -------- 36 | 37 | C language examples are in the `examples/` directory. 38 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec autoreconf -fvi 3 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.64) 2 | 3 | m4_define(wdns_major_version, 0) 4 | m4_define(wdns_minor_version, 12) 5 | m4_define(wdns_patchlevel_version, 0) 6 | m4_define(wdns_version, 7 | wdns_major_version.wdns_minor_version.wdns_patchlevel_version) 8 | 9 | AC_INIT([wdns], 10 | [wdns_version()], 11 | [https://github.com/farsightsec/wdns/issues], 12 | [wdns], 13 | [https://github.com/farsightsec/wdns]) 14 | AC_CONFIG_SRCDIR([wdns/wdns.h.in]) 15 | AC_CONFIG_AUX_DIR([build-aux]) 16 | AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules subdir-objects]) 17 | AC_PROG_CC 18 | AC_USE_SYSTEM_EXTENSIONS 19 | AC_SYS_LARGEFILE 20 | AC_CONFIG_MACRO_DIR([m4]) 21 | AM_SILENT_RULES([yes]) 22 | LT_INIT 23 | 24 | WDNS_MAJOR_VERSION=wdns_major_version() 25 | WDNS_MINOR_VERSION=wdns_minor_version() 26 | WDNS_PATCHLEVEL_VERSION=wdns_patchlevel_version() 27 | WDNS_VERSION=wdns_version() 28 | 29 | AC_SUBST(WDNS_MAJOR_VERSION) 30 | AC_SUBST(WDNS_MINOR_VERSION) 31 | AC_SUBST(WDNS_PATCHLEVEL_VERSION) 32 | AC_SUBST(WDNS_VERSION) 33 | 34 | AC_CONFIG_HEADERS(config.h) 35 | AC_CONFIG_FILES([Makefile wdns/libwdns.pc wdns/wdns.h]) 36 | 37 | PKG_PROG_PKG_CONFIG 38 | if test -n "$PKG_CONFIG"; then 39 | # Horrible hack for systems where the pkg-config install directory is simply wrong! 40 | if $PKG_CONFIG --variable=pc_path pkg-config 2>/dev/null | grep -q /libdata/; then 41 | PKG_INSTALLDIR(['${prefix}/libdata/pkgconfig']) 42 | else 43 | PKG_INSTALLDIR 44 | fi 45 | else 46 | AC_MSG_ERROR([pkg-config is required!]) 47 | fi 48 | 49 | my_CFLAGS="-Wall \ 50 | -Wmissing-declarations -Wmissing-prototypes \ 51 | -Wnested-externs -Wpointer-arith \ 52 | -Wpointer-arith -Wsign-compare -Wchar-subscripts \ 53 | -Wstrict-prototypes -Wshadow \ 54 | -Wformat-security" 55 | AC_SUBST([my_CFLAGS]) 56 | 57 | AC_CHECK_HEADERS([alloca.h]) 58 | 59 | AC_CHECK_HEADER([pcap.h]) 60 | AC_CHECK_LIB([pcap], [pcap_loop], 61 | [ 62 | AC_DEFINE([HAVE_LIBPCAP], [1], [Define to 1 if libpcap works.]) 63 | have_libpcap=true 64 | ], 65 | [ 66 | have_libpcap=false 67 | ] 68 | ) 69 | AM_CONDITIONAL([LIBPCAP], [test "$have_libpcap" = "true"]) 70 | 71 | gl_LD_VERSION_SCRIPT 72 | 73 | AM_PATH_PYTHON(,, [:]) 74 | AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) 75 | 76 | AC_ARG_WITH(coverage, 77 | [ --with-coverage[=PROGRAM] enable gtest and coverage target using the specified lcov], lcov="$withval", lcov="no") 78 | 79 | 80 | USE_LCOV="no" 81 | if test "$lcov" != "no"; then 82 | if test "$lcov" != "yes"; then 83 | LCOV=$lcov 84 | else 85 | AC_PATH_PROG([LCOV], [lcov]) 86 | fi 87 | if test -x "${LCOV}"; then 88 | USE_LCOV="yes" 89 | else 90 | AC_MSG_ERROR([Cannot find lcov.]) 91 | fi 92 | # is genhtml always in the same directory? 93 | GENHTML=`echo "$LCOV" | ${SED} s/lcov$/genhtml/` 94 | if test ! -x $GENHTML; then 95 | AC_MSG_ERROR([genhtml not found, needed for lcov]) 96 | fi 97 | CFLAGS="$CFLAGS --coverage" 98 | LIBS=" $LIBS -lgcov" 99 | AC_SUBST(CPPFLAGS) 100 | AC_SUBST(LIBS) 101 | AC_SUBST(LCOV) 102 | AC_SUBST(GENHTML) 103 | fi 104 | AC_SUBST(USE_LCOV) 105 | 106 | AC_OUTPUT 107 | AC_MSG_RESULT([ 108 | $PACKAGE $VERSION 109 | 110 | CC: ${CC} 111 | CFLAGS: ${CFLAGS} 112 | LDFLAGS: ${LDFLAGS} 113 | LIBS: ${LIBS} 114 | 115 | prefix: ${prefix} 116 | sysconfdir: ${sysconfdir} 117 | libdir: ${libdir} 118 | includedir: ${includedir} 119 | pkgconfigdir: ${pkgconfigdir} 120 | 121 | code coverage enabled: ${USE_LCOV} 122 | ]) 123 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | wdns (0.12.0-1) debian-fsi; urgency=medium 2 | 3 | * Add EDNS output to wdns_message_to_str(). 4 | 5 | * Fix memory leak triggered by multiple OPT records in messages. 6 | 7 | * Fixes multiple bugs in base32 encoding, NSEC bitmap parsing, and HTTPS 8 | svcparam parsing. 9 | 10 | * Fix out of bounds memory write in wdns_str_to_name. 11 | 12 | * Fix handling of no address for client subnets. 13 | 14 | -- Farsight Security, Inc. Thu, 31 Aug 2023 21:20:19 +0000 15 | 16 | wdns (0.11.0-1) debian-fsi; urgency=medium 17 | 18 | * Improve support for CAA records. (CAA was previously rendered as a 19 | "generic" rdata type.) 20 | 21 | * Bug fix for NSEC/NSEC3/CSYNC: do not output empty rrtype bitmaps 22 | per RFC6840 section 6.4. 23 | 24 | * Fix parsing of A6 records that ommit and address portion. Correct 25 | parsing of A6 records with prefix length 0. Correct handling of 26 | A6 address bytes. The address bytes of an A6 record are an address 27 | suffix relative to the prefix represented by the domain name, and 28 | so must be copied to and from the lower order bytes of the internal 29 | address representation. These A6 code updates were for the purposes 30 | of clearing "round trip" test errors in the existing code base. 31 | (A6 is deprecated and was moved to historic status.) 32 | 33 | * Fix bug in IPv6 prefix length processing in _wdns_str_to_rdata_ubuf(). 34 | 35 | * Add support for SVCB and HTTPS resource record types. This is based 36 | on an Internet-Draft but is widely used in the real world. 37 | https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08 38 | 39 | -- Farsight Security, Inc. Mon, 04 Apr 2022 12:13:28 -0400 40 | 41 | wdns (0.10.0-2) debian-fsi; urgency=medium 42 | 43 | * Migrate to Python3 for gen_*, required for building. 44 | 45 | -- Farsight Security, Inc. Tue, 08 Feb 2022 00:58:15 +0000 46 | 47 | wdns (0.10.0-1) debian-fsi; urgency=medium 48 | 49 | * New release. 50 | 51 | -- Farsight Security, Inc. Wed, 27 Nov 2019 13:03:14 -0500 52 | 53 | wdns (0.9.1-1) wheezy-farsightsec; urgency=medium 54 | 55 | * New release. 56 | 57 | -- Farsight Security Tue, 3 Jan 2017 17:56:25 +0000 58 | 59 | wdns (0.9.0-1) wheezy-farsightsec; urgency=medium 60 | 61 | * New release. 62 | 63 | -- Robert Edmonds Mon, 18 Apr 2016 19:42:34 -0400 64 | 65 | wdns (0.8.1-1) wheezy-farsightsec; urgency=medium 66 | 67 | * New release. 68 | * debian/libwdns1.symbols: Update symbols for 0.8.1 69 | * debian/gbp.conf: Remove [dch] id-length 70 | 71 | -- Robert Edmonds Wed, 24 Feb 2016 15:41:35 -0500 72 | 73 | wdns (0.8.0-1) wheezy-farsightsec; urgency=medium 74 | 75 | * New release. 76 | * debian/libwdns1.symbols: Update symbols for 0.8.0 77 | 78 | -- Robert Edmonds Tue, 13 Oct 2015 17:22:11 -0400 79 | 80 | wdns (0.7.0-1) wheezy-farsightsec; urgency=medium 81 | 82 | * New release. 83 | * debian/gbp.conf: Add [dch], set debian-branch = upstream-branch = next 84 | * debian/control: Update Maintainer 85 | * debian/control: Update Standards-Version 86 | * debian/control: wrap-and-sort 87 | * debian/libwdns1.symbols: Update symbols for 0.7.0 88 | * debian/copyright: 2015 89 | 90 | -- Robert Edmonds Thu, 10 Sep 2015 17:24:47 -0400 91 | 92 | wdns (0.6.0-1) unstable; urgency=medium 93 | 94 | * Current release. 95 | 96 | -- Robert Edmonds Wed, 21 May 2014 12:28:00 -0400 97 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: wdns 2 | Section: libs 3 | Priority: optional 4 | Maintainer: Farsight Security, Inc. 5 | Build-Depends: 6 | debhelper-compat (= 13), 7 | dpkg-dev (>= 1.16.0~), 8 | lcov, 9 | pkg-config, 10 | python3, 11 | Standards-Version: 4.5.1 12 | 13 | Package: libwdns-dev 14 | Section: libdevel 15 | Architecture: any 16 | Multi-Arch: same 17 | Depends: libwdns1 (= ${binary:Version}), ${misc:Depends} 18 | Description: low-level DNS library (development files) 19 | wdns is a low-level DNS library. It contains a fast DNS message parser 20 | and various utility functions for manipulating wire-format DNS data. 21 | . 22 | This package contains the static library and header file for libwdns. 23 | 24 | Package: libwdns1 25 | Architecture: any 26 | Multi-Arch: same 27 | Depends: ${misc:Depends}, ${shlibs:Depends} 28 | Description: low-level DNS library 29 | wdns is a low-level DNS library. It contains a fast DNS message parser 30 | and various utility functions for manipulating wire-format DNS data. 31 | . 32 | This package contains the shared library for libwdns. 33 | 34 | Package: libwdns1-dbg 35 | Section: debug 36 | Priority: optional 37 | Architecture: any 38 | Multi-Arch: same 39 | Depends: libwdns1 (= ${binary:Version}), ${misc:Depends} 40 | Description: low-level DNS library (debug symbols) 41 | wdns is a low-level DNS library. It contains a fast DNS message parser 42 | and various utility functions for manipulating wire-format DNS data. 43 | . 44 | This package contains detached debugging symbols for libwdns. 45 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | 3 | Files: * 4 | Copyright: 2022-2023 DomainTools LLC 5 | 2009-2021 by Farsight Security, Inc. 6 | License: Apache-2.0 7 | Licensed under the Apache License, Version 2.0 (the "License"); you 8 | may not use this file except in compliance with the License. You may 9 | obtain a copy of the License at 10 | . 11 | http://www.apache.org/licenses/LICENSE-2.0. 12 | . 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | implied. See the License for the specific language governing 17 | permissions and limitations under the License. 18 | . 19 | On Debian systems, the full text of the Apache License, Version 2.0 can be 20 | found in the file `/usr/share/common-licenses/Apache-2.0'. 21 | 22 | Files: libmy/b32_encode.c libmy/b32_encode.h libmy/b32_decode.c libmy/b32_decode.h 23 | Copyright: 2006 Christian Biere 24 | License: BSD-3-Clause 25 | Redistribution and use in source and binary forms, with or without 26 | modification, are permitted provided that the following conditions 27 | are met: 28 | . 29 | 1. Redistributions of source code must retain the above copyright 30 | notice, this list of conditions and the following disclaimer. 31 | 2. Redistributions in binary form must reproduce the above copyright 32 | notice, this list of conditions and the following disclaimer in the 33 | documentation and/or other materials provided with the distribution. 34 | 3. Neither the name of the authors nor the names of its contributors 35 | may be used to endorse or promote products derived from this software 36 | without specific prior written permission. 37 | . 38 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 39 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 42 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 | SUCH DAMAGE. 49 | -------------------------------------------------------------------------------- /debian/gbp.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | debian-branch = next 3 | upstream-branch = next 4 | upstream-tag = tags/v%(version)s 5 | pristine-tar = False 6 | 7 | [dch] 8 | commit-msg = debian/changelog: %(version)s 9 | -------------------------------------------------------------------------------- /debian/libwdns-dev.install: -------------------------------------------------------------------------------- 1 | usr/include 2 | usr/lib/*/*.a 3 | usr/lib/*/*.so 4 | usr/lib/*/pkgconfig/*.pc 5 | -------------------------------------------------------------------------------- /debian/libwdns1.docs: -------------------------------------------------------------------------------- 1 | ChangeLog 2 | COPYRIGHT 3 | README.md 4 | -------------------------------------------------------------------------------- /debian/libwdns1.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/*.so.* 2 | -------------------------------------------------------------------------------- /debian/libwdns1.symbols: -------------------------------------------------------------------------------- 1 | libwdns.so.1 libwdns1 #MINVER# 2 | LIBWDNS_0.10.0@LIBWDNS_0.10.0 0.10.0 3 | LIBWDNS_0.6.0@LIBWDNS_0.6.0 0.6.0 4 | LIBWDNS_0.7.0@LIBWDNS_0.7.0 0.7.0 5 | LIBWDNS_0.8.0@LIBWDNS_0.8.0 0.8.0 6 | wdns_clear_message@LIBWDNS_0.6.0 0.6.0 7 | wdns_clear_rr@LIBWDNS_0.6.0 0.6.0 8 | wdns_clear_rrset@LIBWDNS_0.6.0 0.6.0 9 | wdns_clear_rrset_array@LIBWDNS_0.6.0 0.6.0 10 | wdns_compare_rr_rrset@LIBWDNS_0.6.0 0.6.0 11 | wdns_copy_uname@LIBWDNS_0.6.0 0.6.0 12 | wdns_count_labels@LIBWDNS_0.6.0 0.6.0 13 | wdns_deserialize_rrset@LIBWDNS_0.6.0 0.6.0 14 | wdns_domain_to_str@LIBWDNS_0.6.0 0.6.0 15 | wdns_downcase_name@LIBWDNS_0.6.0 0.6.0 16 | wdns_downcase_rdata@LIBWDNS_0.6.0 0.6.0 17 | wdns_downcase_rrset@LIBWDNS_0.6.0 0.6.0 18 | wdns_file_load_names@LIBWDNS_0.6.0 0.6.0 19 | wdns_get_version@LIBWDNS_0.10.0 0.10.0 20 | wdns_get_version_number@LIBWDNS_0.10.0 0.10.0 21 | wdns_is_subdomain@LIBWDNS_0.6.0 0.6.0 22 | wdns_left_chop@LIBWDNS_0.6.0 0.6.0 23 | wdns_len_uname@LIBWDNS_0.6.0 0.6.0 24 | wdns_message_to_str@LIBWDNS_0.6.0 0.6.0 25 | wdns_opcode_to_str@LIBWDNS_0.6.0 0.6.0 26 | wdns_parse_message@LIBWDNS_0.6.0 0.8.1 27 | wdns_print_message@LIBWDNS_0.6.0 0.6.0 28 | wdns_print_rr@LIBWDNS_0.6.0 0.6.0 29 | wdns_print_rrset@LIBWDNS_0.6.0 0.6.0 30 | wdns_print_rrset_array@LIBWDNS_0.6.0 0.6.0 31 | wdns_rcode_to_str@LIBWDNS_0.6.0 0.6.0 32 | wdns_rdata_to_str@LIBWDNS_0.6.0 0.6.0 33 | wdns_res_to_str@LIBWDNS_0.6.0 0.6.0 34 | wdns_reverse_name@LIBWDNS_0.6.0 0.6.0 35 | wdns_rr_to_str@LIBWDNS_0.6.0 0.6.0 36 | wdns_rrclass_to_str@LIBWDNS_0.6.0 0.6.0 37 | wdns_rrset_array_to_str@LIBWDNS_0.6.0 0.6.0 38 | wdns_rrset_to_str@LIBWDNS_0.6.0 0.6.0 39 | wdns_rrtype_to_str@LIBWDNS_0.6.0 0.6.0 40 | wdns_serialize_rrset@LIBWDNS_0.6.0 0.6.0 41 | wdns_skip_name@LIBWDNS_0.6.0 0.6.0 42 | wdns_sort_rrset@LIBWDNS_0.6.0 0.6.0 43 | wdns_str_to_name@LIBWDNS_0.6.0 0.6.0 44 | wdns_str_to_name_case@LIBWDNS_0.8.0 0.8.0 45 | wdns_str_to_rcode@LIBWDNS_0.8.0 0.8.0 46 | wdns_str_to_rdata@LIBWDNS_0.7.0 0.7.0 47 | wdns_str_to_rrclass@LIBWDNS_0.7.0 0.7.0 48 | wdns_str_to_rrtype@LIBWDNS_0.6.0 0.6.0 49 | wdns_unpack_name@LIBWDNS_0.6.0 0.6.0 50 | -------------------------------------------------------------------------------- /debian/not-installed: -------------------------------------------------------------------------------- 1 | usr/lib/*/libwdns.la 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ 5 | 6 | override_dh_strip: 7 | dh_strip -p libwdns1 --dbg-package=libwdns1-dbg 8 | dh_strip -a --remaining-packages 9 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/source/local-options: -------------------------------------------------------------------------------- 1 | single-debian-patch 2 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | wdns-dump-file 2 | wdns-dump-pcap 3 | wdns-test-deserialize-rrset 4 | wdns-test-downcase-rrset 5 | wdns-test-print-message 6 | wdns-test-serialize-rrset 7 | -------------------------------------------------------------------------------- /examples/private.h: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_ALLOCA_H 2 | # include 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #if DEBUG 18 | # define VERBOSE(format, ...) do { printf(format, ## __VA_ARGS__); } while (0) 19 | #else 20 | # define VERBOSE(format, ...) 21 | #endif 22 | -------------------------------------------------------------------------------- /examples/wdns-dump-file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "private.h" 11 | 12 | #include 13 | 14 | static int 15 | process_data(const uint8_t *data, size_t len) 16 | { 17 | wdns_message_t m; 18 | wdns_res res; 19 | 20 | res = wdns_parse_message(&m, data, len); 21 | if (res == wdns_res_success) { 22 | wdns_print_message(stdout, &m); 23 | wdns_clear_message(&m); 24 | putchar('\n'); 25 | return EXIT_SUCCESS; 26 | } else { 27 | return EXIT_FAILURE; 28 | } 29 | } 30 | 31 | int 32 | main(int argc, char **argv) { 33 | FILE *fp; 34 | 35 | uint8_t data[4096] = {0}; 36 | size_t len; 37 | 38 | if (argc != 2) { 39 | fprintf(stderr, "Usage: %s \n", argv[0]); 40 | return EXIT_FAILURE; 41 | } 42 | 43 | fp = fopen(argv[1], "r"); 44 | if (fp == NULL) { 45 | fprintf(stderr, "Error: unable to open %s: %s\n", argv[1], strerror(errno)); 46 | return EXIT_FAILURE; 47 | } 48 | 49 | len = fread(data, 1, sizeof(data), fp); 50 | if (ferror(fp)) { 51 | fprintf(stderr, "Error: fread() returned an error on %s\n", argv[1]); 52 | return EXIT_FAILURE; 53 | } 54 | 55 | if (!feof(fp)) { 56 | fprintf(stderr, "Error: did not make a complete read of %s\n", argv[1]); 57 | return EXIT_FAILURE; 58 | } 59 | 60 | return process_data(data, len); 61 | } 62 | -------------------------------------------------------------------------------- /examples/wdns-dump-pcap.c: -------------------------------------------------------------------------------- 1 | /* wdns-dump-pcap: read a pcap file, and optionally dump broken DNS messages */ 2 | 3 | /* XXX -- assumes all packets are DNS, use a bpf if not */ 4 | /* XXX -- doesn't handle fragments */ 5 | /* XXX -- only handles ethernet/ipv4 messages */ 6 | 7 | #include "private.h" 8 | 9 | #include 10 | #include 11 | 12 | static uint64_t count; 13 | static uint64_t count_dump; 14 | 15 | #define eth_type_ip 0x0800 16 | #define eth_type_ipv6 0x86dd 17 | 18 | #define advance(p, len, sz) do { (p) += (sz); (len) -= (sz); } while (0) 19 | #define getu16(dst, src) do { memcpy(&(dst), src, 2); dst = ntohs(dst); } while (0) 20 | 21 | static void 22 | packet_dump(u_char *dumper, 23 | const struct pcap_pkthdr *hdr, 24 | const u_char *pkt) 25 | { 26 | pcap_dump(dumper, hdr, pkt); 27 | VERBOSE("count=%" PRIu64 " dumping broken packet\n", count); 28 | count_dump += 1; 29 | } 30 | 31 | static void 32 | packet_handler(u_char *dumper, 33 | const struct pcap_pkthdr *hdr, 34 | const u_char *pkt) 35 | { 36 | const u_char *dns_p, *p; 37 | uint16_t e_type; 38 | uint16_t ip_len; 39 | uint32_t dns_len; 40 | uint32_t len = hdr->caplen; 41 | uint8_t ihl; 42 | wdns_message_t m; 43 | wdns_res res; 44 | 45 | p = pkt; 46 | count++; 47 | 48 | VERBOSE("count=%" PRIu64 " parsing packet\n", count); 49 | 50 | /* ethernet */ 51 | if (len < 14) { 52 | VERBOSE("count=%" PRIu64 " too short for ethernet\n", count); 53 | return; 54 | } 55 | advance(p, len, 12); 56 | getu16(e_type, p); 57 | advance(p, len, 2); 58 | if (e_type != eth_type_ip) { 59 | VERBOSE("count=%" PRIu64 " not IP e_type=%#.x\n", count, e_type); 60 | return; 61 | } 62 | 63 | /* skip ip */ 64 | ihl = *p & 0x0f; 65 | if (len < ihl * 4U) { 66 | VERBOSE("count=%" PRIu64" IP too short\n", count); 67 | return; 68 | } 69 | getu16(ip_len, p + 2); 70 | if (ip_len < len) 71 | len = ip_len; 72 | advance(p, len, ihl * 4U); 73 | 74 | /* skip udp */ 75 | if (len < 8) { 76 | VERBOSE("count=%" PRIu64" UDP too short\n", count); 77 | return; 78 | } 79 | advance(p, len, 8); 80 | 81 | /* dns header */ 82 | if (len < 12) { 83 | VERBOSE("count=%" PRIu64" DNS header too short\n", count); 84 | return; 85 | } 86 | 87 | dns_p = p; 88 | dns_len = len; 89 | 90 | res = wdns_parse_message(&m, dns_p, dns_len); 91 | if (res == wdns_res_success) { 92 | wdns_print_message(stdout, &m); 93 | wdns_clear_message(&m); 94 | } else { 95 | VERBOSE("wdns_res=%u\n", res); 96 | packet_dump(dumper, hdr, pkt); 97 | } 98 | 99 | VERBOSE("%s", "\n"); 100 | return; 101 | } 102 | 103 | int 104 | main(int argc, char **argv) { 105 | pcap_t *pcap; 106 | pcap_dumper_t *dumper = NULL; 107 | char errbuf[PCAP_ERRBUF_SIZE]; 108 | struct bpf_program bpfp; 109 | 110 | if (argc != 4) { 111 | fprintf(stderr, "Usage: %s \n", argv[0]); 112 | return (EXIT_FAILURE); 113 | } 114 | 115 | pcap = pcap_open_offline(argv[1], errbuf); 116 | if (pcap == NULL) { 117 | fprintf(stderr, "pcap_open_offline() failed: %s\n", errbuf); 118 | return (EXIT_FAILURE); 119 | } 120 | 121 | dumper = pcap_dump_open(pcap, argv[2]); 122 | if (dumper == NULL) { 123 | pcap_perror(pcap, "pcap_dump_open:"); 124 | return (EXIT_FAILURE); 125 | } 126 | 127 | if (pcap_compile(pcap, &bpfp, argv[3], 1, 0) != 0) { 128 | pcap_perror(pcap, "pcap_compile:"); 129 | pcap_close(pcap); 130 | pcap_dump_close(dumper); 131 | return (EXIT_FAILURE); 132 | } else { 133 | if (pcap_setfilter(pcap, &bpfp) != 0) { 134 | pcap_perror(pcap, "pcap_setfilter:"); 135 | pcap_close(pcap); 136 | pcap_dump_close(dumper); 137 | return (EXIT_FAILURE); 138 | } 139 | pcap_freecode(&bpfp); 140 | } 141 | 142 | pcap_loop(pcap, -1, packet_handler, (u_char *) dumper); 143 | pcap_close(pcap); 144 | pcap_dump_close(dumper); 145 | 146 | fprintf(stderr, "count=%" PRIu64 "\n", count); 147 | fprintf(stderr, "count_dump=%" PRIu64 "\n", count_dump); 148 | 149 | return (EXIT_SUCCESS); 150 | } 151 | -------------------------------------------------------------------------------- /examples/wdns-hex-driver.c: -------------------------------------------------------------------------------- 1 | #include "private.h" 2 | 3 | #include 4 | 5 | extern bool loadfunc(uint8_t *data, size_t len); 6 | extern bool testfunc(void); 7 | extern void freefunc(void); 8 | 9 | static bool 10 | hex_to_int(char hex, uint8_t *val) 11 | { 12 | if (islower((unsigned char) hex)) 13 | hex = toupper((unsigned char) hex); 14 | 15 | switch (hex) { 16 | case '0': 17 | case '1': 18 | case '2': 19 | case '3': 20 | case '4': 21 | case '5': 22 | case '6': 23 | case '7': 24 | case '8': 25 | case '9': 26 | *val = (hex - '0'); 27 | return (true); 28 | case 'A': 29 | case 'B': 30 | case 'C': 31 | case 'D': 32 | case 'E': 33 | case 'F': 34 | *val = (hex - 55); 35 | return (true); 36 | default: 37 | printf("hex_to_int() failed\n"); 38 | return (false); 39 | } 40 | } 41 | 42 | static bool 43 | hex_decode(const char *hex, uint8_t **raw, size_t *len) 44 | { 45 | size_t hexlen = strlen(hex); 46 | uint8_t *p; 47 | 48 | if (hexlen == 0 || (hexlen % 2) != 0) 49 | return (false); 50 | 51 | *len = hexlen / 2; 52 | 53 | p = *raw = malloc(*len); 54 | if (*raw == NULL) 55 | return (false); 56 | 57 | while (hexlen != 0) { 58 | uint8_t val[2]; 59 | 60 | if (!hex_to_int(*hex, &val[0])) 61 | goto err; 62 | hex++; 63 | if (!hex_to_int(*hex, &val[1])) 64 | goto err; 65 | hex++; 66 | 67 | *p = (val[0] << 4) | val[1]; 68 | p++; 69 | 70 | hexlen -= 2; 71 | } 72 | 73 | return (true); 74 | err: 75 | free(*raw); 76 | return (false); 77 | } 78 | 79 | int 80 | main(int argc, char **argv) 81 | { 82 | size_t rawlen; 83 | uint8_t *rawdata; 84 | 85 | if (argc != 2) { 86 | fprintf(stderr, "Usage: %s \n", argv[0]); 87 | return (EXIT_FAILURE); 88 | } 89 | 90 | if (!hex_decode(argv[1], &rawdata, &rawlen)) { 91 | fprintf(stderr, "Error: unable to decode hex\n"); 92 | return (EXIT_FAILURE); 93 | } 94 | 95 | if (loadfunc(rawdata, rawlen)) { 96 | testfunc(); 97 | freefunc(); 98 | } else { 99 | free(rawdata); 100 | fprintf(stderr, "Error: load function failed\n"); 101 | return (EXIT_FAILURE); 102 | } 103 | 104 | free(rawdata); 105 | 106 | return (EXIT_SUCCESS); 107 | } 108 | -------------------------------------------------------------------------------- /examples/wdns-print-version.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | int 9 | main(void) { 10 | 11 | /* to do compile-time checking, do something like the following: */ 12 | #if WDNS_LIBRARY_VERSION_NUMBER > 9001 13 | printf("your install of libwdns supports compile-time versioning "); 14 | printf("(WDNS_LIBRARY_VERSION_NUMBER == %lu)\n", 15 | WDNS_LIBRARY_VERSION_NUMBER); 16 | /* to do run-time checking, do something like the following: */ 17 | printf("libwdns run-time version is %d\n", wdns_get_version_number()); 18 | 19 | /* and to emit a stringified version number, do this: */ 20 | printf("this program was linked against libwdns version %s\n", 21 | wdns_get_version()); 22 | return (EXIT_SUCCESS); 23 | #else 24 | printf("your install of libwdns predates versioning, consider an upgrade\n"); 25 | return (EXIT_SUCCESS); 26 | #endif 27 | } 28 | -------------------------------------------------------------------------------- /examples/wdns-test-deserialize-rrset.c: -------------------------------------------------------------------------------- 1 | #include "private.h" 2 | 3 | #include 4 | 5 | bool loadfunc(uint8_t *, size_t); 6 | void freefunc(void); 7 | bool testfunc(void); 8 | 9 | wdns_rrset_t rrset; 10 | 11 | bool 12 | loadfunc(uint8_t *data, size_t len) 13 | { 14 | wdns_res res; 15 | res = wdns_deserialize_rrset(&rrset, data, len); 16 | if (res != wdns_res_success) 17 | return (false); 18 | return (true); 19 | } 20 | 21 | void 22 | freefunc(void) 23 | { 24 | wdns_clear_rrset(&rrset); 25 | } 26 | 27 | bool 28 | testfunc(void) 29 | { 30 | wdns_print_rrset(stdout, &rrset, WDNS_MSG_SEC_ANSWER); 31 | return (true); 32 | } 33 | -------------------------------------------------------------------------------- /examples/wdns-test-downcase-rrset.c: -------------------------------------------------------------------------------- 1 | #include "private.h" 2 | 3 | #include 4 | 5 | bool loadfunc(uint8_t *, size_t); 6 | void freefunc(void); 7 | bool testfunc(void); 8 | 9 | wdns_rrset_t rrset; 10 | 11 | bool 12 | loadfunc(uint8_t *data, size_t len) 13 | { 14 | wdns_res res; 15 | res = wdns_deserialize_rrset(&rrset, data, len); 16 | if (res != wdns_res_success) 17 | return (false); 18 | return (true); 19 | } 20 | 21 | void 22 | freefunc(void) 23 | { 24 | wdns_clear_rrset(&rrset); 25 | } 26 | 27 | bool 28 | testfunc(void) 29 | { 30 | wdns_res res; 31 | res = wdns_downcase_rrset(&rrset); 32 | if (res != wdns_res_success) 33 | return (false); 34 | wdns_print_rrset(stdout, &rrset, WDNS_MSG_SEC_ANSWER); 35 | return (true); 36 | } 37 | -------------------------------------------------------------------------------- /examples/wdns-test-print-message.c: -------------------------------------------------------------------------------- 1 | #include "private.h" 2 | 3 | #include 4 | 5 | bool loadfunc(uint8_t *, size_t); 6 | void freefunc(void); 7 | bool testfunc(void); 8 | 9 | wdns_message_t m; 10 | 11 | bool 12 | loadfunc(uint8_t *data, size_t len) 13 | { 14 | wdns_res res; 15 | res = wdns_parse_message(&m, data, len); 16 | if (res != wdns_res_success) 17 | return (false); 18 | return (true); 19 | } 20 | 21 | void 22 | freefunc(void) 23 | { 24 | wdns_clear_message(&m); 25 | } 26 | 27 | bool 28 | testfunc(void) 29 | { 30 | wdns_print_message(stdout, &m); 31 | return (true); 32 | } 33 | -------------------------------------------------------------------------------- /examples/wdns-test-serialize-rrset.c: -------------------------------------------------------------------------------- 1 | #include "private.h" 2 | 3 | #include 4 | 5 | bool loadfunc(uint8_t *, size_t); 6 | void freefunc(void); 7 | bool testfunc(void); 8 | 9 | wdns_message_t m; 10 | 11 | bool 12 | loadfunc(uint8_t *data, size_t len) 13 | { 14 | wdns_res res; 15 | res = wdns_parse_message(&m, data, len); 16 | if (res != wdns_res_success) 17 | return (false); 18 | return (true); 19 | } 20 | 21 | void 22 | freefunc(void) 23 | { 24 | wdns_clear_message(&m); 25 | } 26 | 27 | 28 | static void 29 | print_data(const uint8_t *d, size_t len) { 30 | while (len-- != 0) 31 | fprintf(stderr, "%02x", *(d++)); 32 | fprintf(stderr, "\n"); 33 | } 34 | 35 | bool 36 | testfunc(void) 37 | { 38 | wdns_rrset_array_t *a; 39 | wdns_rrset_t *rrset; 40 | size_t sz; 41 | uint8_t *buf; 42 | 43 | for (size_t sec = WDNS_MSG_SEC_ANSWER; sec < WDNS_MSG_SEC_MAX; sec++) { 44 | a = &m.sections[sec]; 45 | for (size_t n = 0; n < a->n_rrsets; n++) { 46 | rrset = &a->rrsets[n]; 47 | wdns_serialize_rrset(rrset, NULL, &sz); 48 | buf = alloca(sz); 49 | wdns_serialize_rrset(rrset, buf, NULL); 50 | print_data(buf, sz); 51 | } 52 | } 53 | return (true); 54 | } 55 | -------------------------------------------------------------------------------- /libmy/.gitignore: -------------------------------------------------------------------------------- 1 | *.lo 2 | *.o 3 | .*swp 4 | .deps/ 5 | .dirstamp 6 | .libs/ 7 | -------------------------------------------------------------------------------- /libmy/COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 by Farsight Security, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /libmy/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_ATOMIC_H 2 | #define MY_ATOMIC_H 3 | 4 | /* public domain, from http://golubenco.org/2007/06/14/atomic-operations/ */ 5 | 6 | /** 7 | * Atomic type. 8 | */ 9 | 10 | typedef struct { 11 | volatile int counter; 12 | } atomic_t; 13 | 14 | #define ATOMIC_INIT(i) { (i) } 15 | 16 | /** 17 | * Read atomic variable 18 | * @param v pointer of type atomic_t 19 | * 20 | * Atomically reads the value of @v. 21 | */ 22 | #define atomic_read(v) ((v)->counter) 23 | 24 | /** 25 | * Set atomic variable 26 | * @param v pointer of type atomic_t 27 | * @param i required value 28 | */ 29 | #define atomic_set(v, i) (((v)->counter) = (i)) 30 | 31 | /** 32 | * Add to the atomic variable 33 | * @param i integer value to add 34 | * @param v pointer of type atomic_t 35 | */ 36 | static inline void 37 | atomic_add(int i, atomic_t *v) { 38 | (void)__sync_add_and_fetch(&v->counter, i); 39 | } 40 | 41 | /** 42 | * Subtract the atomic variable 43 | * @param i integer value to subtract 44 | * @param v pointer of type atomic_t 45 | * 46 | * Atomically subtracts @i from @v. 47 | */ 48 | static inline void 49 | atomic_sub(int i, atomic_t *v) { 50 | (void)__sync_sub_and_fetch(&v->counter, i); 51 | } 52 | 53 | /** 54 | * Read atomic variable and reset to zero. 55 | * 56 | * @param v pointer of type atomic_t 57 | */ 58 | static inline int 59 | atomic_zero(atomic_t *v) { 60 | return (__sync_fetch_and_and(&v->counter, 0)); 61 | } 62 | 63 | /** 64 | * Subtract value from variable and test result 65 | * @param i integer value to subtract 66 | * @param v pointer of type atomic_t 67 | * 68 | * Atomically subtracts @i from @v and returns 69 | * true if the result is zero, or false for all 70 | * other cases. 71 | */ 72 | static inline int 73 | atomic_sub_and_test(int i, atomic_t *v) { 74 | return !(__sync_sub_and_fetch(&v->counter, i)); 75 | } 76 | 77 | /** 78 | * Increment atomic variable 79 | * @param v pointer of type atomic_t 80 | * 81 | * Atomically increments @v by 1. 82 | */ 83 | static inline void 84 | atomic_inc(atomic_t *v) { 85 | (void)__sync_fetch_and_add(&v->counter, 1); 86 | } 87 | 88 | /** 89 | * @brief decrement atomic variable 90 | * @param v: pointer of type atomic_t 91 | * 92 | * Atomically decrements @v by 1. Note that the guaranteed 93 | * useful range of an atomic_t is only 24 bits. 94 | */ 95 | static inline void 96 | atomic_dec(atomic_t *v) { 97 | (void)__sync_fetch_and_sub(&v->counter, 1); 98 | } 99 | 100 | /** 101 | * @brief Decrement and test 102 | * @param v pointer of type atomic_t 103 | * 104 | * Atomically decrements @v by 1 and 105 | * returns true if the result is 0, or false for all other 106 | * cases. 107 | */ 108 | static inline int 109 | atomic_dec_and_test(atomic_t *v) { 110 | return !(__sync_sub_and_fetch(&v->counter, 1)); 111 | } 112 | 113 | /** 114 | * @brief Increment and test 115 | * @param v pointer of type atomic_t 116 | * 117 | * Atomically increments @v by 1 118 | * and returns true if the result is zero, or false for all 119 | * other cases. 120 | */ 121 | static inline int 122 | atomic_inc_and_test(atomic_t *v) { 123 | return !(__sync_add_and_fetch(&v->counter, 1)); 124 | } 125 | 126 | /** 127 | * @brief add and test if negative 128 | * @param v pointer of type atomic_t 129 | * @param i integer value to add 130 | * 131 | * Atomically adds @i to @v and returns true 132 | * if the result is negative, or false when 133 | * result is greater than or equal to zero. 134 | */ 135 | static inline int 136 | atomic_add_negative(int i, atomic_t *v) { 137 | return (__sync_add_and_fetch(&v->counter, i) < 0); 138 | } 139 | 140 | #endif /* MY_ATOMIC_H */ 141 | -------------------------------------------------------------------------------- /libmy/atomic_64.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_ATOMIC_64_H 2 | #define MY_ATOMIC_64_H 3 | 4 | #include 5 | 6 | /* public domain, from http://golubenco.org/2007/06/14/atomic-operations/ */ 7 | 8 | /** 9 | * Atomic 64-bit type. 10 | */ 11 | 12 | typedef struct { 13 | volatile int64_t counter; 14 | } atomic64_t; 15 | 16 | #define ATOMIC64_INIT(i) { (i) } 17 | 18 | /** 19 | * Read atomic variable 20 | * @param v pointer of type atomic64_t 21 | * 22 | * Atomically reads the value of @v. 23 | */ 24 | #define atomic64_read(v) ((v)->counter) 25 | 26 | /** 27 | * Set atomic variable 28 | * @param v pointer of type atomic64_t 29 | * @param i required value 30 | */ 31 | #define atomic64_set(v, i) (((v)->counter) = (i)) 32 | 33 | /** 34 | * Add to the atomic variable 35 | * @param i integer value to add 36 | * @param v pointer of type atomic64_t 37 | */ 38 | static inline void 39 | atomic64_add(int i, atomic64_t *v) { 40 | (void)__sync_add_and_fetch(&v->counter, i); 41 | } 42 | 43 | /** 44 | * Subtract the atomic variable 45 | * @param i integer value to subtract 46 | * @param v pointer of type atomic64_t 47 | * 48 | * Atomically subtracts @i from @v. 49 | */ 50 | static inline void 51 | atomic64_sub(int i, atomic64_t *v) { 52 | (void)__sync_sub_and_fetch(&v->counter, i); 53 | } 54 | 55 | /** 56 | * Read atomic variable and reset to zero. 57 | * 58 | * @param v pointer of type atomic64_t 59 | */ 60 | static inline int 61 | atomic64_zero(atomic64_t *v) { 62 | return (__sync_fetch_and_and(&v->counter, 0)); 63 | } 64 | 65 | /** 66 | * Subtract value from variable and test result 67 | * @param i integer value to subtract 68 | * @param v pointer of type atomic64_t 69 | * 70 | * Atomically subtracts @i from @v and returns 71 | * true if the result is zero, or false for all 72 | * other cases. 73 | */ 74 | static inline int 75 | atomic64_sub_and_test(int i, atomic64_t *v) { 76 | return !(__sync_sub_and_fetch(&v->counter, i)); 77 | } 78 | 79 | /** 80 | * Increment atomic variable 81 | * @param v pointer of type atomic64_t 82 | * 83 | * Atomically increments @v by 1. 84 | */ 85 | static inline void 86 | atomic64_inc(atomic64_t *v) { 87 | (void)__sync_fetch_and_add(&v->counter, 1); 88 | } 89 | 90 | /** 91 | * @brief decrement atomic variable 92 | * @param v: pointer of type atomic64_t 93 | * 94 | * Atomically decrements @v by 1. Note that the guaranteed 95 | * useful range of an atomic64_t is only 24 bits. 96 | */ 97 | static inline void 98 | atomic64_dec(atomic64_t *v) { 99 | (void)__sync_fetch_and_sub(&v->counter, 1); 100 | } 101 | 102 | /** 103 | * @brief Decrement and test 104 | * @param v pointer of type atomic64_t 105 | * 106 | * Atomically decrements @v by 1 and 107 | * returns true if the result is 0, or false for all other 108 | * cases. 109 | */ 110 | static inline int 111 | atomic64_dec_and_test(atomic64_t *v) { 112 | return !(__sync_sub_and_fetch(&v->counter, 1)); 113 | } 114 | 115 | /** 116 | * @brief Increment and test 117 | * @param v pointer of type atomic64_t 118 | * 119 | * Atomically increments @v by 1 120 | * and returns true if the result is zero, or false for all 121 | * other cases. 122 | */ 123 | static inline int 124 | atomic64_inc_and_test(atomic64_t *v) { 125 | return !(__sync_add_and_fetch(&v->counter, 1)); 126 | } 127 | 128 | /** 129 | * @brief add and test if negative 130 | * @param v pointer of type atomic64_t 131 | * @param i integer value to add 132 | * 133 | * Atomically adds @i to @v and returns true 134 | * if the result is negative, or false when 135 | * result is greater than or equal to zero. 136 | */ 137 | static inline int 138 | atomic64_add_negative(int i, atomic64_t *v) { 139 | return (__sync_add_and_fetch(&v->counter, i) < 0); 140 | } 141 | 142 | #endif /* MY_ATOMIC_H */ 143 | -------------------------------------------------------------------------------- /libmy/atomic_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_ATOMIC_PTR_H 2 | #define MY_ATOMIC_PTR_H 3 | 4 | typedef struct { 5 | volatile void *ptr; 6 | } atomic_ptr_t; 7 | 8 | static inline void * 9 | atomic_ptr_get(atomic_ptr_t *v) { 10 | return ((void *) (__sync_fetch_and_add(&v->ptr, 0))); 11 | } 12 | 13 | static inline bool 14 | atomic_ptr_set(atomic_ptr_t *v, void *new_ptr) { 15 | void *old_ptr = atomic_ptr_get(v); 16 | return (__sync_bool_compare_and_swap(&v->ptr, old_ptr, new_ptr)); 17 | } 18 | 19 | #endif /* MY_ATOMIC_PTR_H */ 20 | -------------------------------------------------------------------------------- /libmy/b32_decode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Copyright (c) 2006 Christian Biere 19 | * All rights reserved. 20 | * 21 | * Redistribution and use in source and binary forms, with or without 22 | * modification, are permitted provided that the following conditions 23 | * are met: 24 | * 25 | * 1. Redistributions of source code must retain the above copyright 26 | * notice, this list of conditions and the following disclaimer. 27 | * 2. Redistributions in binary form must reproduce the above copyright 28 | * notice, this list of conditions and the following disclaimer in the 29 | * documentation and/or other materials provided with the distribution. 30 | * 3. Neither the name of the authors nor the names of its contributors 31 | * may be used to endorse or promote products derived from this software 32 | * without specific prior written permission. 33 | * 34 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 35 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 38 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44 | * SUCH DAMAGE. 45 | */ 46 | 47 | #ifndef B32_DECODE_H 48 | #define B32_DECODE_H 49 | 50 | size_t base32_decode(void *dst, size_t size, const char *data, size_t len); 51 | 52 | #endif /* B32_DECODE_H */ 53 | -------------------------------------------------------------------------------- /libmy/b32_encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Internet Systems Consortium, Inc. ("ISC") 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | * Copyright (c) 2006 Christian Biere 19 | * All rights reserved. 20 | * 21 | * Redistribution and use in source and binary forms, with or without 22 | * modification, are permitted provided that the following conditions 23 | * are met: 24 | * 25 | * 1. Redistributions of source code must retain the above copyright 26 | * notice, this list of conditions and the following disclaimer. 27 | * 2. Redistributions in binary form must reproduce the above copyright 28 | * notice, this list of conditions and the following disclaimer in the 29 | * documentation and/or other materials provided with the distribution. 30 | * 3. Neither the name of the authors nor the names of its contributors 31 | * may be used to endorse or promote products derived from this software 32 | * without specific prior written permission. 33 | * 34 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 35 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 38 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44 | * SUCH DAMAGE. 45 | */ 46 | 47 | #ifndef B32_ENCODE_H 48 | #define B32_ENCODE_H 49 | 50 | size_t base32_encode(char *dst, size_t dst_len, const void *src, size_t src_len); 51 | 52 | #endif /* B32_ENCODE_H */ 53 | -------------------------------------------------------------------------------- /libmy/b64_decode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cdecoder.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "b64_decode.h" 9 | 10 | int base64_decode_value(char value_in) 11 | { 12 | static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; 13 | static const char decoding_size = sizeof(decoding); 14 | value_in -= 43; 15 | if (value_in < 0 || value_in > decoding_size) return -1; 16 | return decoding[(int)value_in]; 17 | } 18 | 19 | void base64_init_decodestate(base64_decodestate* state_in) 20 | { 21 | state_in->step = step_a; 22 | state_in->plainchar = 0; 23 | } 24 | 25 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 26 | { 27 | const char* codechar = code_in; 28 | char* plainchar = plaintext_out; 29 | char fragment; 30 | 31 | *plainchar = state_in->plainchar; 32 | 33 | switch (state_in->step) 34 | { 35 | while (1) 36 | { 37 | case step_a: 38 | do { 39 | if (codechar == code_in+length_in) 40 | { 41 | state_in->step = step_a; 42 | state_in->plainchar = *plainchar; 43 | return plainchar - plaintext_out; 44 | } 45 | fragment = (char)base64_decode_value(*codechar++); 46 | } while (fragment < 0); 47 | *plainchar = (fragment & 0x03f) << 2; 48 | case step_b: 49 | do { 50 | if (codechar == code_in+length_in) 51 | { 52 | state_in->step = step_b; 53 | state_in->plainchar = *plainchar; 54 | return plainchar - plaintext_out; 55 | } 56 | fragment = (char)base64_decode_value(*codechar++); 57 | } while (fragment < 0); 58 | *plainchar++ |= (fragment & 0x030) >> 4; 59 | *plainchar = (fragment & 0x00f) << 4; 60 | case step_c: 61 | do { 62 | if (codechar == code_in+length_in) 63 | { 64 | state_in->step = step_c; 65 | state_in->plainchar = *plainchar; 66 | return plainchar - plaintext_out; 67 | } 68 | fragment = (char)base64_decode_value(*codechar++); 69 | } while (fragment < 0); 70 | *plainchar++ |= (fragment & 0x03c) >> 2; 71 | *plainchar = (fragment & 0x003) << 6; 72 | case step_d: 73 | do { 74 | if (codechar == code_in+length_in) 75 | { 76 | state_in->step = step_d; 77 | state_in->plainchar = *plainchar; 78 | return plainchar - plaintext_out; 79 | } 80 | fragment = (char)base64_decode_value(*codechar++); 81 | } while (fragment < 0); 82 | *plainchar++ |= (fragment & 0x03f); 83 | } 84 | } 85 | /* control should not reach here */ 86 | return plainchar - plaintext_out; 87 | } 88 | -------------------------------------------------------------------------------- /libmy/b64_decode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CDECODE_H 9 | #define BASE64_CDECODE_H 10 | 11 | typedef enum 12 | { 13 | step_a, step_b, step_c, step_d 14 | } base64_decodestep; 15 | 16 | typedef struct 17 | { 18 | base64_decodestep step; 19 | char plainchar; 20 | } base64_decodestate; 21 | 22 | void base64_init_decodestate(base64_decodestate* state_in); 23 | 24 | int base64_decode_value(char value_in); 25 | 26 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 27 | 28 | #endif /* BASE64_CDECODE_H */ 29 | -------------------------------------------------------------------------------- /libmy/b64_encode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cencoder.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "b64_encode.h" 9 | 10 | void base64_init_encodestate(base64_encodestate* state_in) 11 | { 12 | state_in->step = step_A; 13 | state_in->result = 0; 14 | } 15 | 16 | char base64_encode_value(char value_in) 17 | { 18 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 19 | if (value_in > 63) return '='; 20 | return encoding[(int)value_in]; 21 | } 22 | 23 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 24 | { 25 | const char* plainchar = plaintext_in; 26 | const char* const plaintextend = plaintext_in + length_in; 27 | char* codechar = code_out; 28 | char result; 29 | char fragment; 30 | 31 | result = state_in->result; 32 | 33 | switch (state_in->step) 34 | { 35 | while (1) 36 | { 37 | case step_A: 38 | if (plainchar == plaintextend) 39 | { 40 | state_in->result = result; 41 | state_in->step = step_A; 42 | return codechar - code_out; 43 | } 44 | fragment = *plainchar++; 45 | result = (fragment & 0x0fc) >> 2; 46 | *codechar++ = base64_encode_value(result); 47 | result = (fragment & 0x003) << 4; 48 | case step_B: 49 | if (plainchar == plaintextend) 50 | { 51 | state_in->result = result; 52 | state_in->step = step_B; 53 | return codechar - code_out; 54 | } 55 | fragment = *plainchar++; 56 | result |= (fragment & 0x0f0) >> 4; 57 | *codechar++ = base64_encode_value(result); 58 | result = (fragment & 0x00f) << 2; 59 | case step_C: 60 | if (plainchar == plaintextend) 61 | { 62 | state_in->result = result; 63 | state_in->step = step_C; 64 | return codechar - code_out; 65 | } 66 | fragment = *plainchar++; 67 | result |= (fragment & 0x0c0) >> 6; 68 | *codechar++ = base64_encode_value(result); 69 | result = (fragment & 0x03f) >> 0; 70 | *codechar++ = base64_encode_value(result); 71 | } 72 | } 73 | /* control should not reach here */ 74 | return codechar - code_out; 75 | } 76 | 77 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 78 | { 79 | char* codechar = code_out; 80 | 81 | switch (state_in->step) 82 | { 83 | case step_B: 84 | *codechar++ = base64_encode_value(state_in->result); 85 | *codechar++ = '='; 86 | *codechar++ = '='; 87 | break; 88 | case step_C: 89 | *codechar++ = base64_encode_value(state_in->result); 90 | *codechar++ = '='; 91 | break; 92 | case step_A: 93 | break; 94 | } 95 | 96 | return codechar - code_out; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /libmy/b64_encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | } base64_encodestate; 21 | 22 | void base64_init_encodestate(base64_encodestate* state_in); 23 | 24 | char base64_encode_value(char value_in); 25 | 26 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 27 | 28 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 29 | 30 | #endif /* BASE64_CENCODE_H */ 31 | -------------------------------------------------------------------------------- /libmy/crc32c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include "crc32c.h" 24 | 25 | static uint32_t my_crc32c_first(const uint8_t *buf, size_t len); 26 | 27 | my_crc32c_fp my_crc32c = my_crc32c_first; 28 | 29 | /* crc32c-slicing.c */ 30 | uint32_t my_crc32c_slicing(const uint8_t *, size_t); 31 | 32 | /* crc32c-sse42.c */ 33 | #if __GNUC__ >= 3 && defined(__x86_64__) 34 | bool my_crc32c_sse42_supported(void); 35 | uint32_t my_crc32c_sse42(const uint8_t *, size_t); 36 | #endif 37 | 38 | #if defined(__GNUC__) 39 | __attribute__((constructor)) 40 | #endif 41 | static void 42 | my_crc32c_runtime_detection(void) 43 | { 44 | #if __GNUC__ >= 3 && defined(__x86_64__) 45 | if (my_crc32c_sse42_supported()) { 46 | my_crc32c = my_crc32c_sse42; 47 | } else { 48 | my_crc32c = my_crc32c_slicing; 49 | } 50 | #else 51 | my_crc32c = my_crc32c_slicing; 52 | #endif 53 | } 54 | 55 | static uint32_t 56 | my_crc32c_first(const uint8_t *buf, size_t len) { 57 | my_crc32c_runtime_detection(); 58 | return my_crc32c(buf, len); 59 | } 60 | -------------------------------------------------------------------------------- /libmy/crc32c.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_CRC32C_H 2 | #define MY_CRC32C_H 3 | 4 | #include 5 | 6 | typedef uint32_t (*my_crc32c_fp)(const uint8_t *buffer, size_t length); 7 | 8 | extern my_crc32c_fp my_crc32c; 9 | 10 | #endif /* MY_CRC32C_H */ 11 | -------------------------------------------------------------------------------- /libmy/fast_inet_ntop.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_FAST_INET_NTOP_H 2 | #define MY_FAST_INET_NTOP_H 3 | 4 | #include 5 | 6 | const char *fast_inet4_ntop(const void *restrict src, char *restrict dst, socklen_t size); 7 | const char *fast_inet6_ntop(const void *restrict src, char *restrict dst, socklen_t size); 8 | const char *fast_inet_ntop(int af, const void *restrict src, char *restrict dst, socklen_t size); 9 | 10 | #endif /* MY_FAST_INET_NTOP_H */ 11 | -------------------------------------------------------------------------------- /libmy/getenv_int.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_GETENV_INT_H 2 | #define MY_GETENV_INT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | static inline bool 9 | getenv_int(const char *name, uint64_t *value) { 10 | char *s, *t; 11 | 12 | s = getenv(name); 13 | if (s == NULL) 14 | return (false); 15 | 16 | *value = strtoul(s, &t, 0); 17 | if (*t != '\0') 18 | return (false); 19 | return (true); 20 | } 21 | 22 | #endif /* MY_GETENV_INT_H */ 23 | -------------------------------------------------------------------------------- /libmy/heap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "my_alloc.h" 20 | #include "heap.h" 21 | #include "vector.h" 22 | 23 | VECTOR_GENERATE(ptrvec, void *); 24 | 25 | struct heap { 26 | ptrvec *vec; 27 | heap_compare_func cmp; 28 | }; 29 | 30 | static inline int 31 | cmp_wrapper(heap_compare_func cmp, const void *a, const void *b) 32 | { 33 | return ((cmp(a, b) < 0) ? 1 : 0); 34 | } 35 | 36 | struct heap * 37 | heap_init(heap_compare_func cmp) 38 | { 39 | struct heap *h = my_calloc(1, sizeof(*h)); 40 | h->cmp = cmp; 41 | h->vec = ptrvec_init(1); 42 | return (h); 43 | } 44 | 45 | void 46 | heap_destroy(struct heap **h) 47 | { 48 | if (*h != NULL) { 49 | ptrvec_destroy(&(*h)->vec); 50 | free(*h); 51 | *h = NULL; 52 | } 53 | } 54 | 55 | static int 56 | siftdown(struct heap *h, size_t startpos, size_t pos) 57 | { 58 | assert(pos < ptrvec_size(h->vec)); 59 | void *newitem = ptrvec_value(h->vec, pos); 60 | while (pos > startpos) { 61 | size_t parentpos = (pos - 1) >> 1; 62 | void *parent = ptrvec_value(h->vec, parentpos); 63 | int cmp = cmp_wrapper(h->cmp, newitem, parent); 64 | if (cmp == -1) 65 | return (-1); 66 | if (cmp == 0) 67 | break; 68 | ptrvec_data(h->vec)[pos] = parent; 69 | pos = parentpos; 70 | } 71 | ptrvec_data(h->vec)[pos] = newitem; 72 | return (0); 73 | } 74 | 75 | static int 76 | siftup(struct heap *h, size_t pos) 77 | { 78 | assert(pos < ptrvec_size(h->vec)); 79 | void *newitem = ptrvec_value(h->vec, pos); 80 | size_t endpos = ptrvec_size(h->vec); 81 | size_t startpos = pos; 82 | size_t childpos = 2 * pos + 1; 83 | while (childpos < endpos) { 84 | size_t rightpos = childpos + 1; 85 | if (rightpos < endpos) { 86 | int cmp = cmp_wrapper(h->cmp, 87 | ptrvec_value(h->vec, childpos), 88 | ptrvec_value(h->vec, rightpos)); 89 | if (cmp == -1) 90 | return (-1); 91 | if (cmp == 0) 92 | childpos = rightpos; 93 | } 94 | ptrvec_data(h->vec)[pos] = ptrvec_value(h->vec, childpos); 95 | pos = childpos; 96 | childpos = 2 * pos + 1; 97 | } 98 | ptrvec_data(h->vec)[pos] = newitem; 99 | return (siftdown(h, startpos, pos)); 100 | } 101 | 102 | void 103 | heap_push(struct heap *h, void *item) 104 | { 105 | ptrvec_add(h->vec, item); 106 | siftdown(h, 0, ptrvec_size(h->vec) - 1); 107 | } 108 | 109 | void * 110 | heap_pop(struct heap *h) 111 | { 112 | if (ptrvec_size(h->vec) < 1) 113 | return (NULL); 114 | void *returnitem; 115 | void *lastelt = ptrvec_value(h->vec, ptrvec_size(h->vec) - 1); 116 | ptrvec_clip(h->vec, ptrvec_size(h->vec) - 1); 117 | if (ptrvec_size(h->vec) > 0) { 118 | returnitem = ptrvec_value(h->vec, 0); 119 | ptrvec_data(h->vec)[0] = lastelt; 120 | siftup(h, 0); 121 | } else { 122 | returnitem = lastelt; 123 | } 124 | return (returnitem); 125 | } 126 | 127 | void * 128 | heap_replace(struct heap *h, void *item) 129 | { 130 | if (ptrvec_size(h->vec) < 1) 131 | return (NULL); 132 | void *returnitem = ptrvec_value(h->vec, 0); 133 | ptrvec_data(h->vec)[0] = item; 134 | siftup(h, 0); 135 | return (returnitem); 136 | } 137 | 138 | void * 139 | heap_peek(struct heap *h) 140 | { 141 | if (ptrvec_size(h->vec) < 1) 142 | return (NULL); 143 | return ptrvec_data(h->vec)[0]; 144 | } 145 | 146 | void * 147 | heap_get(struct heap *h, size_t i) 148 | { 149 | if (i > ptrvec_size(h->vec) - 1) 150 | return (NULL); 151 | return (ptrvec_value(h->vec, i)); 152 | } 153 | 154 | size_t 155 | heap_size(struct heap *h) 156 | { 157 | return (ptrvec_size(h->vec)); 158 | } 159 | -------------------------------------------------------------------------------- /libmy/heap.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_HEAP_H 2 | #define MY_HEAP_H 3 | 4 | struct heap; 5 | 6 | typedef int (*heap_compare_func)(const void *a, const void *b); 7 | 8 | struct heap *heap_init(heap_compare_func); 9 | void heap_destroy(struct heap **); 10 | void heap_push(struct heap *, void *); 11 | void *heap_pop(struct heap *); 12 | void *heap_replace(struct heap *, void *); 13 | void *heap_peek(struct heap *); 14 | void *heap_get(struct heap *, size_t); 15 | size_t heap_size(struct heap *); 16 | 17 | #endif /* MY_HEAP_H */ 18 | -------------------------------------------------------------------------------- /libmy/hex_decode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_HEX_DECODE_H 18 | #define MY_HEX_DECODE_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "my_alloc.h" 26 | 27 | static inline bool 28 | hex_to_int(char hex, uint8_t *val) 29 | { 30 | hex = toupper(hex); 31 | switch (hex) { 32 | case '0': 33 | case '1': 34 | case '2': 35 | case '3': 36 | case '4': 37 | case '5': 38 | case '6': 39 | case '7': 40 | case '8': 41 | case '9': 42 | *val = (hex - '0'); 43 | return (true); 44 | case 'A': 45 | case 'B': 46 | case 'C': 47 | case 'D': 48 | case 'E': 49 | case 'F': 50 | *val = (hex - 55); 51 | return (true); 52 | default: 53 | return (false); 54 | } 55 | } 56 | 57 | static inline bool 58 | hex_decode(const char *hex, uint8_t **raw, size_t *len) 59 | { 60 | size_t hexlen = strlen(hex); 61 | uint8_t *p; 62 | 63 | if (hexlen == 0 || (hexlen % 2) != 0) 64 | return (false); 65 | *len = hexlen / 2; 66 | p = *raw = my_malloc(*len); 67 | while (hexlen != 0) { 68 | uint8_t val[2]; 69 | 70 | if (!hex_to_int(*hex, &val[0])) 71 | goto err; 72 | hex++; 73 | if (!hex_to_int(*hex, &val[1])) 74 | goto err; 75 | hex++; 76 | 77 | *p = (val[0] << 4) | val[1]; 78 | p++; 79 | 80 | hexlen -= 2; 81 | } 82 | return (true); 83 | err: 84 | my_free(*raw); 85 | return (false); 86 | } 87 | 88 | #endif /* MY_HEX_DECODE_H */ 89 | -------------------------------------------------------------------------------- /libmy/ip_arith.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_IP_ARITH_H 18 | #define MY_IP_ARITH_H 19 | 20 | #ifdef HAVE_ENDIAN_H 21 | # include 22 | #else 23 | # ifdef HAVE_SYS_ENDIAN_H 24 | # include 25 | # endif 26 | #endif 27 | 28 | #include 29 | #include 30 | 31 | /* given big endian IPv4 prefix in 'address'/'prefix_len', 32 | * write lowest IP address ("network address") into 'out' */ 33 | static inline void 34 | ip4_lower(const void *address, unsigned prefix_len, void *out) { 35 | uint32_t addr; 36 | memcpy(&addr, address, 4); 37 | addr &= htobe32(~((1 << (32 - prefix_len)) - 1)); 38 | memcpy(out, &addr, 4); 39 | } 40 | 41 | /* given big endian IPv4 prefix in 'address'/'prefix_len', 42 | * write highest IP address ("broadcast address") into 'out' */ 43 | static inline void 44 | ip4_upper(const void *address, unsigned prefix_len, void *out) { 45 | uint32_t addr; 46 | memcpy(&addr, address, 4); 47 | addr |= htobe32((1 << (32 - prefix_len)) - 1); 48 | memcpy(out, &addr, 4); 49 | } 50 | 51 | /* increment IPv4 address by 1 */ 52 | static inline void 53 | ip4_incr(void *address) { 54 | uint32_t addr; 55 | memcpy(&addr, address, 4); 56 | addr = be32toh(addr) + 1; 57 | addr = htobe32(addr); 58 | memcpy(address, &addr, 4); 59 | } 60 | 61 | /* given big endian IPv6 prefix in 'address'/'prefix_len', 62 | * write lowest IP address ("network address") into 'lower' */ 63 | static inline void 64 | ip6_lower(const void *address, unsigned prefix_len, void *lower) 65 | { 66 | uint64_t addr[2], mask[2]; 67 | if (prefix_len < 64) { 68 | mask[0] = htobe64(((1ULL << prefix_len) - 1ULL) << (64ULL - prefix_len)); 69 | mask[1] = htobe64(0); 70 | } else if (prefix_len < 128) { 71 | prefix_len -= 64; 72 | mask[0] = htobe64(UINT64_MAX); 73 | mask[1] = htobe64(((1ULL << prefix_len) - 1ULL) << (64ULL - prefix_len)); 74 | } else { 75 | memset(mask, 0xFF, sizeof(mask)); 76 | } 77 | memcpy(addr, address, 16); 78 | addr[0] &= mask[0]; 79 | addr[1] &= mask[1]; 80 | memcpy(lower, addr, 16); 81 | } 82 | 83 | /* given big endian IPv6 prefix in 'address'/'prefix_len', 84 | * write highest IP address ("broadcast address") into 'upper' */ 85 | static inline void 86 | ip6_upper(const void *address, unsigned prefix_len, void *upper) 87 | { 88 | uint64_t addr[2], mask[2]; 89 | if (prefix_len < 64) { 90 | mask[0] = htobe64(~(((1ULL << prefix_len) - 1ULL) << (64ULL - prefix_len))); 91 | mask[1] = htobe64(UINT64_MAX); 92 | } else if (prefix_len < 128) { 93 | prefix_len -= 64; 94 | mask[0] = htobe64(0); 95 | mask[1] = htobe64(~(((1ULL << prefix_len) - 1ULL) << (64ULL - prefix_len))); 96 | } else { 97 | memset(&mask, 0, sizeof(mask)); 98 | } 99 | memcpy(addr, address, 16); 100 | addr[0] |= mask[0]; 101 | addr[1] |= mask[1]; 102 | memcpy(upper, addr, 16); 103 | } 104 | 105 | /* increment IPv6 address by 1 */ 106 | static inline void 107 | ip6_incr(void *address) { 108 | uint64_t addr[2]; 109 | memcpy(addr, address, 16); 110 | addr[0] = be64toh(addr[0]); 111 | addr[1] = be64toh(addr[1]); 112 | if (addr[1] == UINT64_MAX) { 113 | addr[0] += 1; 114 | addr[1] = 0; 115 | } else { 116 | addr[1] += 1; 117 | } 118 | addr[0] = htobe64(addr[0]); 119 | addr[1] = htobe64(addr[1]); 120 | memcpy(address, addr, 16); 121 | } 122 | 123 | #endif /* MY_IP_ARITH_H */ 124 | -------------------------------------------------------------------------------- /libmy/lookup3.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_LOOKUP3_H 2 | #define MY_LOOKUP3_H 3 | 4 | #include 5 | 6 | uint32_t my_hashword(const uint32_t *key, size_t length, uint32_t initval); 7 | uint32_t my_hashlittle(const void *key, size_t length, uint32_t initval); 8 | uint32_t my_hashbig(const void *key, size_t length, uint32_t initval); 9 | void my_hashword2(const uint32_t *key, size_t length, uint32_t *pc, uint32_t *pb); 10 | void my_hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); 11 | 12 | #endif /* MY_LOOKUP3_H */ 13 | -------------------------------------------------------------------------------- /libmy/m4/ax_define_dir.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_define_dir.html 3 | # =========================================================================== 4 | # 5 | # OBSOLETE MACRO 6 | # 7 | # Deprecated because it does not comply with the GNU Coding Standards. See 8 | # the autoconf manual section "Defining Directories" for alternatives. 9 | # 10 | # SYNOPSIS 11 | # 12 | # AX_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION]) 13 | # 14 | # DESCRIPTION 15 | # 16 | # This macro sets VARNAME to the expansion of the DIR variable, taking 17 | # care of fixing up ${prefix} and such. 18 | # 19 | # VARNAME is then offered as both an output variable and a C preprocessor 20 | # symbol. 21 | # 22 | # Example: 23 | # 24 | # AX_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.]) 25 | # 26 | # LICENSE 27 | # 28 | # Copyright (c) 2008 Stepan Kasal 29 | # Copyright (c) 2008 Andreas Schwab 30 | # Copyright (c) 2008 Guido U. Draheim 31 | # Copyright (c) 2008 Alexandre Oliva 32 | # 33 | # Copying and distribution of this file, with or without modification, are 34 | # permitted in any medium without royalty provided the copyright notice 35 | # and this notice are preserved. This file is offered as-is, without any 36 | # warranty. 37 | 38 | #serial 8 39 | 40 | AU_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR]) 41 | AC_DEFUN([AX_DEFINE_DIR], [ 42 | prefix_NONE= 43 | exec_prefix_NONE= 44 | test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix 45 | test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix 46 | dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn 47 | dnl refers to ${prefix}. Thus we have to use `eval' twice. 48 | eval ax_define_dir="\"[$]$2\"" 49 | eval ax_define_dir="\"$ax_define_dir\"" 50 | AC_SUBST($1, "$ax_define_dir") 51 | AC_DEFINE_UNQUOTED($1, "$ax_define_dir", [$3]) 52 | test "$prefix_NONE" && prefix=NONE 53 | test "$exec_prefix_NONE" && exec_prefix=NONE 54 | ]) 55 | -------------------------------------------------------------------------------- /libmy/m4/ax_prog_xsltproc.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_prog_xsltproc.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_PROG_XSLTPROC([default-flags]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Find an xsltproc executable. 12 | # 13 | # Input: 14 | # 15 | # "default-flags" is the default $XSLTPROC_FLAGS, which will be overridden 16 | # if the user specifies --with-xsltproc-flags. 17 | # 18 | # Output: 19 | # 20 | # $XSLTPROC contains the path to xsltproc, or is empty if none was found 21 | # or the user specified --without-xsltproc. $XSLTPROC_FLAGS contains the 22 | # flags to use with xsltproc. 23 | # 24 | # LICENSE 25 | # 26 | # Copyright (c) 2008,2009 Zmanda Inc. 27 | # Copyright (c) 2008,2009 Dustin J. Mitchell 28 | # 29 | # This program is free software; you can redistribute it and/or modify it 30 | # under the terms of the GNU General Public License as published by the 31 | # Free Software Foundation; either version 2 of the License, or (at your 32 | # option) any later version. 33 | # 34 | # This program is distributed in the hope that it will be useful, but 35 | # WITHOUT ANY WARRANTY; without even the implied warranty of 36 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 37 | # Public License for more details. 38 | # 39 | # You should have received a copy of the GNU General Public License along 40 | # with this program. If not, see . 41 | # 42 | # As a special exception, the respective Autoconf Macro's copyright owner 43 | # gives unlimited permission to copy, distribute and modify the configure 44 | # scripts that are the output of Autoconf when processing the Macro. You 45 | # need not follow the terms of the GNU General Public License when using 46 | # or distributing such scripts, even though portions of the text of the 47 | # Macro appear in them. The GNU General Public License (GPL) does govern 48 | # all other use of the material that constitutes the Autoconf Macro. 49 | # 50 | # This special exception to the GPL applies to versions of the Autoconf 51 | # Macro released by the Autoconf Archive. When you make and distribute a 52 | # modified version of the Autoconf Macro, you may extend this special 53 | # exception to the GPL to apply to your modified version as well. 54 | 55 | #serial 5 56 | 57 | AU_ALIAS([AC_PROG_XSLTPROC], [AX_PROG_XSLTPROC]) 58 | AC_DEFUN([AX_PROG_XSLTPROC], 59 | [ 60 | XSLTPROC_FLAGS="$1" 61 | AC_SUBST(XSLTPROC_FLAGS) 62 | 63 | # The (lack of) whitespace and overquoting here are all necessary for 64 | # proper formatting. 65 | AC_ARG_WITH(xsltproc, 66 | AS_HELP_STRING([--with-xsltproc[[[[[=PATH]]]]]], 67 | [Use the xsltproc binary in PATH.]), 68 | [ ac_with_xsltproc=$withval; ], 69 | [ ac_with_xsltproc=maybe; ]) 70 | 71 | AC_ARG_WITH(xsltproc-flags, 72 | AS_HELP_STRING([ --with-xsltproc-flags=FLAGS], 73 | [Flags to pass to xsltproc (default $1)]), 74 | [ if test "x$withval" == "xno"; then 75 | XSLTPROC_FLAGS='' 76 | else 77 | if test "x$withval" != "xyes"; then 78 | XSLTPROC_FLAGS="$withval" 79 | fi 80 | fi 81 | ]) 82 | 83 | # search for xsltproc if it wasn't specified 84 | if test "$ac_with_xsltproc" = "yes" -o "$ac_with_xsltproc" = "maybe"; then 85 | AC_PATH_PROGS(XSLTPROC,xsltproc) 86 | else 87 | if test "$ac_with_xsltproc" != "no"; then 88 | if test -x "$ac_with_xsltproc"; then 89 | XSLTPROC="$ac_with_xsltproc"; 90 | else 91 | AC_MSG_WARN([Specified xsltproc of $ac_with_xsltproc isn't]) 92 | AC_MSG_WARN([executable; searching for an alternative.]) 93 | AC_PATH_PROGS(XSLTPROC,xsltproc) 94 | fi 95 | fi 96 | fi 97 | ]) 98 | -------------------------------------------------------------------------------- /libmy/m4/ld-version-script.m4: -------------------------------------------------------------------------------- 1 | # ld-version-script.m4 serial 3 2 | dnl Copyright (C) 2008-2014 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Simon Josefsson 8 | 9 | # FIXME: The test below returns a false positive for mingw 10 | # cross-compiles, 'local:' statements does not reduce number of 11 | # exported symbols in a DLL. Use --disable-ld-version-script to work 12 | # around the problem. 13 | 14 | # gl_LD_VERSION_SCRIPT 15 | # -------------------- 16 | # Check if LD supports linker scripts, and define automake conditional 17 | # HAVE_LD_VERSION_SCRIPT if so. 18 | AC_DEFUN([gl_LD_VERSION_SCRIPT], 19 | [ 20 | AC_ARG_ENABLE([ld-version-script], 21 | AS_HELP_STRING([--enable-ld-version-script], 22 | [enable linker version script (default is enabled when possible)]), 23 | [have_ld_version_script=$enableval], []) 24 | if test -z "$have_ld_version_script"; then 25 | AC_MSG_CHECKING([if LD -Wl,--version-script works]) 26 | save_LDFLAGS="$LDFLAGS" 27 | LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" 28 | cat > conftest.map < conftest.map </dev/null | grep -q /libdata/; then 38 | pkgconfig_dir='${prefix}/libdata/pkgconfig' 39 | fi 40 | fi 41 | PKG_INSTALLDIR([$pkgconfig_dir]) 42 | 43 | if test "x$pkgconfigdir" != "xno"; then 44 | if test -z "$PKG_CONFIG"; then 45 | AC_MSG_ERROR([pkg-config is required!]) 46 | fi 47 | $1=$2 48 | AC_SUBST([$1]) 49 | fi 50 | ]) 51 | -------------------------------------------------------------------------------- /libmy/m4/pcap.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([MY_CHECK_LIBPCAP], [ 2 | libpcap_CFLAGS="" 3 | libpcap_LIBS="-lpcap" 4 | 5 | AC_ARG_WITH( 6 | [libpcap], 7 | AC_HELP_STRING([--with-libpcap=DIR], [libpcap installation path]), 8 | [], 9 | [withval="yes"] 10 | ) 11 | if test "$withval" = "yes"; then 12 | withval="/usr /usr/local" 13 | fi 14 | 15 | libpcap_dir="" 16 | 17 | AC_MSG_CHECKING([for libpcap headers]) 18 | for dir in $withval; do 19 | if test -f "$dir/include/pcap.h"; then 20 | libpcap_dir="$dir" 21 | if test "$dir" != "/usr"; then 22 | libpcap_CFLAGS="-I$dir/include" 23 | fi 24 | break 25 | fi 26 | done 27 | if test -n "$libpcap_dir"; then 28 | AC_MSG_RESULT([$libpcap_dir]) 29 | else 30 | AC_MSG_ERROR([cannot find pcap.h in $withval]) 31 | fi 32 | 33 | save_LDFLAGS="$LDFLAGS" 34 | save_LIBS="$LIBS" 35 | if test "$libpcap_dir" != "/usr"; then 36 | libpcap_LIBS="$libpcap_LIBS -L$libpcap_dir/lib" 37 | LDFLAGS="-L$libpcap_dir/lib" 38 | fi 39 | AC_CHECK_LIB( 40 | [pcap], 41 | [pcap_open_offline], 42 | [], 43 | [AC_MSG_ERROR([required library not found])] 44 | ) 45 | AC_SEARCH_LIBS( 46 | [pcap_create], 47 | [pcap], 48 | AC_DEFINE([HAVE_PCAP_CREATE], [1], [Define to 1 if pcap_create() is available.]) 49 | ) 50 | LDFLAGS="$save_LDFLAGS" 51 | LIBS="$save_LIBS" 52 | 53 | AC_SUBST([libpcap_CFLAGS]) 54 | AC_SUBST([libpcap_LIBS]) 55 | ]) 56 | -------------------------------------------------------------------------------- /libmy/m4/protobuf-c.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([MY_CHECK_LIBPROTOBUF_C], [ 2 | libprotobuf_c_CFLAGS="" 3 | libprotobuf_c_LIBS="-lprotobuf-c" 4 | 5 | AC_ARG_WITH( 6 | [libprotobuf_c], 7 | AC_HELP_STRING([--with-libprotobuf_c=DIR], [libprotobuf-c installation path]), 8 | [], 9 | [withval="yes"] 10 | ) 11 | if test "$withval" = "yes"; then 12 | withval="/usr /usr/local" 13 | fi 14 | 15 | libprotobuf_c_dir="" 16 | 17 | AC_MSG_CHECKING([for libprotobuf-c headers]) 18 | for dir in $withval; do 19 | if test -f "$dir/include/protobuf-c/protobuf-c.h"; then 20 | libprotobuf_c_dir="$dir" 21 | if test "$dir" != "/usr"; then 22 | libprotobuf_c_CFLAGS="-I$dir/include" 23 | fi 24 | break 25 | elif test -f "$dir/include/google/protobuf-c/protobuf-c.h"; then 26 | libprotobuf_c_dir="$dir" 27 | libprotobuf_c_CFLAGS="-I$dir/include/google" 28 | break 29 | fi 30 | done 31 | if test -n "$libprotobuf_c_dir"; then 32 | AC_MSG_RESULT([$libprotobuf_c_dir]) 33 | else 34 | AC_MSG_ERROR([cannot find protobuf-c.h in $withval]) 35 | fi 36 | 37 | save_LDFLAGS="$LDFLAGS" 38 | save_LIBS="$LIBS" 39 | if test "$libprotobuf_c_dir" != "/usr"; then 40 | libprotobuf_c_LIBS="$libprotobuf_c_LIBS -L$libprotobuf_c_dir/lib" 41 | LDFLAGS="-L$libprotobuf_c_dir/lib" 42 | fi 43 | AC_CHECK_LIB( 44 | [protobuf-c], 45 | [protobuf_c_message_pack], 46 | [], 47 | [AC_MSG_ERROR([required library not found])] 48 | ) 49 | LDFLAGS="$save_LDFLAGS" 50 | LIBS="$save_LIBS" 51 | 52 | AC_SUBST([libprotobuf_c_CFLAGS]) 53 | AC_SUBST([libprotobuf_c_LIBS]) 54 | 55 | AC_PATH_PROG([PROTOC_C], [protoc-c]) 56 | if test -z "$PROTOC_C"; then 57 | AC_MSG_ERROR([The protoc-c program was not found. Please install the protobuf-c compiler!]) 58 | fi 59 | ]) 60 | -------------------------------------------------------------------------------- /libmy/my_alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_ALLOC_H 2 | #define MY_ALLOC_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | static inline void * 9 | my_calloc(size_t nmemb, size_t size) 10 | { 11 | void *ptr = calloc(nmemb, size); 12 | assert(ptr != NULL); 13 | return (ptr); 14 | } 15 | 16 | static inline void * 17 | my_malloc(size_t size) 18 | { 19 | void *ptr = malloc(size); 20 | assert(ptr != NULL); 21 | return (ptr); 22 | } 23 | 24 | static inline void * 25 | my_realloc(void *ptr, size_t size) 26 | { 27 | ptr = realloc(ptr, size); 28 | assert(ptr != NULL); 29 | return (ptr); 30 | } 31 | 32 | static inline char * 33 | my_strdup(const char *s) 34 | { 35 | char *ptr = strdup(s); 36 | assert(ptr != NULL); 37 | return (ptr); 38 | } 39 | 40 | #define my_free(ptr) do { free(ptr); (ptr) = NULL; } while (0) 41 | 42 | #if defined(MY_ALLOC_WARN_DEPRECATED) 43 | 44 | static inline void *my_calloc_deprecated(size_t, size_t) 45 | __attribute__ ((deprecated("use my_calloc, not calloc"))); 46 | 47 | static inline void *my_malloc_deprecated(size_t) 48 | __attribute__ ((deprecated("use my_malloc, not malloc"))); 49 | 50 | static inline void *my_realloc_deprecated(void *, size_t) 51 | __attribute__ ((deprecated("use my_realloc, not realloc"))); 52 | 53 | static inline void * 54 | my_calloc_deprecated(size_t nmemb, size_t size) 55 | { 56 | return calloc(nmemb, size); 57 | } 58 | 59 | static inline void * 60 | my_malloc_deprecated(size_t size) 61 | { 62 | return malloc(size); 63 | } 64 | 65 | static inline void * 66 | my_realloc_deprecated(void *ptr, size_t size) 67 | { 68 | return realloc(ptr, size); 69 | } 70 | 71 | #define calloc my_calloc_deprecated 72 | #define malloc my_malloc_deprecated 73 | #define realloc my_realloc_deprecated 74 | 75 | #endif /* MY_ALLOC_WARN_DEPRECATED */ 76 | 77 | #endif /* MY_ALLOC_H */ 78 | -------------------------------------------------------------------------------- /libmy/my_byteorder.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_BYTEORDER_H 2 | #define MY_BYTEORDER_H 3 | 4 | #include "config.h" 5 | 6 | #ifdef HAVE_ENDIAN_H 7 | # include 8 | #else 9 | # ifdef HAVE_SYS_ENDIAN_H 10 | # include 11 | # endif 12 | #endif 13 | 14 | #if HAVE_DECL_HTOLE32 15 | # define my_htole32 htole32 16 | #else 17 | # if defined(WORDS_BIGENDIAN) 18 | # define my_htole32 my_bswap32 19 | # else 20 | # define my_htole32(x) (x) 21 | # endif 22 | #endif 23 | 24 | #if HAVE_DECL_LE32TOH 25 | # define my_le32toh le32toh 26 | #else 27 | # if defined(WORDS_BIGENDIAN) 28 | # define my_le32toh my_bswap32 29 | # else 30 | # define my_le32toh(x) (x) 31 | # endif 32 | #endif 33 | 34 | static inline uint32_t 35 | my_bswap32(uint32_t x) 36 | { 37 | return ((x << 24) & 0xff000000 ) | 38 | ((x << 8) & 0x00ff0000 ) | 39 | ((x >> 8) & 0x0000ff00 ) | 40 | ((x >> 24) & 0x000000ff ); 41 | } 42 | 43 | #endif /* MY_BYTEORDER_H */ 44 | -------------------------------------------------------------------------------- /libmy/my_fileset.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_FILESET_H 2 | #define MY_FILESET_H 3 | 4 | #include 5 | 6 | struct my_fileset; 7 | 8 | typedef void *(*my_fileset_load_func)(struct my_fileset *, const char *fname); 9 | typedef void (*my_fileset_unload_func)(struct my_fileset *, const char *fname, void *); 10 | 11 | struct my_fileset *my_fileset_init( 12 | const char *setfile, 13 | my_fileset_load_func, 14 | my_fileset_unload_func, 15 | void *user); 16 | void my_fileset_destroy(struct my_fileset **); 17 | void *my_fileset_user(struct my_fileset *); 18 | void my_fileset_reload(struct my_fileset *); 19 | bool my_fileset_get(struct my_fileset *, size_t, const char **, void **); 20 | 21 | #endif /* MY_FILESET_H */ 22 | -------------------------------------------------------------------------------- /libmy/my_format.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "libmy/my_format.h" 20 | 21 | 22 | static inline const char * 23 | _my_byte_to_hex_str(uint8_t byte, bool is_upper, char *dst) 24 | { 25 | static const char *__hexchars = "0123456789abcdef"; 26 | static const char *__HEXCHARS = "0123456789ABCDEF"; 27 | const char *table = (is_upper ? __HEXCHARS : __hexchars); 28 | 29 | dst[0] = table[(byte >> 4) & 0xf]; 30 | dst[1] = table[byte & 0xf]; 31 | 32 | return dst; 33 | } 34 | 35 | size_t 36 | my_bytes_to_hex_str(const uint8_t *src, size_t len, bool is_upper, char *dst, size_t dst_size) 37 | { 38 | size_t n; 39 | 40 | if ((len * 2) > (dst_size - 1)) 41 | len = (dst_size - 1) / 2; 42 | 43 | for (n = 0; n < len; n++) 44 | _my_byte_to_hex_str(src[n], is_upper, &dst[n * 2]); 45 | 46 | dst[n * 2] = '\x00'; 47 | 48 | return len * 2; 49 | } 50 | 51 | size_t 52 | my_uint16_to_hex_str(uint16_t num, bool is_upper, char *dst, size_t dst_size) 53 | { 54 | uint16_t nval = htons(num); 55 | 56 | return my_bytes_to_hex_str((const uint8_t *) &nval, sizeof(nval), is_upper, dst, dst_size); 57 | } 58 | 59 | size_t 60 | my_uint64_to_str(uint64_t num, char *dst, size_t dst_size, const char **start) 61 | { 62 | size_t ndigits = 0; 63 | char *ptr = &dst[dst_size - 1]; 64 | 65 | *ptr-- = '\0'; 66 | 67 | while (ptr >= dst) { 68 | *ptr = '0' + num % 10; 69 | ndigits++; 70 | num /= 10; 71 | 72 | if (num == 0 || ptr == dst) 73 | break; 74 | 75 | ptr--; 76 | } 77 | 78 | if (start != NULL) 79 | *start = ptr; 80 | 81 | return ndigits; 82 | } 83 | -------------------------------------------------------------------------------- /libmy/my_format.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_NUM_TO_STR_H 2 | #define MY_NUM_TO_STR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* 9 | * Format bytes as a NUL-terminated hex string, with each byte represented as two characters. 10 | * 11 | * Returns the size of the formatted string, up to a maximum of dst_size bytes. 12 | */ 13 | size_t my_bytes_to_hex_str(const uint8_t *src, size_t len, bool is_upper, char *dst, size_t dst_size); 14 | 15 | /* 16 | * Format num as a NUL-terminated hex string of up to dst_size bytes. 17 | * 18 | * Returns the size of the formatted string. 19 | */ 20 | size_t my_uint16_to_hex_str(uint16_t num, bool is_upper, char *dst, size_t dst_size); 21 | 22 | /* 23 | * Format num as a numerical NUL-terminated string of up to dst_size bytes. 24 | * If start is non-NULL, it will receive a pointer to the first digit in 25 | * the formatted string. The formatted string will end at the end of the 26 | * dst buffer, which the caller may fill with padding characters if needed. 27 | * 28 | * Returns the number of digits in the formatted string. 29 | */ 30 | size_t my_uint64_to_str(uint64_t num, char *dst, size_t dst_size, const char **start); 31 | 32 | #endif /* MY_NUM_TO_STR_H */ 33 | -------------------------------------------------------------------------------- /libmy/my_memory_barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_MEMORY_BARRIER_H 2 | #define MY_MEMORY_BARRIER_H 3 | 4 | #if defined(__GNUC__) 5 | # if defined(__x86_64__) 6 | # define MY_HAVE_MEMORY_BARRIERS 1 7 | # define smp_mb() asm volatile("mfence" ::: "memory") 8 | # define smp_rmb() asm volatile("" ::: "memory") 9 | # define smp_wmb() asm volatile("" ::: "memory") 10 | # elif defined(__ia64__) 11 | # define MY_HAVE_MEMORY_BARRIERS 1 12 | # define smp_mb() asm volatile ("mf" ::: "memory") 13 | # define smp_rmb() asm volatile ("mf" ::: "memory") 14 | # define smp_wmb() asm volatile ("mf" ::: "memory") 15 | # endif 16 | #endif 17 | 18 | #endif /* MY_MEMORY_BARRIER_H */ 19 | -------------------------------------------------------------------------------- /libmy/my_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "my_memory_barrier.h" 18 | 19 | #ifdef MY_HAVE_MEMORY_BARRIERS 20 | # define my_queue_mb_init my_queue_init 21 | # define my_queue_mb_destroy my_queue_destroy 22 | # define my_queue_mb_impl_type my_queue_impl_type 23 | # define my_queue_mb_insert my_queue_insert 24 | # define my_queue_mb_remove my_queue_remove 25 | # include "my_queue_mb.c" 26 | #else 27 | # define my_queue_mutex_init my_queue_init 28 | # define my_queue_mutex_destroy my_queue_destroy 29 | # define my_queue_mutex_impl_type my_queue_impl_type 30 | # define my_queue_mutex_insert my_queue_insert 31 | # define my_queue_mutex_remove my_queue_remove 32 | # include "my_queue_mutex.c" 33 | #endif 34 | -------------------------------------------------------------------------------- /libmy/my_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_QUEUE_H 2 | #define MY_QUEUE_H 3 | 4 | #include 5 | 6 | /** 7 | * \file 8 | * 9 | * Fixed-size single-producer / single-consumer queue. 10 | * 11 | * This is a generic queue that supports a single producer thread and a 12 | * single consumer thread. The implementation uses a fixed power-of-2 size 13 | * circular buffer. 14 | * 15 | * The my_queue_insert() and my_queue_remove() functions are "non-blocking"; 16 | * that is, the policies for queue full / queue empty conditions are left to 17 | * the caller. These functions return a boolean indicating whether the queue 18 | * operation succeeded or not. For example, a producer that spins until an 19 | * element is successfully enqueued might look like: 20 | * 21 | * void *item; 22 | * produce_item(&item); 23 | * while (!my_queue_insert(q, item, NULL)); 24 | * 25 | * And a consumer that spins until an element is successfully dequeued 26 | * might look like: 27 | * 28 | * void *item; 29 | * while (!my_queue_remove(q, &item, NULL)); 30 | * consume_item(item); 31 | * 32 | * The my_queue_insert() and my_queue_remove() functions take an optional third 33 | * parameter for returning the spaces remaining in the queue or the count of 34 | * elements remaining, respectively. This allows for more complicated 35 | * coordination between producer and consumer, for instance a consumer thread 36 | * that sleeps when the queue is empty and is woken by the producer when it 37 | * adds an element to an empty queue. 38 | */ 39 | 40 | struct my_queue; 41 | 42 | /** 43 | * Initialize a new queue. 44 | * 45 | * \param[in] num_entries Number of elements in the queue. Must be >=2, and a power-of-2. 46 | * \param[in] size_entry Size in bytes of each queue entry. 47 | * \return Opaque pointer that is NULL on failure or non-NULL on success. 48 | */ 49 | struct my_queue * 50 | my_queue_init(unsigned num_entries, unsigned size_entry); 51 | 52 | /** 53 | * Destroy a queue. 54 | */ 55 | void 56 | my_queue_destroy(struct my_queue **q); 57 | 58 | /** 59 | * Describe the queue implementation type. 60 | */ 61 | const char * 62 | my_queue_impl_type(void); 63 | 64 | /** 65 | * Insert an element into the queue. 66 | * 67 | * \param[in] q Queue object. 68 | * \param[in] elem Element object. 69 | * \param[out] space If non-NULL, pointer to store the number of remaining 70 | * spaces in the queue. 71 | * \return true if the element was inserted into the queue, 72 | * false if the queue is full. 73 | */ 74 | bool 75 | my_queue_insert(struct my_queue *q, void *elem, unsigned *space); 76 | 77 | /** 78 | * Remove an element from the queue. 79 | * 80 | * \param[in] q Queue object. 81 | * \param[out] elem Where the element object will be copied. 82 | * \param[out] count If non-NULL, pointer to store the count of elements 83 | * remaining in the queue. 84 | * \return true if an element was removed from the queue, 85 | * false if the queue is empty. 86 | */ 87 | bool 88 | my_queue_remove(struct my_queue *q, void *elem, unsigned *count); 89 | 90 | struct my_queue_ops { 91 | struct my_queue *(*init)(unsigned, unsigned); 92 | void (*destroy)(struct my_queue **); 93 | const char *(*impl_type)(void); 94 | bool (*insert)(struct my_queue *, void *, unsigned *); 95 | bool (*remove)(struct my_queue *, void *, unsigned *); 96 | }; 97 | 98 | #endif /* MY_QUEUE_H */ 99 | -------------------------------------------------------------------------------- /libmy/my_queue_mb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "my_memory_barrier.h" 18 | 19 | #ifdef MY_HAVE_MEMORY_BARRIERS 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "my_alloc.h" 26 | 27 | #include "my_queue.h" 28 | 29 | #define MY_ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) 30 | 31 | struct my_queue * 32 | my_queue_mb_init(unsigned, unsigned); 33 | 34 | void 35 | my_queue_mb_destroy(struct my_queue **); 36 | 37 | const char * 38 | my_queue_mb_impl_type(void); 39 | 40 | bool 41 | my_queue_mb_insert(struct my_queue *, void *, unsigned *); 42 | 43 | bool 44 | my_queue_mb_remove(struct my_queue *, void *, unsigned *); 45 | 46 | struct my_queue { 47 | uint8_t *data; 48 | unsigned num_elems; 49 | unsigned sizeof_elem; 50 | unsigned head; 51 | unsigned tail; 52 | }; 53 | 54 | struct my_queue * 55 | my_queue_mb_init(unsigned num_elems, unsigned sizeof_elem) 56 | { 57 | struct my_queue *q; 58 | if (num_elems < 2 || ((num_elems - 1) & num_elems) != 0) 59 | return (NULL); 60 | q = my_calloc(1, sizeof(*q)); 61 | q->num_elems = num_elems; 62 | q->sizeof_elem = sizeof_elem; 63 | q->data = my_calloc(q->num_elems, q->sizeof_elem); 64 | return (q); 65 | } 66 | 67 | void 68 | my_queue_mb_destroy(struct my_queue **q) 69 | { 70 | if (*q) { 71 | free((*q)->data); 72 | free(*q); 73 | *q = NULL; 74 | } 75 | } 76 | 77 | const char * 78 | my_queue_mb_impl_type(void) 79 | { 80 | return ("memory barrier"); 81 | } 82 | 83 | static inline unsigned 84 | q_space(unsigned head, unsigned tail, unsigned size) 85 | { 86 | return ((tail - (head + 1)) & (size - 1)); 87 | } 88 | 89 | static inline unsigned 90 | q_count(unsigned head, unsigned tail, unsigned size) 91 | { 92 | return ((head - tail) & (size - 1)); 93 | } 94 | 95 | bool 96 | my_queue_mb_insert(struct my_queue *q, void *item, unsigned *pspace) 97 | { 98 | bool res = false; 99 | unsigned head = q->head; 100 | unsigned tail = MY_ACCESS_ONCE(q->tail); 101 | unsigned space = q_space(head, tail, q->num_elems); 102 | if (space >= 1) { 103 | memcpy(&q->data[head * q->sizeof_elem], item, q->sizeof_elem); 104 | smp_wmb(); 105 | q->head = (head + 1) & (q->num_elems - 1); 106 | smp_wmb(); 107 | res = true; 108 | space--; 109 | } 110 | if (pspace != NULL) 111 | *pspace = space; 112 | return (res); 113 | } 114 | 115 | bool 116 | my_queue_mb_remove(struct my_queue *q, void *item, unsigned *pcount) 117 | { 118 | bool res = false; 119 | unsigned head = MY_ACCESS_ONCE(q->head); 120 | unsigned tail = q->tail; 121 | unsigned count = q_count(head, tail, q->num_elems); 122 | if (count >= 1) { 123 | memcpy(item, &q->data[tail * q->sizeof_elem], q->sizeof_elem); 124 | smp_mb(); 125 | q->tail = (tail + 1) & (q->num_elems - 1); 126 | res = true; 127 | count--; 128 | } 129 | if (pcount != NULL) 130 | *pcount = count; 131 | return (res); 132 | } 133 | 134 | const struct my_queue_ops my_queue_mb_ops = { 135 | .init = 136 | my_queue_mb_init, 137 | .destroy = 138 | my_queue_mb_destroy, 139 | .impl_type = 140 | my_queue_mb_impl_type, 141 | .insert = 142 | my_queue_mb_insert, 143 | .remove = 144 | my_queue_mb_remove, 145 | }; 146 | 147 | #endif /* MY_HAVE_MEMORY_BARRIERS */ 148 | -------------------------------------------------------------------------------- /libmy/my_queue_mutex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "my_alloc.h" 24 | 25 | #include "my_queue.h" 26 | 27 | #if defined(__GNUC__) 28 | # define _aligned __attribute__((aligned(64))) 29 | #else 30 | # define _aligned 31 | #endif 32 | 33 | struct my_queue { 34 | uint8_t *data; 35 | unsigned num_elems; 36 | unsigned sizeof_elem; 37 | unsigned head; 38 | unsigned tail; 39 | pthread_mutex_t lock _aligned; 40 | }; 41 | 42 | struct my_queue * 43 | my_queue_mutex_init(unsigned, unsigned); 44 | 45 | void 46 | my_queue_mutex_destroy(struct my_queue **); 47 | 48 | const char * 49 | my_queue_mutex_impl_type(void); 50 | 51 | bool 52 | my_queue_mutex_insert(struct my_queue *, void *, unsigned *); 53 | 54 | bool 55 | my_queue_mutex_remove(struct my_queue *, void *, unsigned *); 56 | 57 | struct my_queue * 58 | my_queue_mutex_init(unsigned num_elems, unsigned sizeof_elem) 59 | { 60 | struct my_queue *q; 61 | if (num_elems < 2 || ((num_elems - 1) & num_elems) != 0) 62 | return (NULL); 63 | q = my_calloc(1, sizeof(*q)); 64 | q->num_elems = num_elems; 65 | q->sizeof_elem = sizeof_elem; 66 | q->data = my_calloc(q->num_elems, q->sizeof_elem); 67 | int rc = pthread_mutex_init(&q->lock, NULL); 68 | assert(rc == 0); 69 | return (q); 70 | } 71 | 72 | void 73 | my_queue_mutex_destroy(struct my_queue **q) 74 | { 75 | if (*q) { 76 | pthread_mutex_destroy(&(*q)->lock); 77 | free((*q)->data); 78 | free(*q); 79 | *q = NULL; 80 | } 81 | } 82 | 83 | const char * 84 | my_queue_mutex_impl_type(void) 85 | { 86 | return ("pthread mutex"); 87 | } 88 | 89 | static inline void 90 | q_lock(struct my_queue *q) 91 | { 92 | int rc = pthread_mutex_lock(&q->lock); 93 | assert(rc == 0); 94 | } 95 | 96 | static inline void 97 | q_unlock(struct my_queue *q) 98 | { 99 | int rc = pthread_mutex_unlock(&q->lock); 100 | assert(rc == 0); 101 | } 102 | 103 | static inline unsigned 104 | q_space(unsigned head, unsigned tail, unsigned size) 105 | { 106 | return ((tail - (head + 1)) & (size - 1)); 107 | } 108 | 109 | static inline unsigned 110 | q_count(unsigned head, unsigned tail, unsigned size) 111 | { 112 | return ((head - tail) & (size - 1)); 113 | } 114 | 115 | bool 116 | my_queue_mutex_insert(struct my_queue *q, void *item, unsigned *pspace) 117 | { 118 | q_lock(q); 119 | bool res = false; 120 | unsigned head = q->head; 121 | unsigned tail = q->tail; 122 | unsigned space = q_space(head, tail, q->num_elems); 123 | if (space >= 1) { 124 | memcpy(&q->data[head * q->sizeof_elem], item, q->sizeof_elem); 125 | q->head = (head + 1) & (q->num_elems - 1); 126 | res = true; 127 | space--; 128 | } 129 | q_unlock(q); 130 | if (pspace) 131 | *pspace = space; 132 | return (res); 133 | } 134 | 135 | bool 136 | my_queue_mutex_remove(struct my_queue *q, void *item, unsigned *pcount) 137 | { 138 | q_lock(q); 139 | bool res = false; 140 | unsigned head = q->head; 141 | unsigned tail = q->tail; 142 | unsigned count = q_count(head, tail, q->num_elems); 143 | if (count >= 1) { 144 | memcpy(item, &q->data[tail * q->sizeof_elem], q->sizeof_elem); 145 | q->tail = (tail + 1) & (q->num_elems - 1); 146 | res = true; 147 | count--; 148 | } 149 | q_unlock(q); 150 | if (pcount) 151 | *pcount = count; 152 | return (res); 153 | } 154 | 155 | const struct my_queue_ops my_queue_mutex_ops = { 156 | .init = 157 | my_queue_mutex_init, 158 | .destroy = 159 | my_queue_mutex_destroy, 160 | .impl_type = 161 | my_queue_mutex_impl_type, 162 | .insert = 163 | my_queue_mutex_insert, 164 | .remove = 165 | my_queue_mutex_remove, 166 | }; 167 | -------------------------------------------------------------------------------- /libmy/my_rate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, 2009, 2013, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_RATE_H 18 | #define MY_RATE_H 19 | 20 | struct my_rate; 21 | 22 | struct my_rate * 23 | my_rate_init(unsigned rate, unsigned freq); 24 | 25 | void 26 | my_rate_destroy(struct my_rate **); 27 | 28 | void 29 | my_rate_sleep(struct my_rate *); 30 | 31 | #endif /* MY_RATE_H */ 32 | -------------------------------------------------------------------------------- /libmy/my_time.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_TIME_H 2 | #define MY_TIME_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if HAVE_CLOCK_GETTIME 10 | static inline void 11 | my_gettime(clockid_t clk_id, struct timespec *ts) 12 | { 13 | int res; 14 | res = clock_gettime(clk_id, ts); 15 | assert(res == 0); 16 | } 17 | #else 18 | static inline void 19 | my_gettime(int clk_id __attribute__((unused)), struct timespec *ts) 20 | { 21 | struct timeval tv; 22 | int res; 23 | 24 | res = gettimeofday(&tv, NULL); 25 | assert(res == 0); 26 | 27 | ts->tv_sec = tv.tv_sec; 28 | ts->tv_nsec = tv.tv_usec * 1000; 29 | } 30 | #endif 31 | 32 | static inline void 33 | my_timespec_add(const struct timespec *a, struct timespec *b) { 34 | b->tv_sec += a->tv_sec; 35 | b->tv_nsec += a->tv_nsec; 36 | while (b->tv_nsec >= 1000000000) { 37 | b->tv_sec += 1; 38 | b->tv_nsec -= 1000000000; 39 | } 40 | } 41 | 42 | static inline void 43 | my_timespec_sub(const struct timespec *a, struct timespec *b) 44 | { 45 | b->tv_sec -= a->tv_sec; 46 | b->tv_nsec -= a->tv_nsec; 47 | if (b->tv_nsec < 0) { 48 | b->tv_sec -= 1; 49 | b->tv_nsec += 1000000000; 50 | } 51 | } 52 | 53 | static inline double 54 | my_timespec_to_double(const struct timespec *ts) 55 | { 56 | return (ts->tv_sec + ts->tv_nsec / 1E9); 57 | } 58 | 59 | static inline void 60 | my_timespec_from_double(double seconds, struct timespec *ts) { 61 | ts->tv_sec = (time_t) seconds; 62 | ts->tv_nsec = (long) ((seconds - ((int) seconds)) * 1E9); 63 | } 64 | 65 | static inline void 66 | my_nanosleep(const struct timespec *ts) 67 | { 68 | struct timespec rqt, rmt; 69 | 70 | for (rqt = *ts; nanosleep(&rqt, &rmt) < 0 && errno == EINTR; rqt = rmt) 71 | ; 72 | } 73 | 74 | #endif /* MY_TIME_H */ 75 | -------------------------------------------------------------------------------- /libmy/print_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_PRINT_STRING_H 18 | #define MY_PRINT_STRING_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | static inline void 25 | print_string(const void *data, size_t len, FILE *out) 26 | { 27 | uint8_t *str = (uint8_t *) data; 28 | fputc('"', out); 29 | while (len-- != 0) { 30 | unsigned c = *(str++); 31 | if (isprint(c)) { 32 | if (c == '"') 33 | fputs("\\\"", out); 34 | else 35 | fputc(c, out); 36 | } else { 37 | fprintf(out, "\\x%02x", c); 38 | } 39 | } 40 | fputc('"', out); 41 | } 42 | 43 | #endif /* MY_PRINT_STRING_H */ 44 | -------------------------------------------------------------------------------- /libmy/read_bytes.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_READ_BYTES_H 2 | #define MY_READ_BYTES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static inline bool 10 | read_bytes(int fd, uint8_t *buf, size_t bytes_needed) 11 | { 12 | while (bytes_needed > 0) { 13 | ssize_t bytes_read; 14 | 15 | bytes_read = read(fd, buf, bytes_needed); 16 | if (bytes_read == -1 && errno == EINTR) 17 | continue; 18 | else if (bytes_read <= 0) 19 | return false; 20 | bytes_needed -= bytes_read; 21 | buf += bytes_read; 22 | } 23 | return true; 24 | } 25 | 26 | #endif /* MY_READ_BYTES_H */ 27 | -------------------------------------------------------------------------------- /libmy/spooldir.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_SPOOLDIR_H 2 | #define MY_SPOOLDIR_H 3 | 4 | struct spooldir; 5 | 6 | struct spooldir *spooldir_init(const char *path); 7 | void spooldir_destroy(struct spooldir **); 8 | char *spooldir_next(struct spooldir *); 9 | 10 | #endif /* MY_SPOOLDIR_H */ 11 | -------------------------------------------------------------------------------- /libmy/string_replace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_STRING_REPLACE_H 18 | #define MY_STRING_REPLACE_H 19 | 20 | #include 21 | 22 | #include "ubuf.h" 23 | 24 | static inline char * 25 | string_replace(const char *str, const char *old, const char *new) 26 | { 27 | const char *end; 28 | char *ret; 29 | size_t retsz; 30 | 31 | if (strstr(str, old) == NULL) { 32 | char *s = strdup(str); 33 | assert(s != NULL); 34 | return (s); 35 | } 36 | ubuf *u = ubuf_new(); 37 | 38 | end = str + strlen(str) + 1; 39 | while ((ret = strstr(str, old)) != NULL) { 40 | size_t offset = (size_t) (ret - str); 41 | ubuf_append(u, (uint8_t *) str, offset); 42 | ubuf_append(u, (uint8_t *) new, strlen(new)); 43 | str += offset; 44 | if (str + strlen(old) >= end) 45 | break; 46 | str += strlen(old); 47 | } 48 | ubuf_append(u, (uint8_t *) str, strlen(str)); 49 | 50 | ubuf_cterm(u); 51 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 52 | ubuf_destroy(&u); 53 | return (ret); 54 | } 55 | 56 | #endif /* MY_STRING_REPLACE_H */ 57 | -------------------------------------------------------------------------------- /libmy/threadnum.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "threadnum.h" 4 | 5 | static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 6 | static int next_threadnum = 0; 7 | static __thread int threadnum; 8 | 9 | void 10 | my_threadnum_register(void) { 11 | pthread_mutex_lock(&lock); 12 | threadnum = next_threadnum; 13 | next_threadnum += 1; 14 | pthread_mutex_unlock(&lock); 15 | } 16 | 17 | int 18 | my_threadnum(void) { 19 | return (threadnum); 20 | } 21 | -------------------------------------------------------------------------------- /libmy/threadnum.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_THREADNUM_H 2 | #define MY_THREADNUM_H 3 | 4 | void my_threadnum_register(void); 5 | int my_threadnum(void); 6 | 7 | #endif /* MY_THREADNUM_H */ 8 | -------------------------------------------------------------------------------- /libmy/ubuf-pb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_UBUF_PB_H 18 | #define MY_UBUF_PB_H 19 | 20 | #include 21 | 22 | #include "ubuf.h" 23 | 24 | struct ubuf_protobuf_c_buffer { 25 | ProtobufCBuffer base; 26 | ubuf *u; 27 | }; 28 | 29 | static inline void 30 | ubuf_protobuf_c_buffer_append(ProtobufCBuffer *buffer, 31 | size_t len, 32 | const uint8_t *data) 33 | { 34 | ubuf *u = ((struct ubuf_protobuf_c_buffer *) buffer)->u; 35 | ubuf_append(u, data, len); 36 | } 37 | 38 | #define UBUF_PROTOBUF_C_BUFFER_INIT(u) { { ubuf_protobuf_c_buffer_append }, u } 39 | 40 | #endif /* MY_UBUF_PB_H */ 41 | -------------------------------------------------------------------------------- /libmy/ubuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MY_UBUF_H 18 | #define MY_UBUF_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "vector.h" 28 | 29 | VECTOR_GENERATE(ubuf, uint8_t) 30 | 31 | #define ubuf_append_cstr_lit(u, s) ubuf_append(u, (const uint8_t*) s, sizeof(s) - 1) 32 | #define ubuf_append_cstr(u, s, l) ubuf_append(u, (const uint8_t*) s, l) 33 | 34 | static inline ubuf * 35 | ubuf_new(void) 36 | { 37 | return (ubuf_init(64)); 38 | } 39 | 40 | static inline ubuf * 41 | ubuf_dup_cstr(const char *s) 42 | { 43 | size_t len = strlen(s); 44 | ubuf *u = ubuf_init(len + 1); 45 | ubuf_append(u, (const uint8_t *) s, len); 46 | return (u); 47 | } 48 | 49 | static inline void 50 | ubuf_add_cstr(ubuf *u, const char *s) 51 | { 52 | if (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) == '\x00') 53 | ubuf_clip(u, ubuf_size(u) - 1); 54 | ubuf_append(u, (const uint8_t *) s, strlen(s)); 55 | } 56 | 57 | static inline void 58 | ubuf_cterm(ubuf *u) 59 | { 60 | if (ubuf_size(u) == 0 || 61 | (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) != '\x00')) 62 | { 63 | ubuf_append(u, (const uint8_t *) "\x00", 1); 64 | } 65 | } 66 | 67 | static inline char * 68 | ubuf_cstr(ubuf *u) 69 | { 70 | ubuf_cterm(u); 71 | return ((char *) ubuf_data(u)); 72 | } 73 | 74 | static inline void 75 | ubuf_add_fmt(ubuf *u, const char *fmt, ...) 76 | { 77 | va_list args, args_copy; 78 | int status, needed; 79 | 80 | if (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) == '\x00') 81 | ubuf_clip(u, ubuf_size(u) - 1); 82 | 83 | va_start(args, fmt); 84 | 85 | va_copy(args_copy, args); 86 | needed = vsnprintf(NULL, 0, fmt, args_copy); 87 | assert(needed >= 0); 88 | va_end(args_copy); 89 | 90 | ubuf_reserve(u, ubuf_size(u) + needed + 1); 91 | status = vsnprintf((char *) ubuf_ptr(u), needed + 1, fmt, args); 92 | assert(status >= 0); 93 | ubuf_advance(u, needed); 94 | 95 | va_end(args); 96 | } 97 | 98 | static inline void 99 | ubuf_rstrip(ubuf *u, char s) 100 | { 101 | if (ubuf_size(u) > 0 && 102 | ubuf_value(u, ubuf_size(u) - 1) == ((uint8_t) s)) 103 | { 104 | ubuf_clip(u, ubuf_size(u) - 1); 105 | } 106 | } 107 | 108 | #endif /* MY_UBUF_H */ 109 | -------------------------------------------------------------------------------- /libmy/varint.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_VARINT_H 2 | #define MY_VARINT_H 3 | 4 | #include 5 | #include 6 | 7 | unsigned varint_length(uint64_t v); 8 | unsigned varint_length_packed(const uint8_t *buf, size_t len_buf); 9 | size_t varint_encode32(uint8_t *ptr, uint32_t value); 10 | size_t varint_encode64(uint8_t *ptr, uint64_t value); 11 | size_t varint_decode32(const uint8_t *ptr, uint32_t *value); 12 | size_t varint_decode64(const uint8_t *ptr, uint64_t *value); 13 | 14 | #endif /* MY_VARINT_H */ 15 | -------------------------------------------------------------------------------- /libmy/zonefile.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_ZONEFILE_H 2 | #define MY_ZONEFILE_H 3 | 4 | #include 5 | 6 | struct zonefile; 7 | 8 | struct zonefile * 9 | zonefile_init_fname(const char *fname); 10 | 11 | void 12 | zonefile_destroy(struct zonefile **); 13 | 14 | const ldns_rdf * 15 | zonefile_get_domain(struct zonefile *); 16 | 17 | size_t 18 | zonefile_get_count(struct zonefile *); 19 | 20 | uint32_t 21 | zonefile_get_serial(struct zonefile *); 22 | 23 | ldns_status 24 | zonefile_read(struct zonefile *, ldns_rr **); 25 | 26 | #endif /* MY_ZONEFILE_H */ 27 | -------------------------------------------------------------------------------- /m4/.gitignore: -------------------------------------------------------------------------------- 1 | libtool.m4 2 | ltoptions.m4 3 | ltsugar.m4 4 | ltversion.m4 5 | lt~obsolete.m4 6 | -------------------------------------------------------------------------------- /m4/ld-version-script.m4: -------------------------------------------------------------------------------- 1 | ../libmy/m4/ld-version-script.m4 -------------------------------------------------------------------------------- /m4/pkg.m4: -------------------------------------------------------------------------------- 1 | ../libmy/m4/pkg.m4 -------------------------------------------------------------------------------- /t/test-common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "test-common.h" 23 | 24 | #include 25 | 26 | 27 | void 28 | escape(ubuf *u, const uint8_t *a, size_t len) 29 | { 30 | size_t n; 31 | bool last_hex = false; 32 | 33 | ubuf_add_cstr(u, "\""); 34 | for (n = 0; n < len; n++) { 35 | if (a[n] == '"') { 36 | ubuf_add_cstr(u, "\\\""); 37 | last_hex = false; 38 | } else if (a[n] == '\\') { 39 | ubuf_add_cstr(u, "\\\\"); 40 | last_hex = false; 41 | } else if (a[n] >= ' ' && a[n] <= '~') { 42 | if (last_hex && isxdigit(a[n])) { 43 | ubuf_add_cstr(u, "\"\""); 44 | } 45 | ubuf_append(u, a+n, 1); 46 | last_hex = false; 47 | } else { 48 | ubuf_add_fmt(u, "\\x%02x", a[n]); 49 | last_hex = true; 50 | } 51 | } 52 | ubuf_add_cstr(u, "\""); 53 | } 54 | 55 | int 56 | check(size_t ret, const char *s, const char *cname) 57 | { 58 | if (ret == 0) 59 | fprintf(stderr, "%s : PASS: %s\n", cname, s); 60 | else 61 | fprintf(stderr, "%s : FAIL: %s (%zd failures)\n", cname, s, ret); 62 | return (ret); 63 | } 64 | -------------------------------------------------------------------------------- /t/test-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 DomainTools LLC 3 | * Copyright (c) 2018, 2021 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef TEST_COMMON_H 19 | #define TEST_COMMON_H 1 20 | 21 | #include 22 | 23 | #define QUOTE(...) #__VA_ARGS__ 24 | 25 | /* Package a binary data buffer for friendly display */ 26 | void escape(ubuf *u, const uint8_t *a, size_t len); 27 | 28 | int check(size_t ret, const char *s, const char *cname); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /t/test-fast_inet_ntop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * This test code was copied from BIND9 v9_10 and then extended. 4 | * 5 | * Copyright (c) 2023 DomainTools LLC 6 | * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 7 | * 8 | * Permission to use, copy, modify, and/or distribute this software for any 9 | * purpose with or without fee is hereby granted, provided that the above 10 | * copyright notice and this permission notice appear in all copies. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 13 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 14 | * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 15 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 16 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 17 | * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 | * PERFORMANCE OF THIS SOFTWARE. 19 | */ 20 | 21 | #include "test-common.h" 22 | 23 | #include "libmy/fast_inet_ntop.h" 24 | #include "libmy/fast_inet_ntop.c" 25 | 26 | #include 27 | #include 28 | 29 | #define NAME "test-fast_inet_ntop" 30 | 31 | static size_t 32 | test_fast_inet_ntop(void) { 33 | char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; 34 | char rbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; 35 | const char *result; 36 | size_t failures = 0; 37 | size_t i; 38 | unsigned char abuf[16]; 39 | struct { 40 | int family; 41 | const char * address; 42 | } testdata[] = { 43 | { AF_INET, "0.0.0.0" }, 44 | { AF_INET, "0.1.0.0" }, 45 | { AF_INET, "0.0.2.0" }, 46 | { AF_INET, "0.0.0.3" }, 47 | { AF_INET, "1.2.3.4" }, 48 | { AF_INET, "98.51.100.1" }, 49 | { AF_INET, "255.255.255.255" }, 50 | { AF_INET6, "::" }, 51 | { AF_INET6, "::1.2.3.4" }, 52 | { AF_INET6, "::ffff:1.2.3.4" }, 53 | { AF_INET6, "2001:db8::" }, 54 | { AF_INET6, "2001:db8::ffff" }, 55 | { AF_INET6, "fedc:ba98:7654:3210:fedc:ba98:7654:3210" }, 56 | { AF_INET6, "1080::8:800:200c:417a" }, 57 | { AF_INET6, "::13.1.68.3" }, 58 | { AF_INET6, "::ffff:129.144.52.38" }, 59 | { AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" } 60 | }; 61 | 62 | for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++) { 63 | 64 | /* not testing inet_pton() */ 65 | inet_pton(testdata[i].family, testdata[i].address, abuf); 66 | 67 | fast_inet_ntop(testdata[i].family, abuf, buf, sizeof(buf)); 68 | if (strcmp(buf, testdata[i].address) == 0) { 69 | fprintf(stderr, "PASS: fast_inet_ntop: %s = %s\n", buf, testdata[i].address); 70 | } else { 71 | fprintf(stderr, "FAIL: fast_inet_ntop: %s != %s\n", buf, testdata[i].address); 72 | failures++; 73 | } 74 | 75 | /* this is redundant */ 76 | inet_ntop(testdata[i].family, abuf, rbuf, sizeof(rbuf)); 77 | if (strcmp(buf, rbuf) == 0) { 78 | fprintf(stderr, "PASS: fast_inet_ntop %s = inet_ntop %s\n", buf, rbuf); 79 | } else { 80 | fprintf(stderr, "FAIL: fast_inet_ntop %s != inet_ntop %s\n", buf, rbuf); 81 | failures++; 82 | } 83 | } 84 | 85 | /* error result tests */ 86 | 87 | inet_pton(AF_INET, "0.0.0.0", abuf); 88 | 89 | errno = 0; 90 | result = fast_inet_ntop(2147483647, abuf, buf, sizeof(buf)); 91 | if (result == NULL && errno == EAFNOSUPPORT) { 92 | fprintf(stderr, "PASS: fast_inet_ntop unknown address family results in EAFNOSUPPORT\n"); 93 | } else { 94 | fprintf(stderr, "FAIL: fast_inet_ntop unknown address family results in EAFNOSUPPORT\n"); 95 | failures++; 96 | } 97 | 98 | errno = 0; 99 | result = fast_inet_ntop(AF_APPLETALK, abuf, buf, sizeof(buf)); 100 | if (result == NULL && errno == EAFNOSUPPORT) { 101 | fprintf(stderr, "PASS: fast_inet_ntop unsupported address family results in EAFNOSUPPORT\n"); 102 | } else { 103 | fprintf(stderr, "FAIL: fast_inet_ntop unsupported address family results in EAFNOSUPPORT\n"); 104 | failures++; 105 | } 106 | 107 | return(failures); 108 | } 109 | 110 | int main (void) { 111 | int ret = 0; 112 | 113 | ret |= check(test_fast_inet_ntop(), "test_fast_inet_ntop", NAME); 114 | 115 | if (ret) 116 | return (EXIT_FAILURE); 117 | 118 | return (EXIT_SUCCESS); 119 | } 120 | -------------------------------------------------------------------------------- /t/test-str_to_rcode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 DomainTools LLC 3 | * Copyright (c) 2015-2016, 2018 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "test-common.h" 25 | 26 | #include 27 | #include 28 | 29 | #define NAME "test-str_to_rcode" 30 | 31 | static struct u16str { 32 | uint16_t u16; 33 | const char *str; 34 | } rcodes[] = { 35 | { WDNS_R_BADVERS, "BADVERS" }, 36 | { WDNS_R_FORMERR, "FORMERR" }, 37 | { WDNS_R_NOERROR, "NOERROR" }, 38 | { WDNS_R_NOTAUTH, "NOTAUTH" }, 39 | { WDNS_R_NOTIMP, "NOTIMP" }, 40 | { WDNS_R_NOTZONE, "NOTZONE" }, 41 | { WDNS_R_NXDOMAIN, "NXDOMAIN" }, 42 | { WDNS_R_NXRRSET, "NXRRSET" }, 43 | { WDNS_R_REFUSED, "REFUSED" }, 44 | { WDNS_R_SERVFAIL, "SERVFAIL" }, 45 | { WDNS_R_YXDOMAIN, "YXDOMAIN" }, 46 | { WDNS_R_YXRRSET, "YXRRSET" }, 47 | }; 48 | 49 | #define num_rcodes (sizeof(rcodes) / sizeof(struct u16str)) 50 | 51 | static size_t 52 | test_str_to_rcode(void) 53 | { 54 | size_t n; 55 | size_t failures = 0; 56 | 57 | for (n = 0; n < num_rcodes; n++) { 58 | uint16_t rcode; 59 | wdns_res res; 60 | res = wdns_str_to_rcode(rcodes[n].str, &rcode); 61 | if (res != wdns_res_success) { 62 | fprintf (stderr, "FAIL: %s res=%s\n", rcodes[n].str, wdns_res_to_str(res)); 63 | } else if (rcode != rcodes[n].u16) { 64 | fprintf (stderr, "FAIL: %s %d != %d\n", rcodes[n].str, rcode, rcodes[n].u16); 65 | failures++; 66 | } else { 67 | fprintf (stderr, "PASS: %s = %d\n", rcodes[n].str, rcode); 68 | } 69 | } 70 | 71 | return failures; 72 | } 73 | 74 | int main (void) 75 | { 76 | int ret = 0; 77 | 78 | ret |= check(test_str_to_rcode(), "test_str_to_rcode", NAME); 79 | 80 | if (ret) 81 | return (EXIT_FAILURE); 82 | return (EXIT_SUCCESS); 83 | } 84 | -------------------------------------------------------------------------------- /wdns.spec: -------------------------------------------------------------------------------- 1 | Name: wdns 2 | Version: 0.12.0 3 | Release: 1%{?dist} 4 | Summary: low-level DNS library 5 | 6 | License: Apache-2.0 7 | URL: https://github.com/farsightsec/wdns 8 | Source0: https://dl.farsightsecurity.com/dist/%{name}/%{name}-%{version}.tar.gz 9 | 10 | BuildRequires: gcc 11 | #Requires: 12 | 13 | %description 14 | wdns is a low-level DNS library. It contains a fast DNS message parser 15 | and utility functions for manipulating wire-format DNS data. 16 | 17 | This package contains the shared library for libwdns. 18 | 19 | %package devel 20 | Summary: low-level DNS library (development files) 21 | Requires: %{name}%{?_isa} = %{version}-%{release} 22 | 23 | %description devel 24 | wdns is a low-level DNS library. It contains a fast DNS message parser 25 | and utility functions for manipulating wire-format DNS data. 26 | 27 | This package contains the static library and header file for libwdns. 28 | 29 | %prep 30 | %setup -q 31 | 32 | 33 | %build 34 | %set_build_flags 35 | %if %{rhel} == 7 36 | CFLAGS="$CFLAGS -std=c99 -D_GNU_SOURCE" 37 | %endif 38 | [ -x configure ] || autoreconf -fvi 39 | %configure 40 | make %{?_smp_mflags} 41 | 42 | 43 | %install 44 | rm -rf $RPM_BUILD_ROOT 45 | %make_install 46 | 47 | 48 | %files 49 | %defattr(-,root,root,-) 50 | %{_libdir}/*.so.* 51 | %exclude %{_libdir}/libwdns.la 52 | 53 | %files devel 54 | %{_libdir}/*.so 55 | %{_libdir}/*.a 56 | %{_libdir}/pkgconfig/* 57 | %{_includedir}/* 58 | 59 | %doc 60 | 61 | %changelog 62 | -------------------------------------------------------------------------------- /wdns/buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Advance pointer p by sz bytes and update len. 19 | */ 20 | #define WDNS_BUF_ADVANCE(p, len, sz) do { \ 21 | p += sz; \ 22 | len -= sz; \ 23 | } while (0) 24 | 25 | /** 26 | * Read an 8 bit integer. 27 | */ 28 | #define WDNS_BUF_GET8(dst, src) do { \ 29 | memcpy(&dst, src, 1); \ 30 | src++; \ 31 | } while (0) 32 | 33 | /** 34 | * Read a 16 bit integer. 35 | */ 36 | #define WDNS_BUF_GET16(dst, src) do { \ 37 | memcpy(&dst, src, 2); \ 38 | dst = ntohs(dst); \ 39 | src += 2; \ 40 | } while (0) 41 | 42 | /** 43 | * Read a 32 bit integer. 44 | */ 45 | #define WDNS_BUF_GET32(dst, src) do { \ 46 | memcpy(&dst, src, 4); \ 47 | dst = ntohl(dst); \ 48 | src += 4; \ 49 | } while (0) 50 | -------------------------------------------------------------------------------- /wdns/clear.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | wdns_clear_rr(wdns_rr_t *rr) 19 | { 20 | my_free(rr->name.data); 21 | my_free(rr->rdata); 22 | } 23 | 24 | void 25 | wdns_clear_rrset(wdns_rrset_t *rrset) 26 | { 27 | for (unsigned i = 0; i < rrset->n_rdatas; i++) 28 | my_free(rrset->rdatas[i]); 29 | my_free(rrset->name.data); 30 | my_free(rrset->rdatas); 31 | rrset->n_rdatas = 0; 32 | } 33 | 34 | void 35 | wdns_clear_rrset_array(wdns_rrset_array_t *a) 36 | { 37 | for (unsigned i = 0; i < a->n_rrs; i++) 38 | wdns_clear_rr(&a->rrs[i]); 39 | my_free(a->rrs); 40 | a->n_rrs = 0; 41 | 42 | for (unsigned i = 0; i < a->n_rrsets; i++) 43 | wdns_clear_rrset(&a->rrsets[i]); 44 | my_free(a->rrsets); 45 | a->n_rrsets = 0; 46 | } 47 | 48 | void 49 | wdns_clear_message(wdns_message_t *m) 50 | { 51 | my_free(m->edns.options); 52 | m->edns.present = false; 53 | for (unsigned i = 0; i < WDNS_MSG_SEC_MAX; i++) 54 | wdns_clear_rrset_array(&m->sections[i]); 55 | } 56 | -------------------------------------------------------------------------------- /wdns/compare_rr_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Compare an RR to a RRset. An RR and an RRset compare true if the name, type, 19 | * and class match. 20 | * 21 | * This function does a case-insensitive name comparison. 22 | * 23 | * \param[in] rr the RR to compare 24 | * \param[in] rrset the RRset to compare 25 | * 26 | * \return true if the RR could be part of the RRset, false otherwise 27 | */ 28 | 29 | bool 30 | wdns_compare_rr_rrset(const wdns_rr_t *rr, const wdns_rrset_t *rrset) 31 | { 32 | if (rr->name.len == rrset->name.len && 33 | rr->rrtype == rrset->rrtype && 34 | rr->rrclass == rrset->rrclass) 35 | { 36 | wdns_name_t name_rr; 37 | wdns_name_t name_rrset; 38 | 39 | name_rr.len = rr->name.len; 40 | name_rr.data = alloca(name_rr.len); 41 | memcpy(name_rr.data, rr->name.data, name_rr.len); 42 | wdns_downcase_name(&name_rr); 43 | 44 | name_rrset.len = rrset->name.len; 45 | name_rrset.data = alloca(name_rrset.len); 46 | memcpy(name_rrset.data, rrset->name.data, name_rrset.len); 47 | wdns_downcase_name(&name_rrset); 48 | 49 | return (memcmp(name_rr.data, name_rrset.data, name_rr.len) == 0); 50 | } 51 | 52 | return (false); 53 | } 54 | -------------------------------------------------------------------------------- /wdns/copy_uname.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Copy an uncompressed domain name from a message. 19 | * 20 | * The caller must allocate at least #WDNS_MAXLEN_NAME bytes for 21 | * the destination buffer. 22 | * 23 | * \param[in] p pointer to message 24 | * \param[in] eop pointer to end of message 25 | * \param[in] src pointer to domain name 26 | * \param[out] dst caller-allocated buffer for domain name 27 | * \param[out] sz total length of domain name (may be NULL) 28 | * 29 | * \return 30 | */ 31 | 32 | wdns_res 33 | wdns_copy_uname(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 34 | uint8_t *dst, size_t *sz) 35 | { 36 | uint8_t c; 37 | 38 | size_t total_len = 0; 39 | 40 | if (p >= eop || src >= eop || src < p) 41 | return (wdns_res_out_of_bounds); 42 | 43 | while ((c = *src++) != 0) { 44 | if (c <= 63) { 45 | total_len++; 46 | if (total_len >= WDNS_MAXLEN_NAME) 47 | return (wdns_res_name_overflow); 48 | *dst++ = c; 49 | 50 | total_len += c; 51 | if (total_len >= WDNS_MAXLEN_NAME) 52 | return (wdns_res_name_overflow); 53 | if (src + c > eop) 54 | return (wdns_res_out_of_bounds); 55 | memcpy(dst, src, c); 56 | 57 | dst += c; 58 | src += c; 59 | } else { 60 | return (wdns_res_invalid_length_octet); 61 | } 62 | } 63 | *dst = '\0'; 64 | total_len++; 65 | 66 | if (sz) 67 | *sz = total_len; 68 | return (wdns_res_success); 69 | } 70 | -------------------------------------------------------------------------------- /wdns/count_labels.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Count the number of labels in an uncompressed domain name. 19 | * 20 | * \param[in] name 21 | * \param[out] nlabels 22 | * 23 | * \return wdns_res_success 24 | * \return wdns_res_invalid_length_octet 25 | * \return wdns_res_name_overflow 26 | */ 27 | 28 | wdns_res 29 | wdns_count_labels(wdns_name_t *name, size_t *nlabels) 30 | { 31 | uint8_t c, *data; 32 | 33 | *nlabels = 0; 34 | data = name->data; 35 | 36 | while ((c = *data++) != 0) { 37 | if (c <= 63) { 38 | *nlabels += 1; 39 | data += c; 40 | if (data - name->data > name->len) 41 | return (wdns_res_name_overflow); 42 | } else { 43 | return (wdns_res_invalid_length_octet); 44 | } 45 | } 46 | 47 | return (wdns_res_success); 48 | } 49 | -------------------------------------------------------------------------------- /wdns/deserialize_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Parse a serialized wdns_rrset_t. 19 | * 20 | * \param[out] rrset parsed RRset 21 | * \param[in] buf serialized RRset 22 | * \param[in] sz length of buf 23 | */ 24 | 25 | wdns_res 26 | wdns_deserialize_rrset(wdns_rrset_t *rrset, const uint8_t *buf, size_t sz) 27 | { 28 | 29 | #define copy_bytes(ptr, len) do { \ 30 | if (bytes_read + len > sz) { \ 31 | wdns_clear_rrset(rrset); \ 32 | return (wdns_res_overflow); \ 33 | } \ 34 | memcpy(ptr, buf, len); \ 35 | buf += len; \ 36 | bytes_read += len; \ 37 | } while(0) 38 | 39 | size_t bytes_read = 0; 40 | 41 | memset(rrset, 0, sizeof(*rrset)); 42 | 43 | /* length of name */ 44 | copy_bytes(&rrset->name.len, 1); 45 | 46 | /* name */ 47 | rrset->name.data = my_malloc(rrset->name.len); 48 | copy_bytes(rrset->name.data, rrset->name.len); 49 | 50 | /* type */ 51 | copy_bytes(&rrset->rrtype, 2); 52 | 53 | /* class */ 54 | copy_bytes(&rrset->rrclass, 2); 55 | 56 | /* ttl */ 57 | copy_bytes(&rrset->rrttl, 4); 58 | 59 | /* number of rdatas */ 60 | copy_bytes(&rrset->n_rdatas, 2); 61 | 62 | /* rdatas */ 63 | rrset->rdatas = my_calloc(1, sizeof(void *) * rrset->n_rdatas); 64 | for (size_t i = 0; i < rrset->n_rdatas; i++) { 65 | uint16_t rdlen; 66 | 67 | copy_bytes(&rdlen, 2); 68 | rrset->rdatas[i] = my_malloc(sizeof(rrset->rdatas[i]) + rdlen); 69 | rrset->rdatas[i]->len = rdlen; 70 | copy_bytes(&rrset->rdatas[i]->data, rdlen); 71 | } 72 | 73 | return (wdns_res_success); 74 | } 75 | -------------------------------------------------------------------------------- /wdns/domain_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012-2013, 2019 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Convert a domain name to a human-readable string. 19 | * 20 | * \param[in] src domain name in wire format 21 | * \param[in] src_len length of domain name in bytes 22 | * \param[out] dst caller-allocated string buffer of size WDNS_PRESLEN_NAME 23 | * 24 | * \return Number of bytes read from src. 25 | */ 26 | 27 | size_t 28 | wdns_domain_to_str(const uint8_t *src, size_t src_len, char *dst) 29 | { 30 | size_t bytes_read = 0; 31 | size_t bytes_remaining = src_len; 32 | uint8_t oclen; 33 | 34 | assert(src != NULL); 35 | 36 | oclen = *src; 37 | while (bytes_remaining > 0 && oclen != 0) { 38 | src++; 39 | bytes_remaining--; 40 | 41 | bytes_read += oclen + 1 /* length octet */; 42 | 43 | while (oclen-- && bytes_remaining > 0) { 44 | uint8_t c = *src++; 45 | bytes_remaining--; 46 | 47 | if (c == '.' || c == '\\') { 48 | *dst++ = '\\'; 49 | *dst++ = c; 50 | } else if (c >= '!' && c <= '~') { 51 | *dst++ = c; 52 | } else { 53 | snprintf(dst, 5, "\\%.3d", c); 54 | dst += 4; 55 | } 56 | } 57 | *dst++ = '.'; 58 | oclen = *src; 59 | } 60 | if (bytes_read == 0) 61 | *dst++ = '.'; 62 | bytes_read++; 63 | 64 | *dst = '\0'; 65 | return (bytes_read); 66 | } 67 | -------------------------------------------------------------------------------- /wdns/downcase_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Downcase a wdns_name_t. 19 | * 20 | * \param[in] name the name to downcase 21 | */ 22 | 23 | void 24 | wdns_downcase_name(wdns_name_t *name) 25 | { 26 | uint8_t *p = name->data; 27 | uint16_t len = name->len; 28 | 29 | while (len-- != 0) { 30 | if (*p >= 'A' && *p <= 'Z') 31 | *p |= 0x20; 32 | p++; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /wdns/downcase_rdata.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 2014, 2016, 2021 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | wdns_downcase_rdata(wdns_rdata_t *rdata, uint16_t rrtype, uint16_t rrclass) 19 | { 20 | 21 | #define advance_bytes(x) do { \ 22 | if (bytes_remaining < (x)) \ 23 | return (wdns_res_parse_error); \ 24 | p += (x); \ 25 | bytes_remaining -= (x); \ 26 | } while(0) 27 | 28 | const record_descr *descr; 29 | const uint8_t *t; 30 | size_t bytes_remaining = rdata->len; 31 | uint8_t oclen; 32 | uint8_t *p = rdata->data; 33 | 34 | if (rrtype < record_descr_len) { 35 | descr = &record_descr_array[rrtype]; 36 | if (descr->types[0] == rdf_unknown) 37 | return (wdns_res_success); 38 | } else { 39 | return (wdns_res_success); 40 | } 41 | 42 | /* only downcase rrtypes specified by RFC 4034 section 6.2 43 | * and draft-ietf-dnsext-dnssec-bis-updates-11 section 5.1 */ 44 | switch (rrtype) { 45 | case WDNS_TYPE_A6: 46 | case WDNS_TYPE_AFSDB: 47 | case WDNS_TYPE_CNAME: 48 | case WDNS_TYPE_DNAME: 49 | case WDNS_TYPE_KX: 50 | case WDNS_TYPE_MB: 51 | case WDNS_TYPE_MD: 52 | case WDNS_TYPE_MF: 53 | case WDNS_TYPE_MG: 54 | case WDNS_TYPE_MINFO: 55 | case WDNS_TYPE_MR: 56 | case WDNS_TYPE_MX: 57 | case WDNS_TYPE_NAPTR: 58 | case WDNS_TYPE_NS: 59 | case WDNS_TYPE_NXT: 60 | case WDNS_TYPE_PTR: 61 | case WDNS_TYPE_PX: 62 | case WDNS_TYPE_RP: 63 | case WDNS_TYPE_RT: 64 | case WDNS_TYPE_SIG: 65 | case WDNS_TYPE_SOA: 66 | case WDNS_TYPE_SRV: 67 | break; 68 | default: 69 | return (wdns_res_success); 70 | } 71 | 72 | if (descr->record_class == class_un || 73 | descr->record_class == rrclass) 74 | { 75 | for (t = &descr->types[0]; *t != rdf_end; t++) { 76 | if (bytes_remaining == 0) 77 | break; 78 | 79 | switch (*t) { 80 | case rdf_name: 81 | case rdf_uname: 82 | while (bytes_remaining-- != 0) { 83 | if (*p == 0) { 84 | p++; 85 | break; 86 | } 87 | if (*p >= 'A' && *p <= 'Z') 88 | *p |= 0x20; 89 | p++; 90 | } 91 | break; 92 | 93 | case rdf_repstring: 94 | case rdf_bytes: 95 | case rdf_bytes_b64: 96 | case rdf_bytes_str: 97 | case rdf_type_bitmap: 98 | case rdf_svcparams: 99 | return (wdns_res_success); 100 | 101 | case rdf_int8: 102 | advance_bytes(1U); 103 | break; 104 | 105 | case rdf_int16: 106 | case rdf_rrtype: 107 | advance_bytes(2U); 108 | break; 109 | 110 | case rdf_int32: 111 | case rdf_ipv4: 112 | advance_bytes(4U); 113 | break; 114 | 115 | case rdf_ipv6: 116 | advance_bytes(16U); 117 | break; 118 | 119 | case rdf_eui48: 120 | advance_bytes(6U); 121 | break; 122 | 123 | case rdf_eui64: 124 | advance_bytes(8U); 125 | 126 | case rdf_string: 127 | case rdf_salt: 128 | case rdf_hash: 129 | oclen = *p; 130 | advance_bytes(oclen + 1U); 131 | break; 132 | 133 | case rdf_ipv6prefix: 134 | oclen = *p; 135 | if (oclen > 16U) 136 | return (wdns_res_parse_error); 137 | advance_bytes(oclen + 1U); 138 | break; 139 | 140 | default: 141 | fprintf(stderr, "ERROR: unhandled rdf type %u\n", *t); 142 | abort(); 143 | } 144 | 145 | } 146 | if (bytes_remaining != 0) { 147 | return (wdns_res_parse_error); 148 | } 149 | } 150 | 151 | return (wdns_res_success); 152 | } 153 | -------------------------------------------------------------------------------- /wdns/downcase_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | wdns_downcase_rrset(wdns_rrset_t *rrset) 19 | { 20 | wdns_res res; 21 | 22 | wdns_downcase_name(&rrset->name); 23 | for (int i = 0; i < rrset->n_rdatas; i++) { 24 | if (rrset->rdatas[i] != NULL) { 25 | res = wdns_downcase_rdata(rrset->rdatas[i], 26 | rrset->rrtype, rrset->rrclass); 27 | if (res != wdns_res_success) 28 | return (res); 29 | } 30 | } 31 | 32 | return (wdns_res_success); 33 | } 34 | -------------------------------------------------------------------------------- /wdns/file_load_names.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | wdns_file_load_names(const char *fname, wdns_callback_name cb, void *user) 19 | { 20 | FILE *fp; 21 | char line[1280]; 22 | wdns_res res; 23 | wdns_name_t name; 24 | 25 | fp = fopen(fname, "r"); 26 | if (fp == NULL) 27 | return (wdns_res_failure); 28 | 29 | res = wdns_res_success; 30 | memset(line, 0, sizeof(line)); 31 | 32 | while (fgets(line, sizeof(line), fp) != NULL) { 33 | if (line[0] == '\n' || line[0] == ' ' || line[0] == '#') 34 | continue; 35 | if (line[strlen(line) - 1] == '\n') 36 | line[strlen(line) - 1] = '\0'; 37 | res = wdns_str_to_name(line, &name); 38 | if (res != wdns_res_success) 39 | break; 40 | cb(&name, user); 41 | } 42 | 43 | fclose(fp); 44 | return (res); 45 | } 46 | -------------------------------------------------------------------------------- /wdns/gen_rcode_to_str: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2015 by Farsight Security, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import sys 18 | 19 | header_fname = sys.argv[1] 20 | output_fname = sys.argv[2] 21 | 22 | w = open(output_fname, 'w') 23 | 24 | w.write('''/* 25 | * Copyright (c) Farsight Security, Inc. 26 | * 27 | * Licensed under the Apache License, Version 2.0 (the "License"); 28 | * you may not use this file except in compliance with the License. 29 | * You may obtain a copy of the License at 30 | * 31 | * http://www.apache.org/licenses/LICENSE-2.0 32 | * 33 | * Unless required by applicable law or agreed to in writing, software 34 | * distributed under the License is distributed on an "AS IS" BASIS, 35 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | * See the License for the specific language governing permissions and 37 | * limitations under the License. 38 | */ 39 | ''') 40 | 41 | w.write(''' 42 | const char * 43 | wdns_rcode_to_str(uint16_t rcode) 44 | { 45 | switch (rcode) { 46 | ''') 47 | 48 | for line in open(header_fname): 49 | if 'WDNS_R_' in line: 50 | wdns_type = line.split()[1] 51 | rcode = wdns_type.replace('WDNS_R_','',1).replace('_', '-') 52 | w.write('\tcase %s: return ("%s");\n' % (wdns_type, rcode)) 53 | 54 | w.write(''' } 55 | 56 | return (NULL); 57 | } 58 | ''') 59 | 60 | w.write(''' 61 | static struct u16str { 62 | uint16_t u16; 63 | const char *str; 64 | } rcodes[] = { 65 | ''') 66 | 67 | rcodes = [] 68 | for line in open(header_fname): 69 | if 'WDNS_R_' in line: 70 | wdns_type = line.split()[1] 71 | rcode = wdns_type.replace('WDNS_R_','',1).replace('_', '-') 72 | rcodes.append((wdns_type, rcode)) 73 | rcodes.sort() 74 | for wdns_type, rcode in rcodes: 75 | w.write('\t{ %s, "%s" },\n' % (wdns_type, rcode)) 76 | 77 | w.write('''}; 78 | 79 | #define num_rcodes (sizeof(rcodes) / sizeof(struct u16str)) 80 | 81 | static int 82 | cmp_u16str(const void *a, const void *b) { 83 | struct u16str *u1 = (struct u16str *) a; 84 | struct u16str *u2 = (struct u16str *) b; 85 | return (strcasecmp(u1->str, u2->str)); 86 | } 87 | 88 | wdns_res 89 | wdns_str_to_rcode(const char *str, uint16_t *out) { 90 | struct u16str key, *res; 91 | key.str = str; 92 | res = bsearch(&key, rcodes, num_rcodes, sizeof(struct u16str), cmp_u16str); 93 | if (res != NULL) { 94 | *out = res->u16; 95 | return (wdns_res_success); 96 | } 97 | return (wdns_res_failure); 98 | } 99 | ''') 100 | 101 | w.close() 102 | -------------------------------------------------------------------------------- /wdns/gen_rrclass_to_str: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2009, 2012, 2015 by Farsight Security, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import sys 18 | 19 | header_fname = sys.argv[1] 20 | output_fname = sys.argv[2] 21 | 22 | header = ''' 23 | /* 24 | * Copyright (c) Farsight Security, Inc. 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); 27 | * you may not use this file except in compliance with the License. 28 | * You may obtain a copy of the License at 29 | * 30 | * http://www.apache.org/licenses/LICENSE-2.0 31 | * 32 | * Unless required by applicable law or agreed to in writing, software 33 | * distributed under the License is distributed on an "AS IS" BASIS, 34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | * See the License for the specific language governing permissions and 36 | * limitations under the License. 37 | */ 38 | 39 | const char * 40 | wdns_rrclass_to_str(uint16_t rrclass) 41 | { 42 | switch (rrclass) { 43 | ''' 44 | 45 | footer = ''' } 46 | 47 | return (NULL); 48 | } 49 | ''' 50 | 51 | w = open(output_fname, 'w') 52 | 53 | w.write(header) 54 | 55 | for line in open(header_fname): 56 | if 'WDNS_CLASS_' in line: 57 | wdns_class = line.split()[1] 58 | rrclass = wdns_class.replace('WDNS_CLASS_','',1).replace('_', '-') 59 | w.write('\tcase %s: return ("%s");\n' % (wdns_class, rrclass)) 60 | 61 | w.write(footer) 62 | 63 | w.write(''' 64 | static struct u16str { 65 | uint16_t u16; 66 | const char *str; 67 | } rrclasses[] = { 68 | ''') 69 | 70 | rrclasses = [] 71 | for line in open(header_fname): 72 | if 'WDNS_CLASS_' in line: 73 | wdns_class = line.split()[1] 74 | rrclass = wdns_class.replace('WDNS_CLASS_','',1).replace('_', '-') 75 | rrclasses.append((wdns_class, rrclass)) 76 | rrclasses.sort() 77 | for wdns_class, rrclass in rrclasses: 78 | w.write('\t{ %s, "%s" },\n' % (wdns_class, rrclass)) 79 | 80 | w.write('''}; 81 | 82 | #define num_rrclasses (sizeof(rrclasses) / sizeof(struct u16str)) 83 | 84 | static int 85 | cmp_u16str(const void *a, const void *b) { 86 | struct u16str *u1 = (struct u16str *) a; 87 | struct u16str *u2 = (struct u16str *) b; 88 | return (strcasecmp(u1->str, u2->str)); 89 | } 90 | 91 | static bool 92 | convert_generic_rrclass(const char *s, long int *val) { 93 | char *endptr = NULL; 94 | 95 | if (strlen(s) <= 5) 96 | return (false); 97 | if (strncasecmp(s, "CLASS", 5) != 0) 98 | return (false); 99 | 100 | s += 5; /* skip leading "CLASS" */ 101 | 102 | *val = strtol(s, &endptr, 10); 103 | if (endptr != NULL && *endptr != '\\0') 104 | return (false); 105 | if (*val < 0 || *val > 65535) 106 | return (false); 107 | 108 | return (true); 109 | } 110 | 111 | uint16_t 112 | wdns_str_to_rrclass(const char *str) { 113 | struct u16str key, *res; 114 | key.str = str; 115 | res = bsearch(&key, rrclasses, num_rrclasses, sizeof(struct u16str), cmp_u16str); 116 | if (res != NULL) { 117 | return (res->u16); 118 | } else { 119 | long int val = 0; 120 | if (convert_generic_rrclass(str, &val)) 121 | return (val); 122 | } 123 | return (0); 124 | } 125 | ''') 126 | 127 | w.close() 128 | -------------------------------------------------------------------------------- /wdns/gen_rrtype_to_str: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2009, 2011, 2012, 2015 by Farsight Security, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | import sys 19 | 20 | header_fname = sys.argv[1] 21 | output_fname = sys.argv[2] 22 | 23 | w = open(output_fname, 'w') 24 | 25 | w.write('''/* 26 | * Copyright (c) Farsight Security, Inc. 27 | * 28 | * Licensed under the Apache License, Version 2.0 (the "License"); 29 | * you may not use this file except in compliance with the License. 30 | * You may obtain a copy of the License at 31 | * 32 | * http://www.apache.org/licenses/LICENSE-2.0 33 | * 34 | * Unless required by applicable law or agreed to in writing, software 35 | * distributed under the License is distributed on an "AS IS" BASIS, 36 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 37 | * See the License for the specific language governing permissions and 38 | * limitations under the License. 39 | */ 40 | ''') 41 | 42 | w.write(''' 43 | const char * 44 | wdns_rrtype_to_str(uint16_t rrtype) 45 | { 46 | switch (rrtype) { 47 | ''') 48 | 49 | for line in open(header_fname): 50 | if 'WDNS_TYPE_' in line: 51 | wdns_type = line.split()[1] 52 | rrtype = wdns_type.replace('WDNS_TYPE_','',1).replace('_', '-') 53 | w.write('\tcase %s: return ("%s");\n' % (wdns_type, rrtype)) 54 | 55 | w.write(''' } 56 | 57 | return (NULL); 58 | } 59 | ''') 60 | 61 | w.write(''' 62 | static struct u16str { 63 | uint16_t u16; 64 | const char *str; 65 | } rrtypes[] = { 66 | ''') 67 | 68 | rrtypes = [] 69 | for line in open(header_fname): 70 | if 'WDNS_TYPE_' in line: 71 | wdns_type = line.split()[1] 72 | rrtype = wdns_type.replace('WDNS_TYPE_','',1).replace('_', '-') 73 | rrtypes.append((wdns_type, rrtype)) 74 | rrtypes.sort() 75 | for wdns_type, rrtype in rrtypes: 76 | w.write('\t{ %s, "%s" },\n' % (wdns_type, rrtype)) 77 | 78 | w.write('''}; 79 | 80 | #define num_rrtypes (sizeof(rrtypes) / sizeof(struct u16str)) 81 | 82 | static int 83 | cmp_u16str(const void *a, const void *b) { 84 | struct u16str *u1 = (struct u16str *) a; 85 | struct u16str *u2 = (struct u16str *) b; 86 | return (strcasecmp(u1->str, u2->str)); 87 | } 88 | 89 | static bool 90 | convert_generic_rrtype(const char *s, long int *val) { 91 | char *endptr = NULL; 92 | 93 | if (strlen(s) <= 4) 94 | return (false); 95 | if (strncasecmp(s, "TYPE", 4) != 0) 96 | return (false); 97 | 98 | s += 4; /* skip leading "TYPE" */ 99 | 100 | *val = strtol(s, &endptr, 10); 101 | if (endptr != NULL && *endptr != '\\0') 102 | return (false); 103 | if (*val < 0 || *val > 65535) 104 | return (false); 105 | 106 | return (true); 107 | } 108 | 109 | uint16_t 110 | wdns_str_to_rrtype(const char *str) { 111 | struct u16str key, *res; 112 | key.str = str; 113 | res = bsearch(&key, rrtypes, num_rrtypes, sizeof(struct u16str), cmp_u16str); 114 | if (res != NULL) { 115 | return (res->u16); 116 | } else { 117 | long int val = 0; 118 | if (convert_generic_rrtype(str, &val)) 119 | return (val); 120 | } 121 | return (0); 122 | } 123 | ''') 124 | 125 | w.close() 126 | -------------------------------------------------------------------------------- /wdns/insert_rr_rrset_array.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Insert an RR into an RRset array. 19 | * 20 | * This function is destructive. No copying is performed; instead the RR's name 21 | * and/or rdata fields are detached from the RR and given to an RRset in the 22 | * RRset array. wdns_clear_rr() is called on the RR object. 23 | * 24 | * \return wdns_res_success 25 | * \return wdns_res_malloc 26 | */ 27 | 28 | wdns_res 29 | _wdns_insert_rr_rrset_array(wdns_rrset_array_t *a, wdns_rr_t *rr, unsigned sec) 30 | { 31 | bool found_rrset = false; 32 | wdns_rdata_t *rdata; 33 | wdns_rr_t *new_rr; 34 | wdns_rrset_t *rrset; 35 | 36 | /* add to RR array */ 37 | a->n_rrs += 1; 38 | a->rrs = my_realloc(a->rrs, a->n_rrs * sizeof(wdns_rr_t)); 39 | new_rr = &a->rrs[a->n_rrs - 1]; 40 | new_rr->rrttl = rr->rrttl; 41 | new_rr->rrtype = rr->rrtype; 42 | new_rr->rrclass = rr->rrclass; 43 | new_rr->name.len = rr->name.len; 44 | 45 | /* copy the owner name */ 46 | new_rr->name.data = my_malloc(rr->name.len); 47 | memcpy(new_rr->name.data, rr->name.data, rr->name.len); 48 | 49 | /* copy the rdata */ 50 | if (sec != WDNS_MSG_SEC_QUESTION) { 51 | new_rr->rdata = my_malloc(sizeof(wdns_rdata_t) + rr->rdata->len); 52 | new_rr->rdata->len = rr->rdata->len; 53 | memcpy(new_rr->rdata->data, rr->rdata->data, rr->rdata->len); 54 | } else { 55 | new_rr->rdata = NULL; 56 | } 57 | 58 | /* iterate over RRset array backwards */ 59 | for (unsigned i = a->n_rrsets; i > 0; i--) { 60 | if (sec == WDNS_MSG_SEC_QUESTION) 61 | break; 62 | 63 | rrset = &a->rrsets[i - 1]; 64 | 65 | if (wdns_compare_rr_rrset(rr, rrset)) { 66 | /* this RR is part of the RRset */ 67 | rrset->n_rdatas += 1; 68 | rrset->rdatas = my_realloc(rrset->rdatas, 69 | rrset->n_rdatas * sizeof(*(rrset->rdatas))); 70 | 71 | /* detach the rdata from the RR and give it to the RRset */ 72 | rdata = rr->rdata; 73 | rr->rdata = NULL; 74 | rrset->rdatas[rrset->n_rdatas - 1] = rdata; 75 | 76 | /* use the lowest TTL out of the RRs for the RRset itself */ 77 | if (rr->rrttl < rrset->rrttl) 78 | rrset->rrttl = rr->rrttl; 79 | 80 | found_rrset = true; 81 | break; 82 | } 83 | } 84 | 85 | if (found_rrset == false) { 86 | /* create a new RRset */ 87 | a->n_rrsets += 1; 88 | a->rrsets = my_realloc(a->rrsets, a->n_rrsets * sizeof(wdns_rrset_t)); 89 | rrset = &a->rrsets[a->n_rrsets - 1]; 90 | memset(rrset, 0, sizeof(*rrset)); 91 | 92 | /* copy fields from the RR */ 93 | rrset->rrttl = rr->rrttl; 94 | rrset->rrtype = rr->rrtype; 95 | rrset->rrclass = rr->rrclass; 96 | 97 | /* add rdata */ 98 | if (sec != WDNS_MSG_SEC_QUESTION) { 99 | rrset->n_rdatas = 1; 100 | rrset->rdatas = my_malloc(sizeof(*(rrset->rdatas))); 101 | } 102 | 103 | /* detach the owner name from the RR and give it to the RRset */ 104 | rrset->name.len = rr->name.len; 105 | rrset->name.data = rr->name.data; 106 | rr->name.len = 0; 107 | rr->name.data = NULL; 108 | 109 | /* detach the rdata from the RR and give it to the RRset */ 110 | if (sec != WDNS_MSG_SEC_QUESTION) { 111 | rdata = rr->rdata; 112 | rr->rdata = NULL; 113 | rrset->rdatas[0] = rdata; 114 | } 115 | } 116 | 117 | wdns_clear_rr(rr); 118 | return (wdns_res_success); 119 | } 120 | -------------------------------------------------------------------------------- /wdns/is_subdomain.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014, 2019 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | static wdns_res 18 | gen_label_offsets(wdns_name_t *name, size_t n_labels, uint8_t *offsets) 19 | { 20 | size_t n = 0; 21 | uint8_t c, *data; 22 | 23 | data = name->data; 24 | 25 | while ((c = *data) != 0) { 26 | if (c <= 63) { 27 | offsets[n++] = data - name->data; 28 | if (n == n_labels) 29 | return (wdns_res_success); 30 | data += c; 31 | if (data - name->data > name->len) 32 | return (wdns_res_name_overflow); 33 | } else { 34 | return (wdns_res_invalid_length_octet); 35 | } 36 | data++; 37 | } 38 | return (wdns_res_success); 39 | } 40 | 41 | static bool 42 | compare_label(uint8_t *l0, uint8_t *l1) 43 | { 44 | uint8_t len0, len1; 45 | len0 = *l0++; 46 | len1 = *l1++; 47 | if (len0 == len1) 48 | return (memcmp(l0, l1, len0) == 0); 49 | return (false); 50 | } 51 | 52 | /** 53 | * Determine if a name is a subdomain of another domain. 54 | * 55 | * A domain is not a subdomain of itself. 56 | * 57 | * \param[in] n0 58 | * \param[in] n1 59 | * \param[out] is_subdomain 60 | * 61 | * \return wdns_res_success 62 | * \return wdns_res_parse_error 63 | */ 64 | 65 | wdns_res 66 | wdns_is_subdomain(wdns_name_t *n0, wdns_name_t *n1, bool *is_subdomain) 67 | { 68 | wdns_res res; 69 | size_t n0_nlabels, n1_nlabels; 70 | ssize_t n0_idx, n1_idx; 71 | 72 | *is_subdomain = false; 73 | 74 | /* count the number of labels in each name */ 75 | res = wdns_count_labels(n0, &n0_nlabels); 76 | if (res != wdns_res_success) 77 | return (wdns_res_parse_error); 78 | 79 | res = wdns_count_labels(n1, &n1_nlabels); 80 | if (res != wdns_res_success) 81 | return (wdns_res_parse_error); 82 | 83 | /* exclude any cases that can be determined solely by label counts */ 84 | if (n0_nlabels <= n1_nlabels) { 85 | /* a subdomain must have more labels than any of its parents */ 86 | return (wdns_res_success); 87 | } 88 | if (n0_nlabels == 0) { 89 | /* the root cannot be a subdomain of any other domain */ 90 | return (wdns_res_success); 91 | } 92 | if (n1_nlabels == 0) { 93 | /* all other domains are subdomains of the root */ 94 | *is_subdomain = true; 95 | return (wdns_res_success); 96 | } 97 | 98 | /* for each name, create an array of label offsets */ 99 | uint8_t n0_offsets[n0_nlabels]; 100 | uint8_t n1_offsets[n1_nlabels]; 101 | memset(n0_offsets, 0, sizeof(n0_offsets)); 102 | memset(n1_offsets, 0, sizeof(n1_offsets)); 103 | 104 | res = gen_label_offsets(n0, n0_nlabels, n0_offsets); 105 | if (res != wdns_res_success) 106 | return (wdns_res_parse_error); 107 | 108 | res = gen_label_offsets(n1, n1_nlabels, n1_offsets); 109 | if (res != wdns_res_success) 110 | return (wdns_res_parse_error); 111 | 112 | /* compare each label, right-to-left */ 113 | n0_idx = n0_nlabels - 1; 114 | n1_idx = n1_nlabels - 1; 115 | do { 116 | if (!compare_label(n0->data + n0_offsets[n0_idx], 117 | n1->data + n1_offsets[n1_idx])) 118 | { 119 | return (wdns_res_success); 120 | } 121 | n0_idx--; 122 | n1_idx--; 123 | } while (n1_idx >= 0); 124 | 125 | /* all labels of the potential parent domain have compared true, 126 | * thus n1 is a suffix of n0 */ 127 | *is_subdomain = true; 128 | return (wdns_res_success); 129 | } 130 | -------------------------------------------------------------------------------- /wdns/left_chop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | wdns_left_chop(wdns_name_t *name, wdns_name_t *chop) 19 | { 20 | uint8_t oclen; 21 | 22 | oclen = name->data[0]; 23 | 24 | if (oclen == 0 && name->len == 1) { 25 | chop->len = 1; 26 | chop->data = name->data; 27 | return (wdns_res_success); 28 | } 29 | 30 | if (oclen > name->len - 1) 31 | return (wdns_res_name_overflow); 32 | 33 | chop->len = name->len - oclen - 1; 34 | chop->data = name->data + oclen + 1; 35 | return (wdns_res_success); 36 | } 37 | -------------------------------------------------------------------------------- /wdns/len_uname.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Determine the length of an uncompressed wire format domain name. 19 | * 20 | * \param[in] p pointer to uncompressed domain name 21 | * \param[in] eop pointer to end of buffer containing name 22 | * \param[out] sz length of name 23 | * 24 | * \return wdns_res_success 25 | * \return wdns_res_name_len 26 | * \return wdns_res_overflow 27 | * \return wdns_res_invalid_length_octet 28 | */ 29 | 30 | wdns_res 31 | wdns_len_uname(const uint8_t *p, const uint8_t *eop, size_t *sz) 32 | { 33 | uint32_t olen = eop - p; 34 | uint32_t len = olen; 35 | 36 | if (p >= eop) 37 | return (wdns_res_overflow); 38 | 39 | while (len-- != 0) { 40 | uint8_t oclen; 41 | WDNS_BUF_GET8(oclen, p); 42 | 43 | if (oclen > 63 || oclen > len) 44 | return (wdns_res_invalid_length_octet); 45 | if (oclen == 0) 46 | break; 47 | 48 | WDNS_BUF_ADVANCE(p, len, oclen); 49 | } 50 | 51 | *sz = olen - len; 52 | if (*sz > WDNS_MAXLEN_NAME) 53 | return (wdns_res_name_len); 54 | return (wdns_res_success); 55 | } 56 | -------------------------------------------------------------------------------- /wdns/libwdns.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libwdns 7 | Description: low-level DNS library 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lwdns 10 | Libs.private: 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /wdns/libwdns.sym: -------------------------------------------------------------------------------- 1 | LIBWDNS_0.6.0 { 2 | global: 3 | wdns_clear_message; 4 | wdns_clear_rr; 5 | wdns_clear_rrset; 6 | wdns_clear_rrset_array; 7 | wdns_compare_rr_rrset; 8 | wdns_copy_uname; 9 | wdns_count_labels; 10 | wdns_deserialize_rrset; 11 | wdns_domain_to_str; 12 | wdns_downcase_name; 13 | wdns_downcase_rdata; 14 | wdns_downcase_rrset; 15 | wdns_file_load_names; 16 | wdns_is_subdomain; 17 | wdns_left_chop; 18 | wdns_len_uname; 19 | wdns_message_to_str; 20 | wdns_opcode_to_str; 21 | wdns_parse_message; 22 | wdns_print_message; 23 | wdns_print_rr; 24 | wdns_print_rrset; 25 | wdns_print_rrset_array; 26 | wdns_rcode_to_str; 27 | wdns_rdata_to_str; 28 | wdns_res_to_str; 29 | wdns_reverse_name; 30 | wdns_rr_to_str; 31 | wdns_rrclass_to_str; 32 | wdns_rrset_array_to_str; 33 | wdns_rrset_to_str; 34 | wdns_rrtype_to_str; 35 | wdns_serialize_rrset; 36 | wdns_skip_name; 37 | wdns_sort_rrset; 38 | wdns_str_to_name; 39 | wdns_str_to_rrtype; 40 | wdns_unpack_name; 41 | local: 42 | *; 43 | }; 44 | 45 | LIBWDNS_0.7.0 { 46 | global: 47 | wdns_str_to_rrclass; 48 | wdns_str_to_rdata; 49 | } LIBWDNS_0.6.0; 50 | 51 | LIBWDNS_0.8.0 { 52 | global: 53 | wdns_str_to_rcode; 54 | wdns_str_to_name_case; 55 | } LIBWDNS_0.7.0; 56 | 57 | LIBWDNS_0.10.0 { 58 | global: 59 | wdns_get_version; 60 | wdns_get_version_number; 61 | } LIBWDNS_0.8.0; 62 | -------------------------------------------------------------------------------- /wdns/message_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * Copyright (c) 2010, 2012, 2019 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | char * 19 | wdns_message_to_str(wdns_message_t *m) 20 | { 21 | const char *opcode; 22 | const char *rcode; 23 | char *ret; 24 | size_t retsz; 25 | ubuf *u; 26 | 27 | u = ubuf_new(); 28 | 29 | ubuf_append_cstr_lit(u, ";; ->>HEADER<<- "); 30 | 31 | opcode = wdns_opcode_to_str(WDNS_FLAGS_OPCODE(*m)); 32 | if (opcode != NULL) 33 | ubuf_add_fmt(u, "opcode: %s", opcode); 34 | else 35 | ubuf_add_fmt(u, "opcode: %hu", WDNS_FLAGS_OPCODE(*m)); 36 | 37 | rcode = wdns_rcode_to_str(WDNS_FLAGS_RCODE(*m)); 38 | if (rcode != NULL) 39 | ubuf_add_fmt(u, ", rcode: %s", rcode); 40 | else 41 | ubuf_add_fmt(u, ", rcode: %hu", WDNS_FLAGS_RCODE(*m)); 42 | 43 | ubuf_add_fmt(u, 44 | ", id: %hu\n" 45 | ";; flags:%s%s%s%s%s%s%s; " 46 | "QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n", 47 | m->id, 48 | WDNS_FLAGS_QR(*m) ? " qr" : "", 49 | WDNS_FLAGS_AA(*m) ? " aa" : "", 50 | WDNS_FLAGS_TC(*m) ? " tc" : "", 51 | WDNS_FLAGS_RD(*m) ? " rd" : "", 52 | WDNS_FLAGS_RA(*m) ? " ra" : "", 53 | WDNS_FLAGS_AD(*m) ? " ad" : "", 54 | WDNS_FLAGS_CD(*m) ? " cd" : "", 55 | m->sections[0].n_rrs, 56 | m->sections[1].n_rrs, 57 | m->sections[2].n_rrs, 58 | m->sections[3].n_rrs 59 | ); 60 | 61 | if (m->edns.present) { 62 | char *edns_flags = m->edns.flags & 0x8000 ? " do" : ""; 63 | ubuf_append_cstr_lit(u, "\n;; OPT PSEUDOSECTION:"); 64 | /* 65 | * RFC 6891 Section 6.1.4 and RFC 3225. Display "do" flag 66 | * if the "DNSSEC OK" (D0) bit is set. 67 | */ 68 | ubuf_add_fmt(u, "\n; EDNS: version: %u, flags:%s; udp: %u", m->edns.version, 69 | edns_flags, m->edns.size); 70 | if (m->edns.options != NULL) { 71 | ubuf *ueopts; 72 | char *eopts, *ptr, *opt; 73 | 74 | ueopts = ubuf_new(); 75 | _wdns_rdata_to_ubuf(ueopts, m->edns.options->data, 76 | m->edns.options->len, WDNS_TYPE_OPT, class_un); 77 | eopts = ubuf_cstr(ueopts); 78 | opt = strtok_r(eopts, "\n", &ptr); 79 | while (opt != NULL) { 80 | ubuf_append_cstr_lit(u, "\n; "); 81 | ubuf_append_cstr(u, opt, strlen(opt)); 82 | opt = strtok_r(NULL, "\n", &ptr); 83 | } 84 | ubuf_destroy(&ueopts); 85 | } 86 | } 87 | ubuf_append_cstr_lit(u, "\n;; QUESTION SECTION:\n"); 88 | _wdns_rrset_array_to_ubuf(u, &m->sections[WDNS_MSG_SEC_QUESTION], WDNS_MSG_SEC_QUESTION); 89 | ubuf_append_cstr_lit(u, "\n;; ANSWER SECTION:\n"); 90 | _wdns_rrset_array_to_ubuf(u, &m->sections[WDNS_MSG_SEC_ANSWER], WDNS_MSG_SEC_ANSWER); 91 | 92 | ubuf_append_cstr_lit(u, "\n;; AUTHORITY SECTION:\n"); 93 | _wdns_rrset_array_to_ubuf(u, &m->sections[WDNS_MSG_SEC_AUTHORITY], WDNS_MSG_SEC_AUTHORITY); 94 | 95 | ubuf_append_cstr_lit(u, "\n;; ADDITIONAL SECTION:\n"); 96 | _wdns_rrset_array_to_ubuf(u, &m->sections[WDNS_MSG_SEC_ADDITIONAL], WDNS_MSG_SEC_ADDITIONAL); 97 | 98 | ubuf_cterm(u); 99 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 100 | ubuf_destroy(&u); 101 | return (ret); 102 | } 103 | -------------------------------------------------------------------------------- /wdns/opcode_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const char * 18 | wdns_opcode_to_str(uint16_t opcode) 19 | { 20 | switch (opcode) { 21 | case WDNS_OP_QUERY: return ("QUERY"); 22 | case WDNS_OP_IQUERY: return ("IQUERY"); 23 | case WDNS_OP_STATUS: return ("STATUS"); 24 | case WDNS_OP_NOTIFY: return ("NOTIFY"); 25 | case WDNS_OP_UPDATE: return ("UPDATE"); 26 | } 27 | 28 | return (NULL); 29 | } 30 | -------------------------------------------------------------------------------- /wdns/parse_edns.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | _wdns_parse_edns(wdns_message_t *m, wdns_rr_t *rr) 19 | { 20 | m->edns.present = true; 21 | m->edns.size = rr->rrclass; 22 | m->edns.version = (rr->rrttl >> 16) & 0xFF; 23 | m->edns.flags = rr->rrttl & 0xFFFF; 24 | m->edns.options = rr->rdata; 25 | rr->rdata = NULL; 26 | 27 | m->rcode |= (rr->rrttl >> 16) & 0xFF00; 28 | 29 | wdns_clear_rr(rr); 30 | 31 | return (wdns_res_success); 32 | } 33 | -------------------------------------------------------------------------------- /wdns/parse_header.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | _wdns_parse_header(const uint8_t *p, size_t len, uint16_t *id, uint16_t *flags, 19 | uint16_t *qdcount, uint16_t *ancount, uint16_t *nscount, uint16_t *arcount) 20 | { 21 | if (len < WDNS_LEN_HEADER) 22 | return (wdns_res_len); 23 | 24 | load_net16(p, id); 25 | load_net16(p + 2, flags); 26 | load_net16(p + 4, qdcount); 27 | load_net16(p + 6, ancount); 28 | load_net16(p + 8, nscount); 29 | load_net16(p + 10, arcount); 30 | 31 | return (wdns_res_success); 32 | } 33 | -------------------------------------------------------------------------------- /wdns/parse_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * Copyright (c) 2009-2012, 2014 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | wdns_res 19 | wdns_parse_message(wdns_message_t *m, const uint8_t *pkt, size_t len) 20 | { 21 | const uint8_t *p = pkt; 22 | const uint8_t *pkt_end = pkt + len; 23 | size_t rrlen; 24 | uint16_t sec_counts[WDNS_MSG_SEC_MAX]; 25 | wdns_rr_t rr; 26 | wdns_res res; 27 | 28 | memset(m, 0, sizeof(*m)); 29 | 30 | if (len < WDNS_LEN_HEADER) 31 | return (wdns_res_len); 32 | 33 | WDNS_BUF_GET16(m->id, p); 34 | WDNS_BUF_GET16(m->flags, p); 35 | WDNS_BUF_GET16(sec_counts[WDNS_MSG_SEC_QUESTION], p); 36 | WDNS_BUF_GET16(sec_counts[WDNS_MSG_SEC_ANSWER], p); 37 | WDNS_BUF_GET16(sec_counts[WDNS_MSG_SEC_AUTHORITY], p); 38 | WDNS_BUF_GET16(sec_counts[WDNS_MSG_SEC_ADDITIONAL], p); 39 | 40 | m->rcode = m->flags & 0xf; 41 | 42 | for (unsigned sec = 0; sec < WDNS_MSG_SEC_MAX; sec++) { 43 | for (unsigned n = 0; n < sec_counts[sec]; n++) { 44 | if (p == pkt_end) 45 | return (wdns_res_success); 46 | 47 | res = _wdns_parse_message_rr(sec, pkt, pkt_end, p, &rrlen, &rr); 48 | if (res != wdns_res_success) { 49 | wdns_clear_message(m); 50 | return (res); 51 | } 52 | 53 | /* 54 | * An uncommon occurrence is the presence of multiple 55 | * OPT records. In this case, we apply the first one to 56 | * the DNS header and treat all subsequent ones as 57 | * ordinary resource records. 58 | */ 59 | if (rr.rrtype == WDNS_TYPE_OPT && !m->edns.present) { 60 | res = _wdns_parse_edns(m, &rr); 61 | if (res != wdns_res_success) 62 | goto err; 63 | } else { 64 | res = _wdns_insert_rr_rrset_array(&m->sections[sec], &rr, sec); 65 | if (res != wdns_res_success) 66 | goto err; 67 | } 68 | 69 | p += rrlen; 70 | } 71 | } 72 | 73 | return (wdns_res_success); 74 | err: 75 | wdns_clear_rr(&rr); 76 | wdns_clear_message(m); 77 | return (res); 78 | } 79 | -------------------------------------------------------------------------------- /wdns/parse_message_rr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Parse a DNS resource record contained in a DNS message. 19 | * 20 | * \param[in] sec section the RR is contained in 21 | * \param[in] p the DNS message that contains the resource record 22 | * \param[in] eop pointer to end of buffer containing message 23 | * \param[in] data pointer to start of resource record 24 | * \param[out] rrsz number of wire bytes read from message 25 | * \param[out] rr parsed resource record 26 | */ 27 | 28 | wdns_res 29 | _wdns_parse_message_rr(unsigned sec, const uint8_t *p, const uint8_t *eop, const uint8_t *data, 30 | size_t *rrsz, wdns_rr_t *rr) 31 | { 32 | const uint8_t *src = data; 33 | size_t len; 34 | uint16_t rdlen; 35 | uint8_t domain_name[WDNS_MAXLEN_NAME]; 36 | wdns_res res; 37 | 38 | /* uncompress name */ 39 | res = wdns_unpack_name(p, eop, src, domain_name, &len); 40 | if (res != wdns_res_success) 41 | return (res); 42 | 43 | /* copy name */ 44 | rr->name.len = len; 45 | rr->name.data = my_malloc(len); 46 | memcpy(rr->name.data, domain_name, len); 47 | 48 | /* skip name */ 49 | wdns_skip_name(&src, eop); 50 | 51 | /* if this is a question RR, then we need 4 more bytes, rrtype (2) + rrclass (2). */ 52 | /* if this is a response RR, then we need 10 more bytes, rrtype (2) + rrclass (2) + 53 | * rrttl (4) + rdlen (2). */ 54 | if (src + 4 > eop || (sec != WDNS_MSG_SEC_QUESTION && src + 10 > eop)) { 55 | res = wdns_res_parse_error; 56 | goto err; 57 | } 58 | 59 | /* rrtype */ 60 | WDNS_BUF_GET16(rr->rrtype, src); 61 | 62 | /* rrclass */ 63 | WDNS_BUF_GET16(rr->rrclass, src); 64 | 65 | /* finished parsing if this is a question RR */ 66 | if (sec == WDNS_MSG_SEC_QUESTION) { 67 | rr->rrttl = 0; 68 | rr->rdata = NULL; 69 | *rrsz = (src - data); 70 | return (wdns_res_success); 71 | } 72 | 73 | /* rrttl */ 74 | WDNS_BUF_GET32(rr->rrttl, src); 75 | 76 | /* rdlen */ 77 | WDNS_BUF_GET16(rdlen, src); 78 | 79 | /* rdlen overflow check */ 80 | if (src + rdlen > eop) { 81 | res = wdns_res_overflow; 82 | goto err; 83 | } 84 | 85 | /* parse and copy the rdata */ 86 | res = _wdns_parse_rdata(rr, p, eop, src, rdlen); 87 | if (res != wdns_res_success) 88 | goto err; 89 | 90 | /* calculate the number of wire bytes that were read from the message */ 91 | *rrsz = (src - data) + rdlen; 92 | 93 | return (wdns_res_success); 94 | 95 | err: 96 | my_free(rr->name.data); 97 | return (res); 98 | } 99 | -------------------------------------------------------------------------------- /wdns/print_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | wdns_print_message(FILE *fp, wdns_message_t *m) 19 | { 20 | char *s; 21 | 22 | s = wdns_message_to_str(m); 23 | if (s == NULL) 24 | return; 25 | fputs(s, fp); 26 | my_free(s); 27 | } 28 | -------------------------------------------------------------------------------- /wdns/print_rr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | wdns_print_rr(FILE *fp, wdns_rr_t *rr, unsigned sec) 19 | { 20 | char *s; 21 | 22 | s = wdns_rr_to_str(rr, sec); 23 | if (s == NULL) 24 | return; 25 | fputs(s, fp); 26 | my_free(s); 27 | } 28 | -------------------------------------------------------------------------------- /wdns/print_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | wdns_print_rrset(FILE *fp, wdns_rrset_t *rrset, unsigned sec) 19 | { 20 | char *s; 21 | 22 | s = wdns_rrset_to_str(rrset, sec); 23 | if (s == NULL) 24 | return; 25 | fputs(s, fp); 26 | my_free(s); 27 | } 28 | -------------------------------------------------------------------------------- /wdns/print_rrset_array.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | wdns_print_rrset_array(FILE *fp, wdns_rrset_array_t *rr, unsigned sec) 19 | { 20 | char *s; 21 | 22 | s = wdns_rrset_array_to_str(rr, sec); 23 | if (s == NULL) 24 | return; 25 | fputs(s, fp); 26 | my_free(s); 27 | } 28 | -------------------------------------------------------------------------------- /wdns/rdata_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2015 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | char * 18 | wdns_rdata_to_str(const uint8_t *rdata, uint16_t rdlen, 19 | uint16_t rrtype, uint16_t rrclass) 20 | { 21 | char *ret; 22 | size_t retsz; 23 | ubuf *u; 24 | 25 | u = ubuf_new(); 26 | _wdns_rdata_to_ubuf(u, rdata, rdlen, rrtype, rrclass); 27 | ubuf_cterm(u); 28 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 29 | ubuf_destroy(&u); 30 | return (ret); 31 | } 32 | 33 | wdns_res 34 | wdns_str_to_rdata(const char * str, uint16_t rrtype, uint16_t rrclass, 35 | uint8_t **rdata, size_t *rdlen) { 36 | ubuf *u; 37 | wdns_res res; 38 | 39 | u = ubuf_new(); 40 | res = _wdns_str_to_rdata_ubuf(u, str, rrtype, rrclass); 41 | if (res == wdns_res_success) { 42 | ubuf_detach(u, (uint8_t **) rdata, rdlen); 43 | } 44 | ubuf_destroy(&u); 45 | return (res); 46 | } 47 | -------------------------------------------------------------------------------- /wdns/record_descr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * Copyright (c) 2009-2010, 2012, 2016, 2021 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef WDNS_RECORD_DESCR_H 19 | #define WDNS_RECORD_DESCR_H 20 | 21 | #include 22 | 23 | typedef enum { 24 | class_un, /* not class specific */ 25 | class_in /* Internet class */ 26 | } record_class; 27 | 28 | typedef enum { 29 | rdf_unknown, /* marker for unpopulated entries */ 30 | rdf_bytes, /* byte array (terminal) */ 31 | rdf_bytes_b64, /* byte array (terminal) (base64 encoded presentation) */ 32 | rdf_bytes_str, /* byte array (terminal) (string representation) */ 33 | rdf_name, /* series of labels terminated by zero-length label, possibly compressed */ 34 | rdf_uname, /* series of labels terminated by zero-length label, NOT compressed */ 35 | rdf_int8, /* 8 bit integer */ 36 | rdf_int16, /* 16 bit integer */ 37 | rdf_int32, /* 32 bit integer */ 38 | rdf_ipv4, /* IPv4 host address */ 39 | rdf_ipv6, /* IPv6 host address */ 40 | rdf_ipv6prefix, /* IPv6 prefix: length octet followed by 0-16 octets */ 41 | rdf_eui48, /* EUI-48 address */ 42 | rdf_eui64, /* EUI-64 address */ 43 | rdf_string, /* length octet followed by that many octets */ 44 | rdf_repstring, /* one or more strings (terminal) */ 45 | rdf_rrtype, /* resource record type */ 46 | rdf_type_bitmap, /* rr type bitmap */ 47 | rdf_salt, /* length-prefixed salt value (hex presentation) */ 48 | rdf_hash, /* length-prefixed hash value (base32 presentation) */ 49 | rdf_svcparams, /* list of space separated key=value pairs */ 50 | rdf_edns_opt_rdata, /* byte array of {attribute, value} pairs */ 51 | rdf_end, /* sentinel (terminal) */ 52 | } rdf_type; 53 | 54 | typedef struct { 55 | uint16_t record_class; 56 | uint8_t types[10]; 57 | } record_descr; 58 | 59 | extern const record_descr record_descr_array[]; 60 | extern const size_t record_descr_len; 61 | 62 | /* 63 | * Service Binding (SVCB) Parameter Registry 64 | */ 65 | typedef enum { 66 | spr_mandatory = 0, 67 | 68 | /* 69 | * The "alpn" and "no-default-alpn" SvcParamKeys together indicate the 70 | * set of Application Layer Protocol Negotiation (ALPN) protocol 71 | * identifiers [ALPN] and associated transport protocols supported by 72 | * this service endpoint. 73 | */ 74 | spr_alpn = 1, 75 | spr_nd_alpn = 2, 76 | 77 | /* 78 | * TCP or UDP port that should be used to reach this alternative 79 | * endpoint. If this key is not present, clients SHALL use the 80 | * authority endpoint's port number. 81 | */ 82 | spr_port = 3, 83 | 84 | /* Encrypted ClientHello info */ 85 | spr_ech = 5, 86 | 87 | /* 88 | * The "hint" keys convey IP addresses that clients MAY use to reach 89 | * the service. 90 | */ 91 | spr_ipv4hint = 4, 92 | spr_ipv6hint = 6, 93 | 94 | /* Reserved ("Invalid Key") */ 95 | spr_invalid = 65535, 96 | 97 | } svcb_svcparam_keys; 98 | 99 | #endif /* WDNS_RECORD_DESCR_H */ 100 | -------------------------------------------------------------------------------- /wdns/res_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const char * 18 | wdns_res_to_str(wdns_res res) 19 | { 20 | switch (res) { 21 | case wdns_res_success: 22 | return ("success"); 23 | case wdns_res_failure: 24 | return ("failure"); 25 | case wdns_res_invalid_compression_pointer: 26 | return ("invalid compression pointer"); 27 | case wdns_res_invalid_length_octet: 28 | return ("invalid length octet"); 29 | case wdns_res_invalid_opcode: 30 | return ("invalid opcode"); 31 | case wdns_res_invalid_rcode: 32 | return ("invalid rcode"); 33 | case wdns_res_len: 34 | return ("len"); 35 | case wdns_res_malloc: 36 | return ("malloc"); 37 | case wdns_res_name_len: 38 | return ("name len"); 39 | case wdns_res_name_overflow: 40 | return ("name overflow"); 41 | case wdns_res_out_of_bounds: 42 | return ("out of bounds"); 43 | case wdns_res_overflow: 44 | return ("overflow"); 45 | case wdns_res_parse_error: 46 | return ("parse error"); 47 | case wdns_res_qdcount: 48 | return ("qdcount"); 49 | case wdns_res_unknown_opcode: 50 | return ("unknown opcode"); 51 | case wdns_res_unknown_rcode: 52 | return ("unknown rcode"); 53 | } 54 | 55 | return (NULL); 56 | } 57 | -------------------------------------------------------------------------------- /wdns/reverse_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | wdns_res 18 | wdns_reverse_name(const uint8_t *name, size_t len_name, uint8_t *rev_name) { 19 | const uint8_t *p; 20 | size_t len; 21 | size_t total_len = 0; 22 | 23 | p = name; 24 | memset(rev_name, 0, len_name); 25 | rev_name += len_name - 1; 26 | 27 | while ((len = *p) != '\x00') { 28 | len += 1; 29 | total_len += len; 30 | if (total_len > len_name) { 31 | return (wdns_res_out_of_bounds); 32 | } 33 | rev_name -= len; 34 | memcpy(rev_name, p, len); 35 | p += len; 36 | } 37 | 38 | return (wdns_res_success); 39 | } 40 | -------------------------------------------------------------------------------- /wdns/rr_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | char * 18 | wdns_rr_to_str(wdns_rr_t *rr, unsigned sec) 19 | { 20 | char *ret; 21 | size_t retsz; 22 | ubuf *u; 23 | 24 | u = ubuf_new(); 25 | _wdns_rr_to_ubuf(u, rr, sec); 26 | ubuf_cterm(u); 27 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 28 | ubuf_destroy(&u); 29 | return (ret); 30 | } 31 | -------------------------------------------------------------------------------- /wdns/rr_to_ubuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, 2019 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | _wdns_rr_to_ubuf(ubuf *u, wdns_rr_t *rr, unsigned sec) 19 | { 20 | const char *dns_class, *dns_type; 21 | char name[WDNS_PRESLEN_NAME]; 22 | 23 | wdns_domain_to_str(rr->name.data, rr->name.len, name); 24 | dns_class = wdns_rrclass_to_str(rr->rrclass); 25 | dns_type = wdns_rrtype_to_str(rr->rrtype); 26 | 27 | if (sec == WDNS_MSG_SEC_QUESTION) 28 | ubuf_add(u, ';'); 29 | 30 | ubuf_add_cstr(u, name); 31 | 32 | if (sec != WDNS_MSG_SEC_QUESTION) { 33 | char tmp[sizeof("4294967295")]; 34 | const char *rrttl_str; 35 | size_t len; 36 | 37 | ubuf_add(u, ' '); 38 | len = my_uint64_to_str(rr->rrttl, tmp, sizeof(tmp), &rrttl_str); 39 | ubuf_append_cstr(u, rrttl_str, len); 40 | } 41 | 42 | 43 | if (dns_class) 44 | ubuf_add_fmt(u, " %s", dns_class); 45 | else 46 | ubuf_add_fmt(u, " CLASS%u", rr->rrclass); 47 | 48 | if (dns_type) 49 | ubuf_add_fmt(u, " %s", dns_type); 50 | else 51 | ubuf_add_fmt(u, " TYPE%u", rr->rrtype); 52 | 53 | if (sec != WDNS_MSG_SEC_QUESTION) { 54 | ubuf_add(u, ' '); 55 | _wdns_rdata_to_ubuf(u, rr->rdata->data, rr->rdata->len, rr->rrtype, rr->rrclass); 56 | } 57 | ubuf_add(u, '\n'); 58 | } 59 | -------------------------------------------------------------------------------- /wdns/rrset_array_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | char * 18 | wdns_rrset_array_to_str(wdns_rrset_array_t *a, unsigned sec) 19 | { 20 | char *ret; 21 | size_t retsz; 22 | ubuf *u; 23 | 24 | u = ubuf_new(); 25 | _wdns_rrset_array_to_ubuf(u, a, sec); 26 | ubuf_cterm(u); 27 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 28 | ubuf_destroy(&u); 29 | return (ret); 30 | } 31 | -------------------------------------------------------------------------------- /wdns/rrset_array_to_ubuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | _wdns_rrset_array_to_ubuf(ubuf *u, wdns_rrset_array_t *a, unsigned sec) 19 | { 20 | for (unsigned i = 0; i < a->n_rrs; i++) 21 | _wdns_rr_to_ubuf(u, &a->rrs[i], sec); 22 | } 23 | -------------------------------------------------------------------------------- /wdns/rrset_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | char * 18 | wdns_rrset_to_str(wdns_rrset_t *rrset, unsigned sec) 19 | { 20 | char *ret; 21 | size_t retsz; 22 | ubuf *u; 23 | 24 | u = ubuf_new(); 25 | _wdns_rrset_to_ubuf(u, rrset, sec); 26 | ubuf_cterm(u); 27 | ubuf_detach(u, (uint8_t **) &ret, &retsz); 28 | ubuf_destroy(&u); 29 | return (ret); 30 | } 31 | -------------------------------------------------------------------------------- /wdns/rrset_to_ubuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | void 18 | _wdns_rrset_to_ubuf(ubuf *u, wdns_rrset_t *rrset, unsigned sec) 19 | { 20 | unsigned n_rdatas; 21 | 22 | if (sec == WDNS_MSG_SEC_QUESTION) 23 | n_rdatas = 1; 24 | else 25 | n_rdatas = rrset->n_rdatas; 26 | 27 | for (unsigned i = 0; i < n_rdatas; i++) { 28 | wdns_rr_t rr; 29 | rr.rrttl = rrset->rrttl; 30 | rr.rrtype = rrset->rrtype; 31 | rr.rrclass = rrset->rrclass; 32 | rr.name.len = rrset->name.len; 33 | rr.name.data = rrset->name.data; 34 | rr.rdata = rrset->rdatas[i]; 35 | _wdns_rr_to_ubuf(u, &rr, sec); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /wdns/serialize_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Serialize a wdns_rrset_t. 19 | * 20 | * \param[in] rrset the RRset to serialize 21 | * \param[out] buf the output buffer (may be NULL) 22 | * \param[out] sz serialized length (may be NULL) 23 | * 24 | * \return wdns_res_success 25 | */ 26 | 27 | wdns_res 28 | wdns_serialize_rrset(const wdns_rrset_t *rrset, uint8_t *buf, size_t *sz) 29 | { 30 | if (sz) { 31 | *sz = 1; /* length of name */ 32 | *sz += rrset->name.len; /* name */ 33 | *sz += 2; /* type */ 34 | *sz += 2; /* class */ 35 | *sz += 4; /* ttl */ 36 | *sz += 2; /* number of rdatas */ 37 | 38 | for (size_t i = 0; i < rrset->n_rdatas; i++) { 39 | /* rdata length */ 40 | *sz += 2; 41 | 42 | /* rdata */ 43 | *sz += rrset->rdatas[i]->len; 44 | } 45 | } 46 | 47 | if (buf) { 48 | /* length of name */ 49 | memcpy(buf, &rrset->name.len, 1); 50 | buf += 1; 51 | 52 | /* name */ 53 | memcpy(buf, rrset->name.data, rrset->name.len); 54 | buf += rrset->name.len; 55 | 56 | /* type */ 57 | memcpy(buf, &rrset->rrtype, 2); 58 | buf += 2; 59 | 60 | /* class */ 61 | memcpy(buf, &rrset->rrclass, 2); 62 | buf += 2; 63 | 64 | /* ttl */ 65 | memcpy(buf, &rrset->rrttl, 4); 66 | buf += 4; 67 | 68 | /* number of rdatas */ 69 | memcpy(buf, &rrset->n_rdatas, 2); 70 | buf += 2; 71 | 72 | for (size_t i = 0; i < rrset->n_rdatas; i++) { 73 | uint16_t rdlen = rrset->rdatas[i]->len; 74 | 75 | /* rdata length */ 76 | memcpy(buf, &rdlen, 2); 77 | buf += 2; 78 | 79 | /* rdata */ 80 | memcpy(buf, &rrset->rdatas[i]->data, rdlen); 81 | buf += rdlen; 82 | } 83 | } 84 | 85 | return (wdns_res_success); 86 | } 87 | -------------------------------------------------------------------------------- /wdns/skip_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012, 2014 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Skip a possibly compressed domain name. 19 | * 20 | * This function will skip to the end of the buffer if a compression pointer 21 | * or the terminal zero octet is not found. 22 | * 23 | * \param[in,out] data start of the domain name 24 | * \param[in] eod end of buffer containing the domain name 25 | * 26 | * \return number of bytes skipped 27 | */ 28 | 29 | size_t 30 | wdns_skip_name(const uint8_t **data, const uint8_t *eod) 31 | { 32 | const uint8_t *src = *data; 33 | size_t bytes_skipped; 34 | uint8_t c; 35 | 36 | while (src <= eod && (c = *src) != 0) { 37 | if (c >= 192) { 38 | /* compression pointers occupy two octets */ 39 | src++; 40 | break; 41 | } else { 42 | /* skip c octets to the end of the label, then one more to the next 43 | * length octet */ 44 | src += c + 1; 45 | } 46 | } 47 | 48 | /* advance to one octet beyond the end of the name */ 49 | src++; 50 | 51 | if (src > eod) 52 | src = eod; 53 | 54 | bytes_skipped = src - *data; 55 | *data = src; 56 | 57 | return (bytes_skipped); 58 | } 59 | -------------------------------------------------------------------------------- /wdns/sort_rrset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2012 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | static int 18 | rdata_cmp(const void *e1, const void *e2) 19 | { 20 | const wdns_rdata_t *r1 = *((wdns_rdata_t **) e1); 21 | const wdns_rdata_t *r2 = *((wdns_rdata_t **) e2); 22 | 23 | if (r1->len < r2->len) { 24 | return (-1); 25 | } else if (r1->len > r2->len) { 26 | return (1); 27 | } else { 28 | return (memcmp(r1->data, r2->data, r1->len)); 29 | } 30 | } 31 | 32 | /** 33 | * Sort the rdata set of an RRset. 34 | * 35 | * \return wdns_res_success 36 | */ 37 | 38 | wdns_res 39 | wdns_sort_rrset(wdns_rrset_t *rrset) 40 | { 41 | if (rrset->n_rdatas > 1) 42 | qsort(&rrset->rdatas[0], 43 | rrset->n_rdatas, 44 | sizeof(rrset->rdatas[0]), 45 | rdata_cmp); 46 | return (wdns_res_success); 47 | } 48 | -------------------------------------------------------------------------------- /wdns/str_to_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * Copyright (c) 2009-2010, 2012, 2014-2015, 2019 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | static bool 19 | is_digit(char c) 20 | { 21 | if (c >= '0' && c <= '9') 22 | return (true); 23 | return (false); 24 | } 25 | 26 | static wdns_res 27 | _wdns_str_to_name(const char *str, wdns_name_t *name, bool downcase) 28 | { 29 | const char *p = str; 30 | size_t label_len = 0; 31 | ssize_t slen; 32 | uint8_t c, *oclen, *data; 33 | wdns_res res = wdns_res_parse_error; 34 | 35 | slen = strlen(str); 36 | name->len = 1; /* at least 1 in any possible case */ 37 | 38 | if (slen == 0 || (slen == 1 && *p == '.')) { 39 | name->data = my_malloc(1); 40 | name->data[0] = '\0'; 41 | return (wdns_res_success); 42 | } 43 | 44 | name->data = my_malloc(WDNS_MAXLEN_NAME); 45 | data = name->data; 46 | oclen = data++; 47 | 48 | for (;;) { 49 | c = *p++; 50 | label_len++; 51 | 52 | if (slen == 0) { 53 | /* end of input */ 54 | if (name->len == WDNS_MAXLEN_NAME) { 55 | res = wdns_res_name_overflow; 56 | goto out; 57 | } 58 | *oclen = --label_len; 59 | *data++ = '\0'; 60 | name->len++; 61 | break; 62 | } 63 | 64 | if (name->len >= WDNS_MAXLEN_NAME) { 65 | res = wdns_res_name_overflow; 66 | goto out; 67 | } 68 | 69 | if (c >= 'A' && c <= 'Z') { 70 | /* an upper case letter; downcase it */ 71 | if (downcase) 72 | c |= 0x20; 73 | *data++ = c; 74 | name->len++; 75 | } else if (c == '\\' && !is_digit(*p)) { 76 | /* an escaped character */ 77 | if (slen <= 0) 78 | goto out; 79 | *data++ = *p; 80 | name->len++; 81 | p++; 82 | slen--; 83 | } else if (c == '\\' && slen >= 3) { 84 | /* an escaped octet */ 85 | char d[4]; 86 | char *endptr = NULL; 87 | long int val; 88 | 89 | d[0] = *p++; 90 | d[1] = *p++; 91 | d[2] = *p++; 92 | d[3] = '\0'; 93 | slen -= 3; 94 | if (!is_digit(d[0]) || !is_digit(d[1]) || !is_digit(d[2])) 95 | goto out; 96 | val = strtol(d, &endptr, 10); 97 | if (endptr != NULL && *endptr == '\0' 98 | && val >= 0 && val <= 255) 99 | { 100 | uint8_t uval; 101 | 102 | uval = (uint8_t) val; 103 | *data++ = uval; 104 | name->len++; 105 | } else { 106 | goto out; 107 | } 108 | } else if (c == '\\') { 109 | /* should not occur */ 110 | goto out; 111 | } else if (c == '.') { 112 | /* end of label */ 113 | *oclen = --label_len; 114 | if (label_len == 0) 115 | goto out; 116 | oclen = data++; 117 | name->len++; 118 | if (slen == 1) { 119 | /* trailing '.', end of name */ 120 | *oclen = 0; 121 | break; 122 | } 123 | label_len = 0; 124 | } else if (c != '\0') { 125 | *data++ = c; 126 | name->len++; 127 | } 128 | 129 | slen--; 130 | } 131 | 132 | return (wdns_res_success); 133 | 134 | out: 135 | my_free(name->data); 136 | return (res); 137 | } 138 | 139 | wdns_res 140 | wdns_str_to_name(const char *str, wdns_name_t *name) 141 | { 142 | return _wdns_str_to_name(str, name, true); 143 | } 144 | 145 | wdns_res 146 | wdns_str_to_name_case(const char *str, wdns_name_t *name) 147 | { 148 | return _wdns_str_to_name(str, name, false); 149 | } 150 | -------------------------------------------------------------------------------- /wdns/svcparamkeys_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Helper routines for values in the Service Binding (SVCB) Parameter Registry. 19 | */ 20 | char * 21 | _wdns_svcparamkey_to_str(uint16_t key, char *buf, size_t len) 22 | { 23 | switch (key) { 24 | case spr_mandatory: 25 | return (strncpy(buf, "mandatory", len)); 26 | 27 | case spr_alpn: 28 | return (strncpy(buf, "alpn", len)); 29 | 30 | case spr_nd_alpn: 31 | return (strncpy(buf, "no-default-alpn", len)); 32 | 33 | case spr_port: 34 | return (strncpy(buf, "port", len)); 35 | 36 | case spr_ech: 37 | return (strncpy(buf, "ech", len)); 38 | 39 | case spr_ipv4hint: 40 | return (strncpy(buf, "ipv4hint", len)); 41 | 42 | case spr_ipv6hint: 43 | return (strncpy(buf, "ipv6hint", len)); 44 | 45 | case spr_invalid: 46 | return (strncpy(buf, "invalid key", len)); 47 | 48 | default: 49 | if (snprintf(buf, len, "key%hu", key) > 0) { 50 | return (buf); 51 | } 52 | } 53 | 54 | return (NULL); 55 | } 56 | 57 | uint16_t 58 | _wdns_str_to_svcparamkey(char *str) 59 | { 60 | if (strcmp(str, "mandatory") == 0) { 61 | return (spr_mandatory); 62 | } else if (strcmp(str, "alpn") == 0) { 63 | return (spr_alpn); 64 | } else if (strcmp(str, "no-default-alpn") == 0) { 65 | return (spr_nd_alpn); 66 | } else if (strcmp(str, "port") == 0) { 67 | return (spr_port); 68 | } else if (strcmp(str, "ech") == 0) { 69 | return (spr_ech); 70 | } else if (strcmp(str, "ipv4hint") == 0) { 71 | return (spr_ipv4hint); 72 | } else if (strcmp(str, "ipv6hint") == 0) { 73 | return (spr_ipv6hint); 74 | } else if (strncmp(str, "key", 3) == 0 && strlen(str) > 3) { 75 | /* parse an arbitrary key */ 76 | unsigned long int key; 77 | char *endp; 78 | 79 | key = strtoul(str + strlen("key"), &endp, 10); 80 | assert(endp != NULL); 81 | 82 | if (*endp != '\0' || key >= (unsigned long int)spr_invalid) { 83 | return (spr_invalid); 84 | } 85 | 86 | if (key < spr_invalid) { 87 | return ((uint16_t)key); 88 | } 89 | } 90 | 91 | return (spr_invalid); 92 | } 93 | -------------------------------------------------------------------------------- /wdns/unpack_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, 2012, 2019 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Uncompress a domain name from a message. 19 | * 20 | * The caller must allocate at least #WDNS_MAXLEN_NAME bytes for 21 | * the destination buffer. 22 | * 23 | * \param[in] p pointer to message 24 | * \param[in] eop pointer to end of message 25 | * \param[in] src pointer to domain name 26 | * \param[out] dst caller-allocated buffer for uncompressed domain name 27 | * \param[out] sz total length of uncompressed domain name (may be NULL) 28 | * 29 | * \return 30 | */ 31 | 32 | wdns_res 33 | wdns_unpack_name(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 34 | uint8_t *dst, size_t *sz) 35 | { 36 | const uint8_t *cptr; 37 | uint8_t c; 38 | 39 | size_t total_len = 0; 40 | 41 | if (p >= eop || src >= eop || src < p) 42 | return (wdns_res_out_of_bounds); 43 | 44 | while ((c = *src++) != 0) { 45 | if (c >= 192) { 46 | uint16_t offset; 47 | 48 | if (src > eop) 49 | return (wdns_res_out_of_bounds); 50 | 51 | /* offset is the lower 14 bits of the 2 octet sequence */ 52 | offset = ((c & 63) << 8) + *src; 53 | 54 | cptr = p + offset; 55 | 56 | if (cptr > eop) 57 | return (wdns_res_invalid_compression_pointer); 58 | 59 | if (cptr == src - 1 && (*(src - 1) == 0)) { 60 | /* if a compression pointer points to exactly one octet 61 | * before itself, then the only valid domain name pointee 62 | * is the zero-octet root label. */ 63 | src = cptr; 64 | } else if (cptr > src - 2) { 65 | return (wdns_res_invalid_compression_pointer); 66 | } else { 67 | src = cptr; 68 | } 69 | } else if (c <= 63) { 70 | total_len++; 71 | if (total_len >= WDNS_MAXLEN_NAME) 72 | return (wdns_res_name_overflow); 73 | *dst++ = c; 74 | 75 | total_len += c; 76 | if (total_len >= WDNS_MAXLEN_NAME) 77 | return (wdns_res_name_overflow); 78 | if (src + c > eop) 79 | return (wdns_res_out_of_bounds); 80 | memcpy(dst, src, c); 81 | 82 | dst += c; 83 | src += c; 84 | } else { 85 | return (wdns_res_invalid_length_octet); 86 | } 87 | } 88 | *dst = '\0'; 89 | total_len++; 90 | 91 | if (sz) 92 | *sz = total_len; 93 | return (wdns_res_success); 94 | } 95 | -------------------------------------------------------------------------------- /wdns/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 by Farsight Security, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* Import. */ 18 | 19 | #include "wdns.h" 20 | 21 | const char * 22 | wdns_get_version(void) 23 | { 24 | return (WDNS_LIBRARY_VERSION); 25 | } 26 | 27 | uint32_t 28 | wdns_get_version_number(void) 29 | { 30 | return (WDNS_LIBRARY_VERSION_NUMBER); 31 | } 32 | -------------------------------------------------------------------------------- /wdns/wdns-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 DomainTools LLC 3 | * Copyright (c) 2012-2015, 2021 by Farsight Security, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifdef HAVE_ALLOCA_H 19 | # include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "wdns.h" 37 | 38 | #include "record_descr.h" 39 | #include "libmy/b32_decode.h" 40 | #include "libmy/b32_encode.h" 41 | #include "libmy/b64_decode.h" 42 | #include "libmy/b64_encode.h" 43 | 44 | #include "libmy/my_format.h" 45 | 46 | #include "libmy/my_alloc.h" 47 | #include "libmy/ubuf.h" 48 | 49 | #include "libmy/fast_inet_ntop.h" 50 | 51 | #define load_net16(buf, out) do { \ 52 | uint16_t _my_16; \ 53 | memcpy(&_my_16, buf, sizeof(uint16_t)); \ 54 | _my_16 = ntohs(_my_16); \ 55 | *(out) = _my_16; \ 56 | } while (0) 57 | 58 | #define load_net32(buf, out) do { \ 59 | uint32_t _my_32; \ 60 | memcpy(&_my_32, buf, sizeof(uint32_t)); \ 61 | _my_32 = ntohl(_my_32); \ 62 | *(out) = _my_32; \ 63 | } while (0) 64 | 65 | /** 66 | * Advance pointer p by sz bytes and update len. 67 | */ 68 | #define WDNS_BUF_ADVANCE(p, len, sz) do { \ 69 | p += sz; \ 70 | len -= sz; \ 71 | } while (0) 72 | 73 | /** 74 | * Read an 8 bit integer. 75 | */ 76 | #define WDNS_BUF_GET8(dst, src) do { \ 77 | memcpy(&dst, src, 1); \ 78 | src++; \ 79 | } while (0) 80 | 81 | /** 82 | * Read a 16 bit integer. 83 | */ 84 | #define WDNS_BUF_GET16(dst, src) do { \ 85 | memcpy(&dst, src, 2); \ 86 | dst = ntohs(dst); \ 87 | src += 2; \ 88 | } while (0) 89 | 90 | /** 91 | * Read a 32 bit integer. 92 | */ 93 | #define WDNS_BUF_GET32(dst, src) do { \ 94 | memcpy(&dst, src, 4); \ 95 | dst = ntohl(dst); \ 96 | src += 4; \ 97 | } while (0) 98 | 99 | wdns_res 100 | _wdns_insert_rr_rrset_array(wdns_rrset_array_t *a, wdns_rr_t *rr, unsigned sec); 101 | 102 | wdns_res 103 | _wdns_parse_edns(wdns_message_t *m, wdns_rr_t *rr); 104 | 105 | wdns_res 106 | _wdns_parse_rdata(wdns_rr_t *rr, const uint8_t *p, const uint8_t *eop, 107 | const uint8_t *rdata, uint16_t rdlen); 108 | 109 | wdns_res 110 | _wdns_parse_header(const uint8_t *p, size_t len, uint16_t *id, uint16_t *flags, 111 | uint16_t *qdcount, uint16_t *ancount, uint16_t *nscount, uint16_t *arcount); 112 | 113 | wdns_res 114 | _wdns_parse_message_rr(unsigned sec, const uint8_t *p, const uint8_t *eop, const uint8_t *data, 115 | size_t *rrsz, wdns_rr_t *rr); 116 | 117 | void 118 | _wdns_rdata_to_ubuf(ubuf *, const uint8_t *rdata, uint16_t rdlen, 119 | uint16_t rrtype, uint16_t rrclass); 120 | 121 | wdns_res 122 | _wdns_str_to_rdata_ubuf(ubuf *, const char * str, 123 | uint16_t rrtype, uint16_t rrclass); 124 | 125 | void 126 | _wdns_rr_to_ubuf(ubuf *, wdns_rr_t *rr, unsigned sec); 127 | 128 | void 129 | _wdns_rrset_to_ubuf(ubuf *, wdns_rrset_t *rrset, unsigned sec); 130 | 131 | void 132 | _wdns_rrset_array_to_ubuf(ubuf *, wdns_rrset_array_t *a, unsigned sec); 133 | 134 | uint16_t 135 | _wdns_str_to_svcparamkey(char *str); 136 | 137 | char * 138 | _wdns_svcparamkey_to_str(uint16_t key, char *buf, size_t len); 139 | 140 | void 141 | _wdns_ednsoptcode_to_ubuf(ubuf *, uint16_t option_code); 142 | 143 | wdns_res 144 | _wdns_ednsoptdata_to_ubuf(ubuf *u, uint16_t option_code, const uint8_t *src, uint16_t src_bytes); 145 | --------------------------------------------------------------------------------