[ci skip] Pack with inline submodules

This commit is contained in:
github-actions[bot] 2022-06-24 12:19:07 +00:00
parent 3b5f5f24a2
commit c1bdea8e1d
2827 changed files with 3970520 additions and 2 deletions

View File

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.0...3.12) cmake_minimum_required(VERSION 3.0...3.12)
if(UA_BUILD_FUZZING OR UA_BUILD_OSS_FUZZ OR UA_BUILD_FUZZING_CORPUS) if(UA_BUILD_FUZZING OR UA_BUILD_OSS_FUZZ OR UA_BUILD_FUZZING_CORPUS)
set(OPEN62541_VERSION "v1.3.2")
project(open62541) # We need to have C++ support configured for fuzzing project(open62541) # We need to have C++ support configured for fuzzing
else() else()
project(open62541 C) # Do not look for a C++ compiler project(open62541 C) # Do not look for a C++ compiler

12
debian/changelog vendored Normal file
View File

@ -0,0 +1,12 @@
open62541 (20220624T121906~1.3.2) UNRELEASED; urgency=medium
* Full changelog is available here:
https://github.com/open62541/open62541/blob/master/CHANGELOG
-- open62541 Team <open62541-core@googlegroups.com> Fri, 24 Jun 2022 12:19:06 -0000
open62541 (1.0~rc1) UNRELEASED; urgency=low
* Release Candidate 1 for 1.0 Version.
-- open62541 Team <open62541-core@googlegroups.com> Fri, 19 Jul 2019 10:51:28 +0100

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
9

78
debian/control vendored Normal file
View File

@ -0,0 +1,78 @@
Source: open62541
Priority: optional
Maintainer: open62541 Team <open62541-core@googlegroups.com>
Build-Depends: debhelper (>= 9),
cmake (>= 2.8),
python3,
python3-sphinx, python3-sphinx-rtd-theme,
graphviz,
texlive-fonts-recommended,
texlive-latex-extra,
texlive-plain-generic | texlive-generic-extra,
latexmk,
libmbedtls-dev
Standards-Version: 4.4.1
Section: libs
Homepage: https://open62541.org/
Vcs-Git: https://github.com/open62541/open62541.git
Vcs-Browser: https://github.com/open62541/open62541
Package: libopen62541-1.3
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}, libmbedtls10 | libmbedtls12
Description: Open source implementation of OPC UA - shared library
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 shared library
Package: libopen62541-1.3-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libopen62541-1.3 (= ${binary:Version}), ${misc:Depends}, libmbedtls-dev
Description: Open source implementation of OPC UA - development files
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 header and development files
Package: libopen62541-1.3-tools
Section: libdevel
Architecture: all
Depends: ${misc:Depends}, python3
Recommends: libopen62541-1.3-dev
Description: Open source implementation of OPC UA - tools
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides some open62541 tools, e.g. the nodeset compiler
Package: libopen62541-1.3-doc
Section: doc
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}, ${sphinxdoc:Depends}
Description: Open source implementation of OPC UA - documentation
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 documentation as PDF and HTML
and example applications

78
debian/control-template vendored Normal file
View File

@ -0,0 +1,78 @@
Source: open62541
Priority: optional
Maintainer: open62541 Team <open62541-core@googlegroups.com>
Build-Depends: debhelper (>= 9),
cmake (>= 2.8),
python3,
python3-sphinx, python3-sphinx-rtd-theme,
graphviz,
texlive-fonts-recommended,
texlive-latex-extra,
texlive-plain-generic | texlive-generic-extra,
latexmk,
libmbedtls-dev
Standards-Version: 4.4.1
Section: libs
Homepage: https://open62541.org/
Vcs-Git: https://github.com/open62541/open62541.git
Vcs-Browser: https://github.com/open62541/open62541
Package: libopen62541-<soname>
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}, libmbedtls10 | libmbedtls12
Description: Open source implementation of OPC UA - shared library
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 shared library
Package: libopen62541-<soname>-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libopen62541-<soname> (= ${binary:Version}), ${misc:Depends}, libmbedtls-dev
Description: Open source implementation of OPC UA - development files
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 header and development files
Package: libopen62541-<soname>-tools
Section: libdevel
Architecture: all
Depends: ${misc:Depends}, python3
Recommends: libopen62541-<soname>-dev
Description: Open source implementation of OPC UA - tools
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides some open62541 tools, e.g. the nodeset compiler
Package: libopen62541-<soname>-doc
Section: doc
Architecture: all
Multi-Arch: foreign
Depends: ${misc:Depends}, ${sphinxdoc:Depends}
Description: Open source implementation of OPC UA - documentation
open62541 (http://open62541.org) is an open source and free implementation
of OPC UA (OPC Unified Architecture) written in the common subset of the
C99 and C++98 languages.
The library is usable with all major compilers and provides the necessary
tools to implement dedicated OPC UA clients and servers, or to integrate
OPC UA-based communication into existing applications.
.
This package provides the open62541 documentation as PDF and HTML
and example applications

381
debian/copyright vendored Normal file
View File

@ -0,0 +1,381 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: open62541
Upstream-Contact: open62541 Team <open62541-core@googlegroups.com>
Source: https://open62541.org/
Files: *
Copyright: 2019 open62541 Team <open62541-core@googlegroups.com>
License: MPL-2.0
Mozilla Public License Version 2.0
==================================
.
1. Definitions
--------------
.
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
.
1.3. "Contribution"
means Covered Software of a particular Contributor.
.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
.
1.5. "Incompatible With Secondary Licenses"
means
.
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
.
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
.
1.8. "License"
means this document.
.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
.
1.10. "Modifications"
means any of the following:
.
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
.
(b) any new file in Source Code Form that contains any Covered
Software.
.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
.
2. License Grants and Conditions
--------------------------------
.
2.1. Grants
.
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
.
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
.
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
.
2.2. Effective Date
.
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
.
2.3. Limitations on Grant Scope
.
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
.
(a) for any code that a Contributor has removed from Covered Software;
or
.
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
.
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
.
2.4. Subsequent Licenses
.
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
.
2.5. Representation
.
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
.
2.6. Fair Use
.
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
.
2.7. Conditions
.
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
.
3. Responsibilities
-------------------
.
3.1. Distribution of Source Form
.
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
.
3.2. Distribution of Executable Form
.
If You distribute Covered Software in Executable Form then:
.
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
.
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
.
3.3. Distribution of a Larger Work
.
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
.
3.4. Notices
.
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
.
3.5. Application of Additional Terms
.
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
.
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
.
5. Termination
--------------
.
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
.
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
.
8. Litigation
-------------
.
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
.
9. Miscellaneous
----------------
.
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
.
10. Versions of the License
---------------------------
.
10.1. New Versions
.
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
.
10.2. Effect of New Versions
.
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
.
10.3. Modified Versions
.
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
.
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
.
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
.
Exhibit A - Source Code Form License Notice
-------------------------------------------
.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
.
You may add additional accurate notices of copyright ownership.
.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
.
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

5
debian/libopen62541-1.3-dev.install vendored Normal file
View File

@ -0,0 +1,5 @@
usr/include
usr/lib/*/*.so
usr/lib/*/*.a
usr/lib/*/cmake/open62541/*
usr/lib/*/pkgconfig/open62541.pc

16
debian/libopen62541-1.3-doc.doc-base vendored Normal file
View File

@ -0,0 +1,16 @@
Document: open62541
Title: open62541 Manual
Author: The open62541 Team <open62541-core@googlegroups.com>
Abstract: open62541 (http://open62541.org) is an open source
and free implementation of OPC UA (OPC Unified Architecture)
written in the common subset of the C99 and C++98 languages.
This manual contains an introduction to the open62541 library
and describes how to use it for server and client applications.
Section: Network/Communication
Format: HTML
Index: /usr/share/doc/open62541/open62541.html/index.html
Files: /usr/share/doc/open62541/open62541.html/*
Format: PDF
Files: /usr/share/doc/open62541/open62541.pdf.gz

2
debian/libopen62541-1.3-doc.install vendored Normal file
View File

@ -0,0 +1,2 @@
usr/share/doc/open62541
usr/share/open62541/examples

9
debian/libopen62541-1.3-tools.install vendored Normal file
View File

@ -0,0 +1,9 @@
usr/share/open62541/tools/*.py
usr/share/open62541/tools/certs
usr/share/open62541/tools/nodeset_compiler
usr/share/open62541/tools/schema
usr/share/open62541/tools/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
usr/share/open62541/tools/ua-nodeset/Schema/Opc.Ua.Types.bsd
usr/share/open62541/tools/ua-nodeset/Schema/AttributeIds.csv
usr/share/open62541/tools/ua-nodeset/Schema/NodeIds.csv
usr/share/open62541/tools/ua-nodeset/Schema/StatusCode.csv

1
debian/libopen62541-1.3.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/*.so.*

View File

@ -0,0 +1,5 @@
usr/include
usr/lib/*/*.so
usr/lib/*/*.a
usr/lib/*/cmake/open62541/*
usr/lib/*/pkgconfig/open62541.pc

View File

@ -0,0 +1,16 @@
Document: open62541
Title: open62541 Manual
Author: The open62541 Team <open62541-core@googlegroups.com>
Abstract: open62541 (http://open62541.org) is an open source
and free implementation of OPC UA (OPC Unified Architecture)
written in the common subset of the C99 and C++98 languages.
This manual contains an introduction to the open62541 library
and describes how to use it for server and client applications.
Section: Network/Communication
Format: HTML
Index: /usr/share/doc/open62541/open62541.html/index.html
Files: /usr/share/doc/open62541/open62541.html/*
Format: PDF
Files: /usr/share/doc/open62541/open62541.pdf.gz

View File

@ -0,0 +1,2 @@
usr/share/doc/open62541
usr/share/open62541/examples

View File

@ -0,0 +1,9 @@
usr/share/open62541/tools/*.py
usr/share/open62541/tools/certs
usr/share/open62541/tools/nodeset_compiler
usr/share/open62541/tools/schema
usr/share/open62541/tools/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
usr/share/open62541/tools/ua-nodeset/Schema/Opc.Ua.Types.bsd
usr/share/open62541/tools/ua-nodeset/Schema/AttributeIds.csv
usr/share/open62541/tools/ua-nodeset/Schema/NodeIds.csv
usr/share/open62541/tools/ua-nodeset/Schema/StatusCode.csv

1
debian/libopen62541.install-template vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/*.so.*

22
debian/rules vendored Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
override_dh_auto_configure:
dh_auto_configure -- -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUA_NAMESPACE_ZERO=REDUCED -DUA_ENABLE_ENCRYPTION="MBEDTLS" -DUA_ENABLE_AMALGAMATION=OFF -DUA_PACK_DEBIAN=ON -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_HOST_MULTIARCH)"
override_dh_auto_test:
dh_auto_test -- ARGS+=--output-on-failure
override_dh_auto_build:
dh_auto_build -- -j`nproc --ignore=2`
make -C obj-${DEB_HOST_GNU_TYPE} doc doc_pdf
override_dh_install:
dh_install
dh_sphinxdoc -X_sources
%:
dh $@ --buildsystem=cmake --parallel

22
debian/rules-template vendored Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
override_dh_auto_configure:
dh_auto_configure -- -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUA_NAMESPACE_ZERO=REDUCED -DUA_ENABLE_ENCRYPTION="MBEDTLS" -DUA_ENABLE_AMALGAMATION=OFF -DUA_PACK_DEBIAN=ON -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_HOST_MULTIARCH)"
override_dh_auto_test:
dh_auto_test -- ARGS+=--output-on-failure
override_dh_auto_build:
dh_auto_build -- -j`nproc --ignore=2`
make -C obj-${DEB_HOST_GNU_TYPE} doc doc_pdf
override_dh_install:
dh_install
dh_sphinxdoc -X_sources
%:
dh $@ --buildsystem=cmake --parallel

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (native)

1
deps/mdnsd vendored

@ -1 +0,0 @@
Subproject commit 3151afe5899dba5125dffa9f4cf3ae1fe2edc0f0

3
deps/mdnsd/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*~
build/
.vscode/

184
deps/mdnsd/.travis.yml vendored Normal file
View File

@ -0,0 +1,184 @@
# using c for language overwrites our compilers
language: c
sudo: false
dist: trusty
matrix:
include:
#
# gcc-4.8 (trusty) full host and cross build with tests:
- os: linux
compiler: gcc-4.8
addons:
apt:
sources:
# see https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
- ubuntu-toolchain-r-test
packages:
- binutils-mingw-w64-i686
- build-essential
- check
- cppcheck
- gcc-multilib
- gcc-4.9
- gcc-mingw-w64-i686
- g++-multilib
- g++-mingw-w64
- libc6-dev-i386
- linux-libc-dev:i386
- mingw-w64
- valgrind
env:
- ANALYZE=false
- MINGW=true
#
# gcc-8 full host build with tests:
- os: linux
compiler: gcc-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-8
- gcc-8-multilib
- check
- cppcheck
- valgrind
env:
- ANALYZE=false
#
# clang-8 full host build with tests:
- os: linux
compiler: clang-8
addons:
apt:
sources:
- llvm-toolchain-trusty-8
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-8
- valgrind
env:
- ANALYZE=false
- os: linux
compiler: clang-6.0
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-6.0
- clang-tidy-6.0
- valgrind
env:
- ANALYZE=false
#
# gcc-4.8 static code analysis
- os: linux
compiler: gcc
addons:
apt:
packages:
- check
- cppcheck
- valgrind
env:
- ANALYZE=true
#
# clang-6 static code analysis
- os: linux
compiler: clang-6.0
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-6.0
- clang-tidy-6.0
- valgrind
env:
- ANALYZE=true
#
# clang-8 FUZZER build
- os: linux
compiler: clang-8
addons:
apt:
sources:
- llvm-toolchain-trusty-8
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- valgrind
- clang-8
- clang-tidy-8
- libfuzzer-8-dev
env:
- FUZZER=true
#
# OSX clang build
- os: osx
compiler: clang
# disable homebrew auto update which takes a lot of time
env: HOMEBREW_NO_AUTO_UPDATE=1
cache:
directories:
- $HOME/Library/Caches/Homebrew
env:
- ANALYZE=false
#addons:
# apt:
# sources:
# # see https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
# packages:
# - binutils-mingw-w64-i686
# - build-essential
# - cmake
# - mingw32-gcc
# - gcc-mingw-w64-i686
# - gcc-mingw-w64
# - g++-mingw-w64
# - gcc-multilib
# - g++-multilib
# - libc6-dbg # for valgrind compilation
cache:
pip: true
apt: true
directories:
- $HOME/install
before_install:
# set paths for locally installed libs (like liburcu)
- export LOCAL_PKG=$HOME/install
- mkdir -p $LOCAL_PKG/lib
- mkdir -p $LOCAL_PKG/include
- mkdir -p $LOCAL_PKG/bin
- export LIBRARY_PATH=$LOCAL_PKG/lib:$LIBRARY_PATH
- export C_INCLUDE_PATH=$LOCAL_PKG/include:$C_INCLUDE_PATH
- export CPLUS_INCLUDE_PATH=$LOCAL_PKG/include:$CPLUS_INCLUDE_PATH
- export PKG_CONFIG_PATH=$LOCAL_PKG/lib/pkgconfig:$PKG_CONFIG_PATH
- export PATH=$LOCAL_PKG:$LOCAL_PKG/bin:$PATH
# set local path for python packages
- export PATH=$PATH:$HOME/.local/bin # linux
- export PATH=$PATH:$HOME/Library/Python #OS X
- export PATH=$PATH:$HOME/Library/Python/2.7/bin #OS X
- if [ ${TRAVIS_OS_NAME} == "linux" ]; then sh ./tools/travis/travis_linux_before_install.sh; fi
- if [ ${TRAVIS_OS_NAME} == "osx" ]; then sh ./tools/travis/travis_osx_before_install.sh; fi
script:
- if [ ${TRAVIS_OS_NAME} == "linux" ]; then sh ./tools/travis/travis_linux_script.sh; fi
- if [ ${TRAVIS_OS_NAME} == "osx" ]; then sh ./tools/travis/travis_osx_script.sh; fi

76
deps/mdnsd/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 2.8)
project(mdnsd C CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake")
include(GNUInstallDirs)
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
option(MDNSD_BUILD_OSS_FUZZ "Special build switch used in oss-fuzz" OFF)
mark_as_advanced(MDNSD_BUILD_OSS_FUZZ)
option(MDNSD_BUILD_FUZZING "Build the fuzzing executables" OFF)
mark_as_advanced(MDNSD_BUILD_FUZZING)
if(MDNSD_BUILD_FUZZING)
# oss-fuzz already defines this by default
add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
endif()
set(BUILD_SHARED_LIBS_DEFAULT ON)
if(MDNSD_BUILD_OSS_FUZZ)
set(BUILD_SHARED_LIBS_DEFAULT OFF)
endif()
option(BUILD_SHARED_LIBS "Build libmdnsd as a shared library" ${BUILD_SHARED_LIBS_DEFAULT})
if(MDNSD_BUILD_FUZZING_CORPUS)
add_definitions(-DMDNSD_DEBUG_DUMP_PKGS_FILE)
endif()
option(MDNSD_ENABLE_SANITIZERS "enable sanitizers for mdnsd ON)" ON)
# Debug
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER_CASE)
if(MDNSD_ENABLE_SANITIZERS AND BUILD_TYPE_LOWER_CASE STREQUAL "debug" AND UNIX)
if("x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
# Add default sanitizer settings when using clang and Debug build.
# This allows e.g. CLion to find memory locations for SegFaults
message(STATUS "Sanitizer enabled")
set(SANITIZER_FLAGS "-g -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -fsanitize=leak -fsanitize=undefined")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAGS}")
endif()
endif()
add_subdirectory(libmdnsd)
if(MDNSD_BUILD_FUZZING OR MDNSD_BUILD_OSS_FUZZ)
add_subdirectory(tests/fuzz)
endif()
add_executable(mdnsd mdnsd.c)
target_link_libraries(mdnsd PRIVATE libmdnsd)
add_executable(mquery mquery.c)
target_link_libraries(mquery PRIVATE libmdnsd)
include(CMakePackageConfigHelpers)
configure_package_config_file(mdnsdConfig.cmake.in mdnsdConfig.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
)
install(
TARGETS mdnsd mquery
EXPORT mdnsd
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
install(
FILES "${PROJECT_SOURCE_DIR}/LICENSE"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}"
)
install(EXPORT mdnsd
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
FILE "mdnsdConfigTargets.cmake"
)
install(FILES "${PROJECT_BINARY_DIR}/mdnsdConfig.cmake"
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
)

24
deps/mdnsd/LICENSE vendored Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2003 Jeremie Miller <jer@jabber.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

66
deps/mdnsd/README.md vendored Normal file
View File

@ -0,0 +1,66 @@
mdnsd - embeddable Multicast DNS Daemon
=======================================
[![Ohloh Project Status](https://www.ohloh.net/p/mdnsd_pro/widgets/project_thin_badge.gif)](https://www.ohloh.net/p/mdnsd_pro)
[![Build Status](https://travis-ci.org/Pro/mdnsd.png?branch=master)](https://travis-ci.org/Pro/mdnsd)
[![Build status](https://ci.appveyor.com/api/projects/status/gv4lros88uubrkwd?svg=true)](https://ci.appveyor.com/project/Pro/mdnsd)
This package is intended for software developers and integrators, there
isn't really anything here for an end user. The project license is the
modified 3-clause BSD, https://en.wikipedia.org/wiki/BSD_licenses
You should be able to just type make and it will build the included
example apps. Otherwise, check out `mdnsd.h` to get started, the API is
as simple as I could make it, but I hope to find some easier/better ways
to improve it in the future. Also included are some other utilities,
`sdtxt.*` for service discovery TXT record parsing/generation, and
`xht.*` for simple fast hashtables, and `1035.*` which mdnsd uses for
standalone DNS parsing.
**Differences to the base repo (https://github.com/troglobit/mdnsd)**:
* Use CMake for the build
* Strict compilation flags for better portability
* Support of Linux, MinGW, **OS X** and **Windows**
* Continuous Integration
Build & Install
---------------
The software is built for and developed on GNU/Linux systems, but should
work on any UNIX like system.
The GNU configure and build system is used, simply call the configure
script to generate a Makefile. If you are using the GitHub sources you
first need to call `./autogen.sh` to generate the configure script.
./configure
make all
make install
Running
-------
To test the included example applications you need to first start the
`mdnsd` daemon before calling `mquery`:
./mdnsd _name._service 192.168.1.2 80 &
./mquery 12 _http._tcp.local.
Origin & References
-------------------
This MDNS-SD implementation was developed by [Jeremie Miller][jeremie]
in 2003, originally [announced on the rendezvous-dev][announced] mailing
list. It has many forks and has been used by many other applications
over the years.
This GitHub project is an attempt to clean it up, develop it further,
and maintain it for the long haul.
[jeremie]: https://github.com/quartzjer
[announced]: http://lists.apple.com/archives/rendezvous-dev/2003/Feb/msg00062.html
[Travis]: https://travis-ci.org/troglobit/mdnsd
[Travis Status]: https://travis-ci.org/troglobit/mdnsd.png?branch=master

65
deps/mdnsd/appveyor.yml vendored Normal file
View File

@ -0,0 +1,65 @@
version: '{build}'
clone_folder: c:\projects\mdnsd
clone_depth: 1
environment:
global:
CYG_ARCH: x86
CYG_ROOT: C:/cygwin
CYG_SETUP_URL: http://cygwin.com/setup-x86.exe
CYG_MIRROR: http://cygwin.mirror.constant.com
CYG_CACHE: C:\cygwin\var\cache\setup
CYG_BASH: C:/cygwin/bin/bash
SHARED: ON
matrix:
- GENERATOR: MinGW Makefiles
FORCE_CXX: OFF
- GENERATOR: Visual Studio 9 2008
FORCE_CXX: ON
- GENERATOR: Visual Studio 12 2013
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- GENERATOR: Visual Studio 12 2013 Win64
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- GENERATOR: Visual Studio 16 2019
SHARED: ON
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- GENERATOR: Visual Studio 16 2019
SHARED: OFF
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
cache:
- '%CYG_CACHE%'
init:
- git config --global core.autocrlf input # Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail
# Install needed build dependencies
install:
- git submodule update --init --recursive
- if not exist "%CYG_ROOT%" mkdir "%CYG_ROOT%"
- ps: echo "Installing Cygwin from $env:CYG_SETUP_URL to $env:CYG_ROOT/setup-x86.exe"
- appveyor DownloadFile %CYG_SETUP_URL% -FileName %CYG_ROOT%/setup-x86.exe
- ps: echo "Downloaded. Now ready to install."
- cmd: '"%CYG_ROOT%/setup-x86.exe" --quiet-mode --no-shortcuts --only-site -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" --packages cmake,python'
- cmd: '%CYG_BASH% -lc "cygcheck -dc cygwin"'
before_build:
# use MinGW64
- set PATH=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
# Workaround for CMake not wanting sh.exe on PATH for MinGW
- set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
build_script:
- cd "%APPVEYOR_BUILD_FOLDER%""
- md build
- cd build
- echo "Testing %GENERATOR%"
- cmake -DMDNSD_COMPILE_AS_CXX:BOOL=%FORCE_CXX% -DBUILD_SHARED_LIBS:BOOL=%SHARED% -G"%GENERATOR%" ..
- cmake --build .
- echo "Build done"

3
deps/mdnsd/libmdnsd/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*~
*.o
libmdnsd*

637
deps/mdnsd/libmdnsd/1035.c vendored Normal file
View File

@ -0,0 +1,637 @@
#include "1035.h"
#include <string.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1900
__inline int msnds_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int msnds_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = msnds_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#else
#define msnds_snprintf snprintf
#endif
uint16_t net2short(const unsigned char **bufp)
{
unsigned short int i;
memcpy(&i, *bufp, sizeof(short int));
*bufp += 2;
return ntohs(i);
}
uint32_t net2long(const unsigned char **bufp)
{
uint32_t l;
memcpy(&l, *bufp, sizeof(uint32_t));
*bufp += 4;
return ntohl(l);
}
void short2net(uint16_t i, unsigned char **bufp)
{
uint16_t x = htons(i);
memcpy(*bufp, &x, sizeof(uint16_t));
*bufp += 2;
}
void long2net(uint32_t l, unsigned char **bufp)
{
uint32_t x = htonl(l);
memcpy(*bufp, &x, sizeof(uint32_t));
*bufp += 4;
}
static unsigned short int _ldecomp(const unsigned char *ptr)
{
unsigned short int i;
i = (unsigned short int)(0xc0 ^ ptr[0]);
i = (unsigned short int)(i<<8);
i = (unsigned short int)(i | ptr[1]);
return i;
}
static bool _label(struct message *m, const unsigned char **bufp, const unsigned char *bufEnd, char **namep)
{
int x;
const unsigned char *label;
char *name;
/* Set namep to the end of the block */
*namep = name = (char *)m->_packet + m->_len;
if (*bufp >= bufEnd)
return false;
// forward buffer pointer until we find the first compressed label
bool moveBufp = true;
/* Loop storing label in the block */
do {
if (moveBufp) {
label = *bufp;
}
if (label >= bufEnd) {
break;
}
/* Since every domain name ends with the null label of
the root, a domain name is terminated by a length byte of zero. */
if (*label == 0) {
if (moveBufp) {
*bufp += 1;
}
break;
}
/* Skip past any compression pointers, kick out if end encountered (bad data prolly) */
/* If a label is compressed, it has following structure of 2 bytes:
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 1 1| OFFSET |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* The OFFSET field specifies an offset from
* the start of the message (i.e., the first octet of the ID field in the
* domain header). A zero offset specifies the first byte of the ID field,
* etc.
**/
if (*label & 0xc0) {
if (label + 2 > bufEnd)
return false;
unsigned short int offset = _ldecomp(label);
if (offset > m->_len)
return false;
if (m->_buf + offset >= bufEnd)
return false;
label = m->_buf + offset;
// chek if label is again pointer, then abort.
if (*label & 0xc0)
return false;
moveBufp = false;
*bufp += 2;
}
/* Make sure we're not over the limits
* See https://tools.ietf.org/html/rfc1035
* 2.3.4. Size limits
* */
const unsigned char labelLen = (unsigned char)*label;
if (labelLen > 63)
// maximum label length is 63 octets
return false;
long nameLen = (name + labelLen) - *namep;
if (nameLen > 255)
// maximum names length is 255 octets
return false;
if (label + 1 + labelLen > bufEnd) {
return false;
}
if ((unsigned char*)name + labelLen > m->_packet + MAX_PACKET_LEN) {
return false;
}
/* Copy chars for this label */
memcpy(name, label + 1, labelLen);
name[labelLen] = '.';
name += labelLen + 1;
if (moveBufp) {
*bufp += labelLen + 1;
}
else {
label += labelLen +1;
}
} while (*bufp <= bufEnd);
if ((unsigned char*)name >= m->_packet + MAX_PACKET_LEN) {
return false;
}
/* Terminate name and check for cache or cache it */
*name = '\0';
for (x = 0; x < MAX_NUM_LABELS && m->_labels[x]; x++) {
if (strcmp(*namep, m->_labels[x]))
continue;
*namep = m->_labels[x];
return true;
}
/* No cache, so cache it if room */
if (x < MAX_NUM_LABELS && m->_labels[x] == 0) {
m->_labels[x] = *namep;
}
m->_len += (unsigned long)((name - *namep) + 1);
return true;
}
/* Internal label matching */
static int _lmatch(struct message *m, const char *l1, const char *l2)
{
int len;
/* Always ensure we get called w/o a pointer */
if (*l1 & 0xc0)
return _lmatch(m, (char*)m->_buf + _ldecomp((const unsigned char*)l1), l2);
if (*l2 & 0xc0)
return _lmatch(m, l1, (char*)m->_buf + _ldecomp((const unsigned char*) l2));
/* Same already? */
if (l1 == l2)
return 1;
/* Compare all label characters */
if (*l1 != *l2)
return 0;
for (len = 1; len <= *l1; len++) {
if (l1[len] != l2[len])
return 0;
}
/* Get new labels */
l1 += *l1 + 1;
l2 += *l2 + 1;
/* At the end, all matched */
if (*l1 == 0 && *l2 == 0)
return 1;
/* Try next labels */
return _lmatch(m, l1, l2);
}
/* Nasty, convert host into label using compression */
static int _host(struct message *m, unsigned char **bufp, char *name)
{
char label[256], *l;
int len = 0, x = 1, y = 0, last = 0;
if (name == 0)
return 0;
/* Make our label */
while (name[y]) {
if (name[y] == '.') {
if (!name[y + 1])
break;
label[last] = (char)(x - (last + 1));
last = x;
} else {
label[x] = name[y];
}
if (x++ == 255)
return 0;
y++;
}
label[last] = (char)(x - (last + 1));
if (x == 1)
x--; /* Special case, bad names, but handle correctly */
len = x + 1;
label[x] = 0; /* Always terminate w/ a 0 */
/* Double-loop checking each label against all m->_labels for match */
for (x = 0; label[x]; x += label[x] + 1) {
for (y = 0; y < MAX_NUM_LABELS && m->_labels[y]; y++) {
if (_lmatch(m, label + x, m->_labels[y])) {
/* Matching label, set up pointer */
l = label + x;
short2net((unsigned short)((unsigned char *)m->_labels[y] - m->_packet), (unsigned char **)&l);
label[x] = (char)(label[x] | 0xc0);
len = x + 2;
break;
}
}
if (label[x] & 0xc0)
break;
}
/* Copy into buffer, point there now */
memcpy(*bufp, label, (size_t)len);
l = (char *)*bufp;
*bufp += len;
/* For each new label, store it's location for future compression */
for (x = 0; l[x] && m->_label < MAX_NUM_LABELS; x += l[x] + 1) {
if (l[x] & 0xc0)
break;
m->_labels[m->_label++] = l + x;
}
return len;
}
static bool _rrparse(struct message *m, struct resource *rr, int count, const unsigned char **bufp, const unsigned char* bufferEnd)
{
int i;
const unsigned char *addr_bytes = NULL;
if (count == 0) {
return true;
}
if (*bufp >= m->_bufEnd) {
return false;
}
for (i = 0; i < count; i++) {
if (*bufp >= bufferEnd) {
return false;
}
if (!_label(m, bufp, bufferEnd, &(rr[i].name))) {
return false;
}
if (*bufp + 10 > bufferEnd) {
return false;
}
rr[i].type = net2short(bufp);
rr[i].clazz = net2short(bufp);
rr[i].ttl = net2long(bufp);
rr[i].rdlength = net2short(bufp);
// fprintf(stderr, "Record type %d class 0x%2x ttl %lu len %d\n", rr[i].type, rr[i].clazz, rr[i].ttl, rr[i].rdlength);
/* For the following records the rdata will be parsed later. So don't set it here:
* NS, CNAME, PTR, DNAME, SOA, MX, AFSDB, RT, KX, RP, PX, SRV, NSEC
* See 18.14 of https://tools.ietf.org/html/rfc6762#page-47 */
if (rr[i].type == QTYPE_NS || rr[i].type == QTYPE_CNAME || rr[i].type == QTYPE_PTR || rr[i].type == QTYPE_SRV) {
rr[i].rdlength = 0;
} else {
/* If not going to overflow, make copy of source rdata */
if (*bufp + rr[i].rdlength > bufferEnd) {
return false;
}
if (m->_len + rr[i].rdlength > MAX_PACKET_LEN) {
return false;
}
rr[i].rdata = m->_packet + m->_len;
m->_len += rr[i].rdlength;
memcpy(rr[i].rdata, *bufp, rr[i].rdlength);
}
/* Parse commonly known ones */
switch (rr[i].type) {
case QTYPE_A:
if (m->_len + 16 > MAX_PACKET_LEN) {
return false;
}
rr[i].known.a.name = (char *)m->_packet + m->_len;
m->_len += 16;
if (*bufp + 4 > bufferEnd) {
return false;
}
msnds_snprintf(rr[i].known.a.name,16, "%d.%d.%d.%d", (*bufp)[0], (*bufp)[1], (*bufp)[2], (*bufp)[3]);
addr_bytes = (const unsigned char *) *bufp;
rr[i].known.a.ip.s_addr = (in_addr_t) (
((in_addr_t) addr_bytes[0]) |
(((in_addr_t) addr_bytes[1]) << 8) |
(((in_addr_t) addr_bytes[2]) << 16) |
(((in_addr_t) addr_bytes[3]) << 24));
*bufp += 4;
break;
case QTYPE_NS:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.ns.name))) {
return false;
}
break;
case QTYPE_CNAME:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.cname.name))) {
return false;
}
break;
case QTYPE_PTR:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.ptr.name))) {
return false;
}
break;
case QTYPE_SRV:
if (*bufp + 6 > bufferEnd) {
return false;
}
rr[i].known.srv.priority = net2short(bufp);
rr[i].known.srv.weight = net2short(bufp);
rr[i].known.srv.port = net2short(bufp);
if (!_label(m, bufp, bufferEnd, &(rr[i].known.srv.name))) {
return false;
}
break;
case QTYPE_TXT:
default:
*bufp += rr[i].rdlength;
}
}
return true;
}
/* Keep all our mem in one (aligned) block for easy freeing */
#define my(x,y, cast) \
while (m->_len & 7) \
m->_len++; \
\
if (m->_len + y > MAX_PACKET_LEN) { return false; } \
x = (cast)(void *)(m->_packet + m->_len); \
m->_len += y;
bool message_parse(struct message *m, unsigned char *packet, size_t packetLen)
{
int i;
const unsigned char *buf;
m->_bufEnd = packet + packetLen;
/* Message format: https://tools.ietf.org/html/rfc1035
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
*/
if (packet == 0 || m == 0)
return false;
/* See https://tools.ietf.org/html/rfc1035
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
/* The header always needs to be present. Size = 12 byte */
if (packetLen < 12)
return false;
/* Header stuff bit crap */
buf = m->_buf = packet;
m->id = net2short(&buf);
if (buf[0] & 0x80)
m->header.qr = 1;
m->header.opcode = (unsigned short)(((buf[0] & 0x78) >> 3) & 15);
if (buf[0] & 0x04)
m->header.aa = 1;
if (buf[0] & 0x02)
m->header.tc = 1;
if (buf[0] & 0x01)
m->header.rd = 1;
if (buf[1] & 0x80)
m->header.ra = 1;
m->header.z = (unsigned short)(((buf[1] & 0x70) >> 4) & 7);
m->header.rcode = (unsigned short)(buf[1] & 0x0F);
buf += 2;
m->qdcount = net2short(&buf);
m->ancount = net2short(&buf);
m->nscount = net2short(&buf);
m->arcount = net2short(&buf);
// check if the message has the correct size, i.e. the count matches the number of bytes
/* Process questions */
my(m->qd, (sizeof(struct question) * m->qdcount), struct question *);
for (i = 0; i < m->qdcount; i++) {
if (!_label(m, &buf, m->_bufEnd, &(m->qd[i].name))) {
return false;
}
if (buf + 4 > m->_bufEnd) {
return false;
}
m->qd[i].type = net2short(&buf);
m->qd[i].clazz = net2short(&buf);
}
if (buf > m->_bufEnd) {
return false;
}
/* Process rrs */
my(m->an, (sizeof(struct resource) * m->ancount), struct resource *);
my(m->ns, (sizeof(struct resource) * m->nscount), struct resource *);
my(m->ar, (sizeof(struct resource) * m->arcount), struct resource *);
if (!_rrparse(m, m->an, m->ancount, &buf, m->_bufEnd))
return false;
if (!_rrparse(m, m->ns, m->nscount, &buf, m->_bufEnd))
return false;
if (!_rrparse(m, m->ar, m->arcount, &buf, m->_bufEnd))
return false;
return true;
}
void message_qd(struct message *m, char *name, unsigned short int type, unsigned short int clazz)
{
m->qdcount++;
if (m->_buf == 0) {
m->_buf = m->_packet + 12;
m->_bufEnd = m->_packet + sizeof(m->_packet);
}
_host(m, &(m->_buf), name);
short2net(type, &(m->_buf));
short2net(clazz, &(m->_buf));
}
static void _rrappend(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
if (m->_buf == 0) {
m->_buf = m->_packet + 12;
m->_bufEnd = m->_packet + sizeof(m->_packet);
}
_host(m, &(m->_buf), name);
short2net(type, &(m->_buf));
short2net(clazz, &(m->_buf));
long2net((uint32_t)ttl, &(m->_buf));
}
void message_an(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->ancount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_ns(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->nscount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_ar(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->arcount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_rdata_long(struct message *m, struct in_addr l)
{
short2net(4, &(m->_buf));
long2net(l.s_addr, &(m->_buf));
}
void message_rdata_name(struct message *m, char *name)
{
unsigned char *mybuf = m->_buf;
m->_buf += 2;
short2net((unsigned short)_host(m, &(m->_buf), name), &mybuf);
}
void message_rdata_srv(struct message *m, unsigned short int priority, unsigned short int weight, unsigned short int port, char *name)
{
unsigned char *mybuf = m->_buf;
m->_buf += 2;
short2net(priority, &(m->_buf));
short2net(weight, &(m->_buf));
short2net(port, &(m->_buf));
short2net((unsigned short)(_host(m, &(m->_buf), name) + 6), &mybuf);
}
void message_rdata_raw(struct message *m, unsigned char *rdata, unsigned short int rdlength)
{
if (((unsigned char *)m->_buf - m->_packet) + rdlength > 4096)
rdlength = 0;
short2net(rdlength, &(m->_buf));
memcpy(m->_buf, rdata, rdlength);
m->_buf += rdlength;
}
unsigned char *message_packet(struct message *m)
{
unsigned char c, *buf = m->_buf, *bufEnd = m->_bufEnd;
m->_buf = m->_packet;
m->_bufEnd = m->_packet + sizeof(m->_packet);
short2net(m->id, &(m->_buf));
if (m->header.qr)
m->_buf[0] |= 0x80;
if ((c = (unsigned char)m->header.opcode))
m->_buf[0] |= (unsigned char)(c << 3);
if (m->header.aa)
m->_buf[0] |= 0x04;
if (m->header.tc)
m->_buf[0] |= 0x02;
if (m->header.rd)
m->_buf[0] |= 0x01;
if (m->header.ra)
m->_buf[1] |= 0x80;
if ((c = (unsigned char)m->header.z))
m->_buf[1] |= (unsigned char)(c << 4);
if (m->header.rcode)
m->_buf[1] = (unsigned char)(m->_buf[1] | m->header.rcode);
m->_buf += 2;
short2net(m->qdcount, &(m->_buf));
short2net(m->ancount, &(m->_buf));
short2net(m->nscount, &(m->_buf));
short2net(m->arcount, &(m->_buf));
m->_buf = buf; /* Restore, so packet_len works */
m->_bufEnd = bufEnd;
return m->_packet;
}
int message_packet_len(struct message *m)
{
if (m->_buf == 0)
return 12;
return (int)((unsigned char *)m->_buf - m->_packet);
}

188
deps/mdnsd/libmdnsd/1035.h vendored Normal file
View File

@ -0,0 +1,188 @@
/* Familiarize yourself with RFC1035 if you want to know what all the
* variable names mean. This file hides most of the dirty work all of
* this code depends on the buffer space a packet is in being 4096 and
* zero'd before the packet is copied in also conveniently decodes srv
* rr's, type 33, see RFC2782
*/
#ifndef MDNS_1035_H_
#define MDNS_1035_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
#ifdef _WIN32
/* Backup definition of SLIST_ENTRY on mingw winnt.h */
#ifdef SLIST_ENTRY
# pragma push_macro("SLIST_ENTRY")
# undef SLIST_ENTRY
# define POP_SLIST_ENTRY
#endif
/* winnt.h redefines SLIST_ENTRY */
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* inet_ntoa is deprecated on MSVC but used for compatibility */
# include <winsock2.h>
# include <ws2tcpip.h>
#ifndef in_addr_t
#define in_addr_t unsigned __int32
#endif
/* restore definition */
#ifdef POP_SLIST_ENTRY
# undef SLIST_ENTRY
# undef POP_SLIST_ENTRY
# pragma pop_macro("SLIST_ENTRY")
#endif
#else
# include <arpa/inet.h>
#endif
#if !defined(__bool_true_false_are_defined) && defined(_MSC_VER) && _MSC_VER < 1600
// VS 2008 has no stdbool.h
#define bool short
#define true 1
#define false 0
#else
#include <stdbool.h>
#endif
#ifdef _MSC_VER
#include "ms_stdint.h" /* Includes stdint.h or workaround for older Visual Studios */
#else
#include <stdint.h>
#endif
/* Should be reasonably large, for UDP */
#define MAX_PACKET_LEN 10000
#define MAX_NUM_LABELS 20
struct question {
char *name;
unsigned short type, clazz;
};
#define QTYPE_A 1
#define QTYPE_NS 2
#define QTYPE_CNAME 5
#define QTYPE_PTR 12
#define QTYPE_TXT 16
#define QTYPE_SRV 33
struct resource {
char *name;
unsigned short type, clazz;
unsigned long int ttl;
unsigned short int rdlength;
unsigned char *rdata;
union {
struct {
struct in_addr ip;
//cppcheck-suppress unusedStructMember
char *name;
} a;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} ns;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} cname;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} ptr;
struct {
//cppcheck-suppress unusedStructMember
unsigned short int priority, weight, port;
//cppcheck-suppress unusedStructMember
char *name;
} srv;
} known;
};
struct message {
/* External data */
unsigned short int id;
struct {
//it would be better to use unsigned short, but gcc < 5 complaints when using pedantic
//cppcheck-suppress unusedStructMember
unsigned int qr:1, opcode:4, aa:1, tc:1, rd:1, ra:1, z:3, rcode:4;
} header;
unsigned short int qdcount, ancount, nscount, arcount;
struct question *qd;
struct resource *an, *ns, *ar;
/* Internal variables */
unsigned char *_buf;
unsigned char *_bufEnd;
char *_labels[MAX_NUM_LABELS];
size_t _len;
int _label;
/* Packet acts as padding, easier mem management */
unsigned char _packet[MAX_PACKET_LEN];
};
/**
* Returns the next short/long off the buffer (and advances it)
*/
uint16_t net2short(const unsigned char **bufp);
uint32_t net2long (const unsigned char **bufp);
/**
* copies the short/long into the buffer (and advances it)
*/
void MDNSD_EXPORT short2net(uint16_t i, unsigned char **bufp);
void MDNSD_EXPORT long2net (uint32_t l, unsigned char **bufp);
/**
* parse packet into message, packet must be at least MAX_PACKET_LEN and
* message must be zero'd for safety
*/
bool MDNSD_EXPORT message_parse(struct message *m, unsigned char *packet, size_t packetLen);
/**
* create a message for sending out on the wire
*/
struct message *message_wire(void);
/**
* append a question to the wire message
*/
void MDNSD_EXPORT message_qd(struct message *m, char *name, unsigned short int type, unsigned short int clazz);
/**
* append a resource record to the message, all called in order!
*/
void MDNSD_EXPORT message_an(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
void MDNSD_EXPORT message_ns(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
void MDNSD_EXPORT message_ar(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
/**
* Append various special types of resource data blocks
*/
void MDNSD_EXPORT message_rdata_long (struct message *m, struct in_addr l);
void MDNSD_EXPORT message_rdata_name (struct message *m, char *name);
void MDNSD_EXPORT message_rdata_srv (struct message *m, unsigned short int priority, unsigned short int weight,
unsigned short int port, char *name);
void MDNSD_EXPORT message_rdata_raw (struct message *m, unsigned char *rdata, unsigned short int rdlength);
/**
* Return the wire format (and length) of the message, just free message
* when done
*/
unsigned char MDNSD_EXPORT * message_packet (struct message *m);
int MDNSD_EXPORT message_packet_len (struct message *m);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_1035_H_ */

120
deps/mdnsd/libmdnsd/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,120 @@
cmake_minimum_required(VERSION 2.8)
project(libmdnsd C)
include(GenerateExportHeader)
set(MDNSD_LOGLEVEL 300 CACHE STRING "Level at which logs shall be reported")
# Force compilation with as C++
option(MDNSD_COMPILE_AS_CXX "Force compilation with a C++ compiler" OFF)
mark_as_advanced(MDNSD_COMPILE_AS_CXX)
option(CMAKE_POSITION_INDEPENDENT_CODE "Build mdnsd using -fPIC" ON)
if(NOT MDNSD_COMPILE_AS_CXX AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang"))
add_definitions(-std=c99 -pipe
-Wall -Wextra -Werror
-Wno-unused-parameter # some methods may require unused arguments to cast to a method pointer
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
-Wformat -Wformat-security -Wformat-nonliteral
-Wuninitialized -Winit-self
-Wcast-qual -Wcast-align
-Wstrict-overflow
-Wnested-externs
-Wmultichar
-Wundef
-Wc++-compat)
if(NOT MINGW AND NOT MSYS AND NOT MSVC)
add_definitions(-Wpedantic)
endif()
if(NOT WIN32 AND NOT CYGWIN)
add_definitions(-Wshadow -Wconversion)
endif()
endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
option(MDNSD_ENABLE_COVERAGE "Enable gcov coverage" OFF)
if(MDNSD_ENABLE_COVERAGE)
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
# Building shared libs (dll, so)
set(MDNSD_DYNAMIC_LINKING OFF)
if(BUILD_SHARED_LIBS)
set(MDNSD_DYNAMIC_LINKING ON)
endif()
configure_file("mdnsd_config_extra.in" "${PROJECT_BINARY_DIR}/mdnsd_config_extra")
include_directories(${PROJECT_BINARY_DIR})
set(PUBLIC_INCLUDES mdnsd.h 1035.h sdtxt.h xht.h "${PROJECT_BINARY_DIR}/mdnsd_config.h")
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
list(APPEND PUBLIC_INCLUDES ms_stdint.h)
endif()
set(LIBRARY_FILES mdnsd.c 1035.c xht.c sdtxt.c)
if (MDNSD_BUILD_FUZZING_CORPUS)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_definitions(-DMDNSD_CORPUS_OUTPUT_DIR="${PROJECT_BINARY_DIR}/corpus/custom")
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/corpus/custom)
list(APPEND LIBRARY_FILES mdnsd_debug_dump_pkgs_file.c)
endif()
if(MDNSD_COMPILE_AS_CXX)
set_source_files_properties(${LIBRARY_FILES} PROPERTIES LANGUAGE CXX)
enable_language(CXX)
endif()
add_library(libmdnsd ${LIBRARY_FILES} ${PUBLIC_INCLUDES})
target_include_directories(libmdnsd PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/..>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
set_target_properties(libmdnsd PROPERTIES
OUTPUT_NAME "mdnsd"
DEFINE_SYMBOL "MDNSD_DYNAMIC_LINKING_EXPORT"
)
target_compile_definitions(libmdnsd PUBLIC
$<$<STREQUAL:$<TARGET_PROPERTY:libmdnsd,TYPE>,STATIC_LIBRARY>:MDNSD_STATIC_DEFINE>
)
file(READ "${PROJECT_BINARY_DIR}/mdnsd_config_extra" MDNSD_CONFIG_EXTRA)
generate_export_header(libmdnsd
EXPORT_FILE_NAME "${PROJECT_BINARY_DIR}/mdnsd_config.h"
BASE_NAME MDNSD
DEFINE_NO_DEPRECATED
CUSTOM_CONTENT_FROM_VARIABLE MDNSD_CONFIG_EXTRA
)
if(WIN32)
target_link_libraries(libmdnsd PUBLIC wsock32 ws2_32)
endif()
install(
TARGETS libmdnsd
EXPORT mdnsd
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
install(
FILES ${PUBLIC_INCLUDES}
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}"
)
install(
FILES ${PROJECT_BINARY_DIR}/mdnsd_config.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}"
)

1277
deps/mdnsd/libmdnsd/mdnsd.c vendored Normal file

File diff suppressed because it is too large Load Diff

234
deps/mdnsd/libmdnsd/mdnsd.h vendored Normal file
View File

@ -0,0 +1,234 @@
#ifndef MDNSD_H_
#define MDNSD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
#include "1035.h"
#if !defined(__bool_true_false_are_defined) && defined(_MSC_VER) && _MSC_VER < 1600
// VS 2008 has no stdbool.h
#define bool short
#define true 1
#define false 0
#else
#include <stdbool.h>
#endif
#include <stdio.h>
#define QCLASS_IN (1)
#if MDNSD_LOGLEVEL <= 100
#define MDNSD_LOG_TRACE(...) do { \
printf("mdnsd: TRACE - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_TRACE(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 200
#define MDNSD_LOG_DEBUG(...) do { \
printf("mdnsd: DEBUG - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_DEBUG(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 300
#define MDNSD_LOG_INFO(...) do { \
printf("mdnsd: INFO - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_INFO(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 400
#define MDNSD_LOG_WARNING(...) do { \
printf("mdnsd: WARN - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_WARNING(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 500
#define MDNSD_LOG_ERROR(...) do { \
printf("mdnsd: ERROR - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_ERROR(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 600
#define MDNSD_LOG_FATAL(...) do { \
printf("mdnsd: FATAL - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_FATAL(...) do {} while(0)
#endif
/* Main daemon data */
typedef struct mdns_daemon mdns_daemon_t;
/* Record entry */
typedef struct mdns_record mdns_record_t;
/* Callback for received record. Data is passed from the register call */
typedef void (*mdnsd_record_received_callback)(const struct resource* r, void* data);
/* Answer data */
typedef struct mdns_answer {
char *name;
unsigned short type;
unsigned long ttl;
unsigned short rdlen;
unsigned char *rdata;
struct in_addr ip; /* A */
char *rdname; /* NS/CNAME/PTR/SRV */
struct {
//cppcheck-suppress unusedStructMember
unsigned short int priority, weight, port;
} srv; /* SRV */
} mdns_answer_t;
/**
* Global functions
*/
/**
* Create a new mdns daemon for the given class of names (usually 1) and
* maximum frame size
*/
mdns_daemon_t MDNSD_EXPORT * mdnsd_new(int clazz, int frame);
/**
* Gracefully shutdown the daemon, use mdnsd_out() to get the last
* packets
*/
void MDNSD_EXPORT mdnsd_shutdown(mdns_daemon_t *d);
/**
* Flush all cached records (network/interface changed)
*/
void MDNSD_EXPORT mdnsd_flush(mdns_daemon_t *d);
/**
* Free given mdns_daemon_t *(should have used mdnsd_shutdown() first!)
*/
void MDNSD_EXPORT mdnsd_free(mdns_daemon_t *d);
/**
* Register callback which is called when a record is received. The data parameter is passed to the callback.
* Calling this multiple times overwrites the previous register.
*/
void MDNSD_EXPORT mdnsd_register_receive_callback(mdns_daemon_t *d, mdnsd_record_received_callback cb, void* data);
/**
* I/O functions
*/
/**
* Oncoming message from host (to be cached/processed)
*/
int MDNSD_EXPORT mdnsd_in(mdns_daemon_t *d, struct message *m, in_addr_t ip, unsigned short int port);
/**
* Outgoing messge to be delivered to host, returns >0 if one was
* returned and m/ip/port set
*/
int MDNSD_EXPORT mdnsd_out(mdns_daemon_t *d, struct message *m, struct in_addr *ip, unsigned short int *port);
/**
* returns the max wait-time until mdnsd_out() needs to be called again
*/
struct timeval MDNSD_EXPORT * mdnsd_sleep(mdns_daemon_t *d);
/**
* Q/A functions
*/
/**
* Register a new query
*
* The answer() callback is called whenever one is found/changes/expires
* (immediate or anytime after, mdns_answer_t valid until ->ttl==0)
* either answer returns -1, or another mdnsd_query() with a %NULL answer
* will remove/unregister this query
*/
void MDNSD_EXPORT mdnsd_query(mdns_daemon_t *d, const char *host, int type, int (*answer)(mdns_answer_t *a, void *arg), void *arg);
/**
* Returns the first (if last == NULL) or next answer after last from
* the cache mdns_answer_t only valid until an I/O function is called
*/
mdns_answer_t MDNSD_EXPORT *mdnsd_list(mdns_daemon_t *d, const char *host, int type, mdns_answer_t *last);
/**
* Returns the next record of the given record, i.e. the value of next field.
* @param r the base record
* @return r->next
*/
mdns_record_t MDNSD_EXPORT *mdnsd_record_next(const mdns_record_t* r) ;
/**
* Gets the record data
*/
const mdns_answer_t MDNSD_EXPORT *mdnsd_record_data(const mdns_record_t* r) ;
/**
* Publishing functions
*/
/**
* Create a new unique record
*
* Call mdnsd_list() first to make sure the record is not used yet.
*
* The conflict() callback is called at any point when one is detected
* and unable to recover after the first data is set_*(), any future
* changes effectively expire the old one and attempt to create a new
* unique record
*/
mdns_record_t MDNSD_EXPORT * mdnsd_unique(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl, void (*conflict)(char *host, int type, void *arg), void *arg);
/**
* Create a new shared record
*/
mdns_record_t MDNSD_EXPORT * mdnsd_shared(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl);
/**
* Get a previously created record based on the host name. NULL if not found. Does not return records for other hosts.
* If multiple records are found, use record->next to iterate over all the results.
*/
mdns_record_t MDNSD_EXPORT * mdnsd_get_published(const mdns_daemon_t *d, const char *host);
/**
* Check if there is already a query for the given host
*/
int MDNSD_EXPORT mdnsd_has_query(const mdns_daemon_t *d, const char *host);
/**
* de-list the given record
*/
void MDNSD_EXPORT mdnsd_done(mdns_daemon_t *d, mdns_record_t *r);
/**
* These all set/update the data for the given record, nothing is
* published until they are called
*/
void MDNSD_EXPORT mdnsd_set_raw(mdns_daemon_t *d, mdns_record_t *r, const char *data, unsigned short int len);
void MDNSD_EXPORT mdnsd_set_host(mdns_daemon_t *d, mdns_record_t *r, const char *name);
void MDNSD_EXPORT mdnsd_set_ip(mdns_daemon_t *d, mdns_record_t *r, struct in_addr ip);
void MDNSD_EXPORT mdnsd_set_srv(mdns_daemon_t *d, mdns_record_t *r, unsigned short int priority, unsigned short int weight, unsigned short int port, char *name);
/**
* Process input queue and output queue. Should be called at least the time which is returned in nextSleep.
* Returns 0 on success, 1 on read error, 2 on write error
*/
unsigned short int MDNSD_EXPORT mdnsd_step(mdns_daemon_t *d, int mdns_socket, bool processIn, bool processOut, struct timeval *nextSleep);
#ifdef MDNSD_DEBUG_DUMP_PKGS_FILE
void mdnsd_debug_dumpCompleteChunk(mdns_daemon_t *d, const char* data, size_t len);
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNSD_H_ */

View File

@ -0,0 +1,27 @@
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 500
#endif
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
#endif
#if defined __APPLE__
// required for ip_mreq
#define _DARWIN_C_SOURCE 1
#endif
#define MDNSD_free(ptr) free(ptr)
#define MDNSD_malloc(size) malloc(size)
#define MDNSD_calloc(num, size) calloc(num, size)
#define MDNSD_realloc(ptr, size) realloc(ptr, size)
#define MDNSD_LOGLEVEL ${MDNSD_LOGLEVEL}
/**
* Inline Functions
* ---------------- */
#ifdef _MSC_VER
# define MDNSD_INLINE __inline
#else
# define MDNSD_INLINE inline
#endif

View File

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This code is used to generate a binary file for every request type
* which can be sent from a client to the server.
* These files form the basic corpus for fuzzing the server.
*/
#ifndef MDNSD_DEBUG_DUMP_PKGS_FILE
#error MDNSD_DEBUG_DUMP_PKGS_FILE must be defined
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "mdnsd.h"
unsigned int mdnsd_dump_chunkCount = 0;
void mdnsd_debug_dumpCompleteChunk(mdns_daemon_t *d, const char* data, size_t len) {
char fileName[250];
struct timeval t;
gettimeofday(&t, 0);
snprintf(fileName, sizeof(fileName), "%s/%05u_%ld", MDNSD_CORPUS_OUTPUT_DIR, ++mdnsd_dump_chunkCount, t.tv_sec);
char dumpOutputFile[266];
snprintf(dumpOutputFile, 255, "%s.bin", fileName);
// check if file exists and if yes create a counting filename to avoid overwriting
unsigned cnt = 1;
while ( access( dumpOutputFile, F_OK ) != -1 ) {
snprintf(dumpOutputFile, 266, "%s_%u.bin", fileName, cnt);
cnt++;
}
FILE *write_ptr = fopen(dumpOutputFile, "ab");
fwrite(data, len, 1, write_ptr); // write 10 bytes from our buffer
fclose(write_ptr);
}

257
deps/mdnsd/libmdnsd/ms_stdint.h vendored Normal file
View File

@ -0,0 +1,257 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2013 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the product nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(_MSC_VER) || _MSC_VER >= 1600 // [
#include <stdint.h>
#else
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifndef UNDER_CE
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
#endif // !defined(_MSC_VER) || _MSC_VER >= 1600 ]

93
deps/mdnsd/libmdnsd/sdtxt.c vendored Normal file
View File

@ -0,0 +1,93 @@
#include "sdtxt.h"
#include <stdlib.h>
#include <string.h>
static size_t _sd2txt_len(const char *key, char *val)
{
size_t ret = strlen(key);
if (!*val)
return ret;
ret += strlen(val);
ret++;
return ret;
}
static void _sd2txt_count(xht_t *h, char *key, void *val, void *arg)
{
int *count = (int *)arg;
*count += (int)_sd2txt_len(key, (char *)val) + 1;
}
static void _sd2txt_write(xht_t *h, char *key, void *val, void *arg)
{
unsigned char **txtp = (unsigned char **)arg;
char *cval = (char *)val;
/* Copy in lengths, then strings */
**txtp = (unsigned char)_sd2txt_len(key, (char *)val);
(*txtp)++;
memcpy(*txtp, key, strlen(key));
*txtp += strlen(key);
if (!*cval)
return;
**txtp = '=';
(*txtp)++;
memcpy(*txtp, cval, strlen(cval));
*txtp += strlen(cval);
}
unsigned char *sd2txt(xht_t *h, int *len)
{
unsigned char *buf, *raw;
*len = 0;
xht_walk(h, _sd2txt_count, (void *)len);
if (!*len) {
*len = 1;
buf = (unsigned char *)MDNSD_malloc(1);
*buf = 0;
return buf;
}
raw = buf = (unsigned char *)MDNSD_malloc((size_t)(*len));
xht_walk(h, _sd2txt_write, &buf);
return raw;
}
xht_t *txt2sd(const unsigned char *txt, int len)
{
char key[256];
xht_t *h = NULL;
if (txt == 0 || len == 0 || *txt == 0)
return NULL;
h = xht_new(23);
/* Loop through data breaking out each block, storing into hashtable */
for (; len > 0 && *txt <= len; len -= *txt, txt += *txt + 1) {
char* val;
if (*txt == 0)
break;
memcpy(key, txt + 1, *txt);
key[*txt] = 0;
if ((val = strchr(key, '=')) != 0) {
*val = 0;
val++;
}
if (val != NULL)
xht_store(h, key, (int)strlen(key), val, (int)strlen(val));
if (*txt +1 > len)
break;
}
return h;
}

24
deps/mdnsd/libmdnsd/sdtxt.h vendored Normal file
View File

@ -0,0 +1,24 @@
#ifndef MDNS_SDTXT_H_
#define MDNS_SDTXT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xht.h"
/**
* returns hashtable of strings from the SD TXT record rdata
*/
xht_t MDNSD_EXPORT *txt2sd(const unsigned char *txt, int len);
/**
* returns a raw block that can be sent with a SD TXT record, sets length
*/
unsigned char MDNSD_EXPORT *sd2txt(xht_t *h, int *len);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_SDTXT_H_ */

182
deps/mdnsd/libmdnsd/xht.c vendored Normal file
View File

@ -0,0 +1,182 @@
#include "xht.h"
#include <string.h>
#include <stdlib.h>
typedef struct xhn {
char flag;
struct xhn *next;
char *key;
void *val;
} xhn_t;
struct xht {
int prime;
xhn_t *zen;
};
/* Generates a hash code for a string.
* This function uses the ELF hashing algorithm as reprinted in
* Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
*/
static int _xhter(const char *s)
{
/* ELF hash uses unsigned chars and unsigned arithmetic for portability */
const unsigned char *name = (const unsigned char *)s;
unsigned long int h = 0;
while (*name) { /* do some fancy bitwanking on the string */
unsigned long int g;
h = (h << 4) + (unsigned long int)(*name++);
if ((g = (h & 0xF0000000UL)) != 0)
h ^= (g >> 24);
h &= ~g;
}
return (int)h;
}
static xhn_t *_xht_node_find(xhn_t *n, const char *key)
{
for (; n != 0; n = n->next)
if (n->key != 0 && strcmp(key, n->key) == 0)
return n;
return 0;
}
xht_t *xht_new(int prime)
{
xht_t *xnew;
xnew = (xht_t *)MDNSD_malloc(sizeof(struct xht));
xnew->prime = prime;
xnew->zen = (xhn_t *)MDNSD_calloc(1, (sizeof(struct xhn) * (size_t)prime)); /* array of xhn_t size of prime */
return xnew;
}
/* does the set work, used by xht_set and xht_store */
static xhn_t *_xht_set(xht_t *h, char *key, void *val, char flag)
{
int i;
xhn_t *n;
/* get our index for this key */
i = _xhter(key) % h->prime;
/* check for existing key first, or find an empty one */
if ((n = _xht_node_find(&h->zen[i], key)) == 0) {
for (n = &h->zen[i]; n != 0; n = n->next) {
if (n->val == 0)
break;
}
}
/* if none, make a new one, link into this index */
if (n == NULL) {
if (h->zen != NULL) {
n = (xhn_t *)MDNSD_malloc(sizeof(struct xhn));
n->next = NULL;
n->next = h->zen[i].next;
h->zen[i].next = n;
}
} else if (n->flag) {
/* When flag is set, we manage their mem and free em first */
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
if (n != NULL) {
n->flag = flag;
n->key = key;
n->val = val;
} else {
MDNSD_free(key);
MDNSD_free(val);
}
return n;
}
void xht_set(xht_t *h, char *key, void *val)
{
if (h == 0 || key == 0)
return;
_xht_set(h, key, val, 0);
}
void xht_store(xht_t *h, char *key, int klen, void *val, int vlen)
{
char *ckey, *cval;
if (h == 0 || key == 0 || klen == 0)
return;
ckey = (char *)MDNSD_malloc((size_t)klen + 1);
memcpy(ckey, key, (size_t)klen);
ckey[klen] = '\0';
cval = (char *)MDNSD_malloc((size_t)vlen + 1);
memcpy(cval, val, (size_t)vlen);
cval[vlen] = '\0'; /* convenience, in case it was a string too */
_xht_set(h, ckey, cval, 1);
}
void *xht_get(xht_t *h, char *key)
{
xhn_t *n;
if (h == 0 || key == 0 || (n = _xht_node_find(&h->zen[_xhter(key) % h->prime], key)) == 0)
return 0;
return n->val;
}
void xht_free(xht_t *h)
{
int i;
xhn_t *n, *f;
if (h == 0)
return;
for (i = 0; i < h->prime; i++) {
if ((n = (&h->zen[i])) == NULL)
continue;
if (n->flag) {
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
for (n = (&h->zen[i])->next; n != 0;) {
f = n->next;
if (n->flag) {
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
MDNSD_free(n);
n = f;
}
}
MDNSD_free(h->zen);
MDNSD_free(h);
}
void xht_walk(xht_t *h, xht_walker w, void *arg)
{
int i;
xhn_t *n;
if (h == 0 || w == 0)
return;
for (i = 0; i < h->prime; i++) {
for (n = &h->zen[i]; n != 0; n = n->next) {
if (n->key != 0 && n->val != 0)
(*w)(h, n->key, n->val, arg);
}
}
}

53
deps/mdnsd/libmdnsd/xht.h vendored Normal file
View File

@ -0,0 +1,53 @@
/* Simple string->void* hashtable, very static and bare minimal, but efficient */
#ifndef MDNS_XHT_H_
#define MDNS_XHT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
typedef struct xht xht_t;
/**
* must pass a prime#
*/
xht_t MDNSD_EXPORT *xht_new(int prime);
/**
* caller responsible for key storage, no copies made
*
* set val to NULL to clear an entry, memory is reused but never free'd
* (# of keys only grows to peak usage)
*
* Note: don't free it b4 xht_free()!
*/
void MDNSD_EXPORT xht_set(xht_t *h, char *key, void *val);
/**
* Unlike xht_set() where key/val is in caller's mem, here they are
* copied into xht and free'd when val is 0 or xht_free()
*/
void MDNSD_EXPORT xht_store(xht_t *h, char *key, int klen, void *val, int vlen);
/**
* returns value of val if found, or NULL
*/
void MDNSD_EXPORT *xht_get(xht_t *h, char *key);
/**
* free the hashtable and all entries
*/
void MDNSD_EXPORT xht_free(xht_t *h);
/**
* pass a function that is called for every key that has a value set
*/
typedef void (*xht_walker)(xht_t *h, char *key, void *val, void *arg);
void xht_walk(xht_t *h, xht_walker w, void *arg);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_XHT_H_ */

282
deps/mdnsd/mdnsd.c vendored Normal file
View File

@ -0,0 +1,282 @@
#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501)
/* Assume the target is newer than Windows XP */
# undef WINVER
# undef _WIN32_WINDOWS
# undef _WIN32_WINNT
# define WINVER _WIN32_WINNT_VISTA
# define _WIN32_WINDOWS _WIN32_WINNT_VISTA
# define _WIN32_WINNT _WIN32_WINNT_VISTA
#endif
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <sys/types.h>
#ifdef _WIN32
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* inet_ntoa is deprecated on MSVC but used for compatibility */
# include <winsock2.h>
# include <ws2tcpip.h>
static int my_inet_pton(int af, const char *src, void *dst)
{
struct sockaddr_storage ss;
int size = sizeof(ss);
char src_copy[INET6_ADDRSTRLEN+1];
ZeroMemory(&ss, sizeof(ss));
/* stupid non-const API */
strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
src_copy[INET6_ADDRSTRLEN] = 0;
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
switch(af) {
case AF_INET:
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
return 1;
case AF_INET6:
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
return 1;
}
}
return 0;
}
#define INET_PTON my_inet_pton
#else
# include <arpa/inet.h>
# include <netinet/in.h>
# include <sys/select.h>
# include <sys/ioctl.h>
#define INET_PTON inet_pton
#endif
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
# define CLOSESOCKET(S) closesocket((SOCKET)S)
# define ssize_t int
#else
# include <unistd.h> // read, write, close
# define CLOSESOCKET(S) close(S)
#endif
#include <libmdnsd/mdnsd.h>
#include <libmdnsd/sdtxt.h>
int _shutdown = 0;
mdns_daemon_t *_d;
int daemon_socket = 0;
void conflict(char *name, int type, void *arg)
{
printf("conflicting name detected %s for type %d\n", name, type);
exit(1);
}
void record_received(const struct resource* r, void* data) {
#ifndef _WIN32
char ipinput[INET_ADDRSTRLEN];
#endif
switch(r->type) {
case QTYPE_A:
#ifndef _WIN32
inet_ntop(AF_INET, &(r->known.a.ip), ipinput, INET_ADDRSTRLEN);
printf("Got %s: A %s->%s\n", r->name,r->known.a.name, ipinput);
#else
printf("Got %s: A %s\n", r->name,r->known.a.name);
#endif
break;
case QTYPE_NS:
printf("Got %s: NS %s\n", r->name,r->known.ns.name);
break;
case QTYPE_CNAME:
printf("Got %s: CNAME %s\n", r->name,r->known.cname.name);
break;
case QTYPE_PTR:
printf("Got %s: PTR %s\n", r->name,r->known.ptr.name);
break;
case QTYPE_TXT:
printf("Got %s: TXT %s\n", r->name,r->rdata);
break;
case QTYPE_SRV:
printf("Got %s: SRV %d %d %d %s\n", r->name,r->known.srv.priority,r->known.srv.weight,r->known.srv.port,r->known.srv.name);
break;
default:
printf("Got %s: unknown\n", r->name);
}
}
void done(int sig)
{
_shutdown = 1;
mdnsd_shutdown(_d);
// wake up select
if (write(daemon_socket, "\0", 1) == -1) {
printf("Could not write zero byte to socket\n");
}
}
static void socket_set_nonblocking(int sockfd) {
#ifdef _WIN32
u_long iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);
#else
int opts = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, opts|O_NONBLOCK);
#endif
}
/* Create multicast 224.0.0.251:5353 socket */
int msock(void)
{
int s, flag = 1, ittl = 255;
struct sockaddr_in in;
struct ip_mreq mc;
unsigned char ttl = 255; // send to any reachable net, not only the subnet
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
in.sin_port = htons(5353);
in.sin_addr.s_addr = 0;
if ((s = (int)socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 0;
#ifdef SO_REUSEPORT
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
#endif
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
if (bind(s, (struct sockaddr *)&in, sizeof(in))) {
CLOSESOCKET(s);
return 0;
}
mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
mc.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mc, sizeof(mc));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ttl, sizeof(ttl));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ittl, sizeof(ittl));
socket_set_nonblocking(s);
return s;
}
int main(int argc, char *argv[])
{
mdns_daemon_t *d;
mdns_record_t *r;
struct in_addr ip;
unsigned short int port;
fd_set fds;
int s;
char hlocal[256], nlocal[256];
unsigned char *packet;
int len = 0;
xht_t *h;
char *path = NULL;
if (argc < 4) {
printf("usage: mhttp 'unique name' 12.34.56.78 80 '/optionalpath'\n");
return 1;
}
INET_PTON(AF_INET,argv[2], &ip);
port = atoi(argv[3]);
if (argc == 5)
path = argv[4];
printf("Announcing .local site named '%s' to %s:%d and extra path '%s'\n", argv[1], inet_ntoa(ip), port, argv[4]);
signal(SIGINT, done);
#ifdef SIGHUP
signal(SIGHUP, done);
#endif
#ifdef SIGQUIT
signal(SIGQUIT, done);
#endif
signal(SIGTERM, done);
_d = d = mdnsd_new(QCLASS_IN, 1000);
if ((s = msock()) == 0) {
printf("can't create socket: %s\n", strerror(errno));
return 1;
}
mdnsd_register_receive_callback(d, record_received, NULL);
sprintf(hlocal, "%s._http._tcp.local.", argv[1]);
sprintf(nlocal, "http-%s.local.", argv[1]);
// Announce that we have a _http._tcp service
r = mdnsd_shared(d, "_services._dns-sd._udp.local.", QTYPE_PTR, 120);
mdnsd_set_host(d, r, "_http._tcp.local.");
r = mdnsd_shared(d, "_http._tcp.local.", QTYPE_PTR, 120);
mdnsd_set_host(d, r, hlocal);
r = mdnsd_unique(d, hlocal, QTYPE_SRV, 600, conflict, 0);
mdnsd_set_srv(d, r, 0, 0, port, nlocal);
r = mdnsd_unique(d, nlocal, QTYPE_A, 600, conflict, 0);
mdnsd_set_raw(d, r, (char *)&ip.s_addr, 4);
r = mdnsd_unique(d, hlocal, QTYPE_TXT, 600, conflict, 0);
h = xht_new(11);
if (path && strlen(path))
xht_set(h, "path", path);
packet = sd2txt(h, &len);
xht_free(h);
mdnsd_set_raw(d, r, (char *)packet, len);
MDNSD_free(packet);
// example for getting a previously published record:
{
mdns_record_t *get_r = mdnsd_get_published(d, "_http._tcp.local.");
while(get_r) {
const mdns_answer_t *data = mdnsd_record_data(get_r);
printf("Found record of type %d\n", data->type);
get_r = mdnsd_record_next(get_r);
}
}
{
struct timeval next_sleep;
next_sleep.tv_sec = 0;
next_sleep.tv_usec = 0;
while (1) {
FD_ZERO(&fds);
FD_SET(s, &fds);
select(s + 1, &fds, 0, 0, &next_sleep);
if (_shutdown)
break;
{
unsigned short retVal = mdnsd_step(d, s, FD_ISSET(s, &fds), true, &next_sleep);
if (retVal == 1) {
printf("can't read from socket %d: %s\n", errno, strerror(errno));
break;
} else if (retVal == 2) {
printf("can't write to socket: %s\n", strerror(errno));
break;
}
}
if (_shutdown)
break;
}
}
mdnsd_shutdown(d);
mdnsd_free(d);
return 0;
}

3
deps/mdnsd/mdnsdConfig.cmake.in vendored Normal file
View File

@ -0,0 +1,3 @@
include("${CMAKE_CURRENT_LIST_DIR}/mdnsdTargets.cmake")
@PACKAGE_INIT@

3
deps/mdnsd/mdnsd_back/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*~
build/
.vscode/

184
deps/mdnsd/mdnsd_back/.travis.yml vendored Normal file
View File

@ -0,0 +1,184 @@
# using c for language overwrites our compilers
language: c
sudo: false
dist: trusty
matrix:
include:
#
# gcc-4.8 (trusty) full host and cross build with tests:
- os: linux
compiler: gcc-4.8
addons:
apt:
sources:
# see https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
- ubuntu-toolchain-r-test
packages:
- binutils-mingw-w64-i686
- build-essential
- check
- cppcheck
- gcc-multilib
- gcc-4.9
- gcc-mingw-w64-i686
- g++-multilib
- g++-mingw-w64
- libc6-dev-i386
- linux-libc-dev:i386
- mingw-w64
- valgrind
env:
- ANALYZE=false
- MINGW=true
#
# gcc-8 full host build with tests:
- os: linux
compiler: gcc-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-8
- gcc-8-multilib
- check
- cppcheck
- valgrind
env:
- ANALYZE=false
#
# clang-8 full host build with tests:
- os: linux
compiler: clang-8
addons:
apt:
sources:
- llvm-toolchain-trusty-8
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-8
- valgrind
env:
- ANALYZE=false
- os: linux
compiler: clang-6.0
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-6.0
- clang-tidy-6.0
- valgrind
env:
- ANALYZE=false
#
# gcc-4.8 static code analysis
- os: linux
compiler: gcc
addons:
apt:
packages:
- check
- cppcheck
- valgrind
env:
- ANALYZE=true
#
# clang-6 static code analysis
- os: linux
compiler: clang-6.0
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- clang-6.0
- clang-tidy-6.0
- valgrind
env:
- ANALYZE=true
#
# clang-8 FUZZER build
- os: linux
compiler: clang-8
addons:
apt:
sources:
- llvm-toolchain-trusty-8
- ubuntu-toolchain-r-test
packages:
- check
- cppcheck
- valgrind
- clang-8
- clang-tidy-8
- libfuzzer-8-dev
env:
- FUZZER=true
#
# OSX clang build
- os: osx
compiler: clang
# disable homebrew auto update which takes a lot of time
env: HOMEBREW_NO_AUTO_UPDATE=1
cache:
directories:
- $HOME/Library/Caches/Homebrew
env:
- ANALYZE=false
#addons:
# apt:
# sources:
# # see https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
# packages:
# - binutils-mingw-w64-i686
# - build-essential
# - cmake
# - mingw32-gcc
# - gcc-mingw-w64-i686
# - gcc-mingw-w64
# - g++-mingw-w64
# - gcc-multilib
# - g++-multilib
# - libc6-dbg # for valgrind compilation
cache:
pip: true
apt: true
directories:
- $HOME/install
before_install:
# set paths for locally installed libs (like liburcu)
- export LOCAL_PKG=$HOME/install
- mkdir -p $LOCAL_PKG/lib
- mkdir -p $LOCAL_PKG/include
- mkdir -p $LOCAL_PKG/bin
- export LIBRARY_PATH=$LOCAL_PKG/lib:$LIBRARY_PATH
- export C_INCLUDE_PATH=$LOCAL_PKG/include:$C_INCLUDE_PATH
- export CPLUS_INCLUDE_PATH=$LOCAL_PKG/include:$CPLUS_INCLUDE_PATH
- export PKG_CONFIG_PATH=$LOCAL_PKG/lib/pkgconfig:$PKG_CONFIG_PATH
- export PATH=$LOCAL_PKG:$LOCAL_PKG/bin:$PATH
# set local path for python packages
- export PATH=$PATH:$HOME/.local/bin # linux
- export PATH=$PATH:$HOME/Library/Python #OS X
- export PATH=$PATH:$HOME/Library/Python/2.7/bin #OS X
- if [ ${TRAVIS_OS_NAME} == "linux" ]; then sh ./tools/travis/travis_linux_before_install.sh; fi
- if [ ${TRAVIS_OS_NAME} == "osx" ]; then sh ./tools/travis/travis_osx_before_install.sh; fi
script:
- if [ ${TRAVIS_OS_NAME} == "linux" ]; then sh ./tools/travis/travis_linux_script.sh; fi
- if [ ${TRAVIS_OS_NAME} == "osx" ]; then sh ./tools/travis/travis_osx_script.sh; fi

76
deps/mdnsd/mdnsd_back/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 2.8)
project(mdnsd C CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake")
include(GNUInstallDirs)
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
option(MDNSD_BUILD_OSS_FUZZ "Special build switch used in oss-fuzz" OFF)
mark_as_advanced(MDNSD_BUILD_OSS_FUZZ)
option(MDNSD_BUILD_FUZZING "Build the fuzzing executables" OFF)
mark_as_advanced(MDNSD_BUILD_FUZZING)
if(MDNSD_BUILD_FUZZING)
# oss-fuzz already defines this by default
add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
endif()
set(BUILD_SHARED_LIBS_DEFAULT ON)
if(MDNSD_BUILD_OSS_FUZZ)
set(BUILD_SHARED_LIBS_DEFAULT OFF)
endif()
option(BUILD_SHARED_LIBS "Build libmdnsd as a shared library" ${BUILD_SHARED_LIBS_DEFAULT})
if(MDNSD_BUILD_FUZZING_CORPUS)
add_definitions(-DMDNSD_DEBUG_DUMP_PKGS_FILE)
endif()
option(MDNSD_ENABLE_SANITIZERS "enable sanitizers for mdnsd ON)" ON)
# Debug
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER_CASE)
if(MDNSD_ENABLE_SANITIZERS AND BUILD_TYPE_LOWER_CASE STREQUAL "debug" AND UNIX)
if("x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
# Add default sanitizer settings when using clang and Debug build.
# This allows e.g. CLion to find memory locations for SegFaults
message(STATUS "Sanitizer enabled")
set(SANITIZER_FLAGS "-g -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -fsanitize=leak -fsanitize=undefined")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAGS}")
endif()
endif()
add_subdirectory(libmdnsd)
if(MDNSD_BUILD_FUZZING OR MDNSD_BUILD_OSS_FUZZ)
add_subdirectory(tests/fuzz)
endif()
add_executable(mdnsd mdnsd.c)
target_link_libraries(mdnsd PRIVATE libmdnsd)
add_executable(mquery mquery.c)
target_link_libraries(mquery PRIVATE libmdnsd)
include(CMakePackageConfigHelpers)
configure_package_config_file(mdnsdConfig.cmake.in mdnsdConfig.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
)
install(
TARGETS mdnsd mquery
EXPORT mdnsd
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
install(
FILES "${PROJECT_SOURCE_DIR}/LICENSE"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}"
)
install(EXPORT mdnsd
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
FILE "mdnsdConfigTargets.cmake"
)
install(FILES "${PROJECT_BINARY_DIR}/mdnsdConfig.cmake"
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
)

24
deps/mdnsd/mdnsd_back/LICENSE vendored Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2003 Jeremie Miller <jer@jabber.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

66
deps/mdnsd/mdnsd_back/README.md vendored Normal file
View File

@ -0,0 +1,66 @@
mdnsd - embeddable Multicast DNS Daemon
=======================================
[![Ohloh Project Status](https://www.ohloh.net/p/mdnsd_pro/widgets/project_thin_badge.gif)](https://www.ohloh.net/p/mdnsd_pro)
[![Build Status](https://travis-ci.org/Pro/mdnsd.png?branch=master)](https://travis-ci.org/Pro/mdnsd)
[![Build status](https://ci.appveyor.com/api/projects/status/gv4lros88uubrkwd?svg=true)](https://ci.appveyor.com/project/Pro/mdnsd)
This package is intended for software developers and integrators, there
isn't really anything here for an end user. The project license is the
modified 3-clause BSD, https://en.wikipedia.org/wiki/BSD_licenses
You should be able to just type make and it will build the included
example apps. Otherwise, check out `mdnsd.h` to get started, the API is
as simple as I could make it, but I hope to find some easier/better ways
to improve it in the future. Also included are some other utilities,
`sdtxt.*` for service discovery TXT record parsing/generation, and
`xht.*` for simple fast hashtables, and `1035.*` which mdnsd uses for
standalone DNS parsing.
**Differences to the base repo (https://github.com/troglobit/mdnsd)**:
* Use CMake for the build
* Strict compilation flags for better portability
* Support of Linux, MinGW, **OS X** and **Windows**
* Continuous Integration
Build & Install
---------------
The software is built for and developed on GNU/Linux systems, but should
work on any UNIX like system.
The GNU configure and build system is used, simply call the configure
script to generate a Makefile. If you are using the GitHub sources you
first need to call `./autogen.sh` to generate the configure script.
./configure
make all
make install
Running
-------
To test the included example applications you need to first start the
`mdnsd` daemon before calling `mquery`:
./mdnsd _name._service 192.168.1.2 80 &
./mquery 12 _http._tcp.local.
Origin & References
-------------------
This MDNS-SD implementation was developed by [Jeremie Miller][jeremie]
in 2003, originally [announced on the rendezvous-dev][announced] mailing
list. It has many forks and has been used by many other applications
over the years.
This GitHub project is an attempt to clean it up, develop it further,
and maintain it for the long haul.
[jeremie]: https://github.com/quartzjer
[announced]: http://lists.apple.com/archives/rendezvous-dev/2003/Feb/msg00062.html
[Travis]: https://travis-ci.org/troglobit/mdnsd
[Travis Status]: https://travis-ci.org/troglobit/mdnsd.png?branch=master

65
deps/mdnsd/mdnsd_back/appveyor.yml vendored Normal file
View File

@ -0,0 +1,65 @@
version: '{build}'
clone_folder: c:\projects\mdnsd
clone_depth: 1
environment:
global:
CYG_ARCH: x86
CYG_ROOT: C:/cygwin
CYG_SETUP_URL: http://cygwin.com/setup-x86.exe
CYG_MIRROR: http://cygwin.mirror.constant.com
CYG_CACHE: C:\cygwin\var\cache\setup
CYG_BASH: C:/cygwin/bin/bash
SHARED: ON
matrix:
- GENERATOR: MinGW Makefiles
FORCE_CXX: OFF
- GENERATOR: Visual Studio 9 2008
FORCE_CXX: ON
- GENERATOR: Visual Studio 12 2013
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- GENERATOR: Visual Studio 12 2013 Win64
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- GENERATOR: Visual Studio 16 2019
SHARED: ON
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- GENERATOR: Visual Studio 16 2019
SHARED: OFF
FORCE_CXX: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
cache:
- '%CYG_CACHE%'
init:
- git config --global core.autocrlf input # Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail
# Install needed build dependencies
install:
- git submodule update --init --recursive
- if not exist "%CYG_ROOT%" mkdir "%CYG_ROOT%"
- ps: echo "Installing Cygwin from $env:CYG_SETUP_URL to $env:CYG_ROOT/setup-x86.exe"
- appveyor DownloadFile %CYG_SETUP_URL% -FileName %CYG_ROOT%/setup-x86.exe
- ps: echo "Downloaded. Now ready to install."
- cmd: '"%CYG_ROOT%/setup-x86.exe" --quiet-mode --no-shortcuts --only-site -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" --packages cmake,python'
- cmd: '%CYG_BASH% -lc "cygcheck -dc cygwin"'
before_build:
# use MinGW64
- set PATH=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
# Workaround for CMake not wanting sh.exe on PATH for MinGW
- set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
build_script:
- cd "%APPVEYOR_BUILD_FOLDER%""
- md build
- cd build
- echo "Testing %GENERATOR%"
- cmake -DMDNSD_COMPILE_AS_CXX:BOOL=%FORCE_CXX% -DBUILD_SHARED_LIBS:BOOL=%SHARED% -G"%GENERATOR%" ..
- cmake --build .
- echo "Build done"

View File

@ -0,0 +1,3 @@
*~
*.o
libmdnsd*

637
deps/mdnsd/mdnsd_back/libmdnsd/1035.c vendored Normal file
View File

@ -0,0 +1,637 @@
#include "1035.h"
#include <string.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1900
__inline int msnds_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int msnds_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = msnds_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#else
#define msnds_snprintf snprintf
#endif
uint16_t net2short(const unsigned char **bufp)
{
unsigned short int i;
memcpy(&i, *bufp, sizeof(short int));
*bufp += 2;
return ntohs(i);
}
uint32_t net2long(const unsigned char **bufp)
{
uint32_t l;
memcpy(&l, *bufp, sizeof(uint32_t));
*bufp += 4;
return ntohl(l);
}
void short2net(uint16_t i, unsigned char **bufp)
{
uint16_t x = htons(i);
memcpy(*bufp, &x, sizeof(uint16_t));
*bufp += 2;
}
void long2net(uint32_t l, unsigned char **bufp)
{
uint32_t x = htonl(l);
memcpy(*bufp, &x, sizeof(uint32_t));
*bufp += 4;
}
static unsigned short int _ldecomp(const unsigned char *ptr)
{
unsigned short int i;
i = (unsigned short int)(0xc0 ^ ptr[0]);
i = (unsigned short int)(i<<8);
i = (unsigned short int)(i | ptr[1]);
return i;
}
static bool _label(struct message *m, const unsigned char **bufp, const unsigned char *bufEnd, char **namep)
{
int x;
const unsigned char *label;
char *name;
/* Set namep to the end of the block */
*namep = name = (char *)m->_packet + m->_len;
if (*bufp >= bufEnd)
return false;
// forward buffer pointer until we find the first compressed label
bool moveBufp = true;
/* Loop storing label in the block */
do {
if (moveBufp) {
label = *bufp;
}
if (label >= bufEnd) {
break;
}
/* Since every domain name ends with the null label of
the root, a domain name is terminated by a length byte of zero. */
if (*label == 0) {
if (moveBufp) {
*bufp += 1;
}
break;
}
/* Skip past any compression pointers, kick out if end encountered (bad data prolly) */
/* If a label is compressed, it has following structure of 2 bytes:
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* | 1 1| OFFSET |
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*
* The OFFSET field specifies an offset from
* the start of the message (i.e., the first octet of the ID field in the
* domain header). A zero offset specifies the first byte of the ID field,
* etc.
**/
if (*label & 0xc0) {
if (label + 2 > bufEnd)
return false;
unsigned short int offset = _ldecomp(label);
if (offset > m->_len)
return false;
if (m->_buf + offset >= bufEnd)
return false;
label = m->_buf + offset;
// chek if label is again pointer, then abort.
if (*label & 0xc0)
return false;
moveBufp = false;
*bufp += 2;
}
/* Make sure we're not over the limits
* See https://tools.ietf.org/html/rfc1035
* 2.3.4. Size limits
* */
const unsigned char labelLen = (unsigned char)*label;
if (labelLen > 63)
// maximum label length is 63 octets
return false;
long nameLen = (name + labelLen) - *namep;
if (nameLen > 255)
// maximum names length is 255 octets
return false;
if (label + 1 + labelLen > bufEnd) {
return false;
}
if ((unsigned char*)name + labelLen > m->_packet + MAX_PACKET_LEN) {
return false;
}
/* Copy chars for this label */
memcpy(name, label + 1, labelLen);
name[labelLen] = '.';
name += labelLen + 1;
if (moveBufp) {
*bufp += labelLen + 1;
}
else {
label += labelLen +1;
}
} while (*bufp <= bufEnd);
if ((unsigned char*)name >= m->_packet + MAX_PACKET_LEN) {
return false;
}
/* Terminate name and check for cache or cache it */
*name = '\0';
for (x = 0; x < MAX_NUM_LABELS && m->_labels[x]; x++) {
if (strcmp(*namep, m->_labels[x]))
continue;
*namep = m->_labels[x];
return true;
}
/* No cache, so cache it if room */
if (x < MAX_NUM_LABELS && m->_labels[x] == 0) {
m->_labels[x] = *namep;
}
m->_len += (unsigned long)((name - *namep) + 1);
return true;
}
/* Internal label matching */
static int _lmatch(struct message *m, const char *l1, const char *l2)
{
int len;
/* Always ensure we get called w/o a pointer */
if (*l1 & 0xc0)
return _lmatch(m, (char*)m->_buf + _ldecomp((const unsigned char*)l1), l2);
if (*l2 & 0xc0)
return _lmatch(m, l1, (char*)m->_buf + _ldecomp((const unsigned char*) l2));
/* Same already? */
if (l1 == l2)
return 1;
/* Compare all label characters */
if (*l1 != *l2)
return 0;
for (len = 1; len <= *l1; len++) {
if (l1[len] != l2[len])
return 0;
}
/* Get new labels */
l1 += *l1 + 1;
l2 += *l2 + 1;
/* At the end, all matched */
if (*l1 == 0 && *l2 == 0)
return 1;
/* Try next labels */
return _lmatch(m, l1, l2);
}
/* Nasty, convert host into label using compression */
static int _host(struct message *m, unsigned char **bufp, char *name)
{
char label[256], *l;
int len = 0, x = 1, y = 0, last = 0;
if (name == 0)
return 0;
/* Make our label */
while (name[y]) {
if (name[y] == '.') {
if (!name[y + 1])
break;
label[last] = (char)(x - (last + 1));
last = x;
} else {
label[x] = name[y];
}
if (x++ == 255)
return 0;
y++;
}
label[last] = (char)(x - (last + 1));
if (x == 1)
x--; /* Special case, bad names, but handle correctly */
len = x + 1;
label[x] = 0; /* Always terminate w/ a 0 */
/* Double-loop checking each label against all m->_labels for match */
for (x = 0; label[x]; x += label[x] + 1) {
for (y = 0; y < MAX_NUM_LABELS && m->_labels[y]; y++) {
if (_lmatch(m, label + x, m->_labels[y])) {
/* Matching label, set up pointer */
l = label + x;
short2net((unsigned short)((unsigned char *)m->_labels[y] - m->_packet), (unsigned char **)&l);
label[x] = (char)(label[x] | 0xc0);
len = x + 2;
break;
}
}
if (label[x] & 0xc0)
break;
}
/* Copy into buffer, point there now */
memcpy(*bufp, label, (size_t)len);
l = (char *)*bufp;
*bufp += len;
/* For each new label, store it's location for future compression */
for (x = 0; l[x] && m->_label < MAX_NUM_LABELS; x += l[x] + 1) {
if (l[x] & 0xc0)
break;
m->_labels[m->_label++] = l + x;
}
return len;
}
static bool _rrparse(struct message *m, struct resource *rr, int count, const unsigned char **bufp, const unsigned char* bufferEnd)
{
int i;
const unsigned char *addr_bytes = NULL;
if (count == 0) {
return true;
}
if (*bufp >= m->_bufEnd) {
return false;
}
for (i = 0; i < count; i++) {
if (*bufp >= bufferEnd) {
return false;
}
if (!_label(m, bufp, bufferEnd, &(rr[i].name))) {
return false;
}
if (*bufp + 10 > bufferEnd) {
return false;
}
rr[i].type = net2short(bufp);
rr[i].clazz = net2short(bufp);
rr[i].ttl = net2long(bufp);
rr[i].rdlength = net2short(bufp);
// fprintf(stderr, "Record type %d class 0x%2x ttl %lu len %d\n", rr[i].type, rr[i].clazz, rr[i].ttl, rr[i].rdlength);
/* For the following records the rdata will be parsed later. So don't set it here:
* NS, CNAME, PTR, DNAME, SOA, MX, AFSDB, RT, KX, RP, PX, SRV, NSEC
* See 18.14 of https://tools.ietf.org/html/rfc6762#page-47 */
if (rr[i].type == QTYPE_NS || rr[i].type == QTYPE_CNAME || rr[i].type == QTYPE_PTR || rr[i].type == QTYPE_SRV) {
rr[i].rdlength = 0;
} else {
/* If not going to overflow, make copy of source rdata */
if (*bufp + rr[i].rdlength > bufferEnd) {
return false;
}
if (m->_len + rr[i].rdlength > MAX_PACKET_LEN) {
return false;
}
rr[i].rdata = m->_packet + m->_len;
m->_len += rr[i].rdlength;
memcpy(rr[i].rdata, *bufp, rr[i].rdlength);
}
/* Parse commonly known ones */
switch (rr[i].type) {
case QTYPE_A:
if (m->_len + 16 > MAX_PACKET_LEN) {
return false;
}
rr[i].known.a.name = (char *)m->_packet + m->_len;
m->_len += 16;
if (*bufp + 4 > bufferEnd) {
return false;
}
msnds_snprintf(rr[i].known.a.name,16, "%d.%d.%d.%d", (*bufp)[0], (*bufp)[1], (*bufp)[2], (*bufp)[3]);
addr_bytes = (const unsigned char *) *bufp;
rr[i].known.a.ip.s_addr = (in_addr_t) (
((in_addr_t) addr_bytes[0]) |
(((in_addr_t) addr_bytes[1]) << 8) |
(((in_addr_t) addr_bytes[2]) << 16) |
(((in_addr_t) addr_bytes[3]) << 24));
*bufp += 4;
break;
case QTYPE_NS:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.ns.name))) {
return false;
}
break;
case QTYPE_CNAME:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.cname.name))) {
return false;
}
break;
case QTYPE_PTR:
if (!_label(m, bufp, bufferEnd, &(rr[i].known.ptr.name))) {
return false;
}
break;
case QTYPE_SRV:
if (*bufp + 6 > bufferEnd) {
return false;
}
rr[i].known.srv.priority = net2short(bufp);
rr[i].known.srv.weight = net2short(bufp);
rr[i].known.srv.port = net2short(bufp);
if (!_label(m, bufp, bufferEnd, &(rr[i].known.srv.name))) {
return false;
}
break;
case QTYPE_TXT:
default:
*bufp += rr[i].rdlength;
}
}
return true;
}
/* Keep all our mem in one (aligned) block for easy freeing */
#define my(x,y, cast) \
while (m->_len & 7) \
m->_len++; \
\
if (m->_len + y > MAX_PACKET_LEN) { return false; } \
x = (cast)(void *)(m->_packet + m->_len); \
m->_len += y;
bool message_parse(struct message *m, unsigned char *packet, size_t packetLen)
{
int i;
const unsigned char *buf;
m->_bufEnd = packet + packetLen;
/* Message format: https://tools.ietf.org/html/rfc1035
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
*/
if (packet == 0 || m == 0)
return false;
/* See https://tools.ietf.org/html/rfc1035
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
/* The header always needs to be present. Size = 12 byte */
if (packetLen < 12)
return false;
/* Header stuff bit crap */
buf = m->_buf = packet;
m->id = net2short(&buf);
if (buf[0] & 0x80)
m->header.qr = 1;
m->header.opcode = (unsigned short)(((buf[0] & 0x78) >> 3) & 15);
if (buf[0] & 0x04)
m->header.aa = 1;
if (buf[0] & 0x02)
m->header.tc = 1;
if (buf[0] & 0x01)
m->header.rd = 1;
if (buf[1] & 0x80)
m->header.ra = 1;
m->header.z = (unsigned short)(((buf[1] & 0x70) >> 4) & 7);
m->header.rcode = (unsigned short)(buf[1] & 0x0F);
buf += 2;
m->qdcount = net2short(&buf);
m->ancount = net2short(&buf);
m->nscount = net2short(&buf);
m->arcount = net2short(&buf);
// check if the message has the correct size, i.e. the count matches the number of bytes
/* Process questions */
my(m->qd, (sizeof(struct question) * m->qdcount), struct question *);
for (i = 0; i < m->qdcount; i++) {
if (!_label(m, &buf, m->_bufEnd, &(m->qd[i].name))) {
return false;
}
if (buf + 4 > m->_bufEnd) {
return false;
}
m->qd[i].type = net2short(&buf);
m->qd[i].clazz = net2short(&buf);
}
if (buf > m->_bufEnd) {
return false;
}
/* Process rrs */
my(m->an, (sizeof(struct resource) * m->ancount), struct resource *);
my(m->ns, (sizeof(struct resource) * m->nscount), struct resource *);
my(m->ar, (sizeof(struct resource) * m->arcount), struct resource *);
if (!_rrparse(m, m->an, m->ancount, &buf, m->_bufEnd))
return false;
if (!_rrparse(m, m->ns, m->nscount, &buf, m->_bufEnd))
return false;
if (!_rrparse(m, m->ar, m->arcount, &buf, m->_bufEnd))
return false;
return true;
}
void message_qd(struct message *m, char *name, unsigned short int type, unsigned short int clazz)
{
m->qdcount++;
if (m->_buf == 0) {
m->_buf = m->_packet + 12;
m->_bufEnd = m->_packet + sizeof(m->_packet);
}
_host(m, &(m->_buf), name);
short2net(type, &(m->_buf));
short2net(clazz, &(m->_buf));
}
static void _rrappend(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
if (m->_buf == 0) {
m->_buf = m->_packet + 12;
m->_bufEnd = m->_packet + sizeof(m->_packet);
}
_host(m, &(m->_buf), name);
short2net(type, &(m->_buf));
short2net(clazz, &(m->_buf));
long2net((uint32_t)ttl, &(m->_buf));
}
void message_an(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->ancount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_ns(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->nscount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_ar(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl)
{
m->arcount++;
_rrappend(m, name, type, clazz, ttl);
}
void message_rdata_long(struct message *m, struct in_addr l)
{
short2net(4, &(m->_buf));
long2net(l.s_addr, &(m->_buf));
}
void message_rdata_name(struct message *m, char *name)
{
unsigned char *mybuf = m->_buf;
m->_buf += 2;
short2net((unsigned short)_host(m, &(m->_buf), name), &mybuf);
}
void message_rdata_srv(struct message *m, unsigned short int priority, unsigned short int weight, unsigned short int port, char *name)
{
unsigned char *mybuf = m->_buf;
m->_buf += 2;
short2net(priority, &(m->_buf));
short2net(weight, &(m->_buf));
short2net(port, &(m->_buf));
short2net((unsigned short)(_host(m, &(m->_buf), name) + 6), &mybuf);
}
void message_rdata_raw(struct message *m, unsigned char *rdata, unsigned short int rdlength)
{
if (((unsigned char *)m->_buf - m->_packet) + rdlength > 4096)
rdlength = 0;
short2net(rdlength, &(m->_buf));
memcpy(m->_buf, rdata, rdlength);
m->_buf += rdlength;
}
unsigned char *message_packet(struct message *m)
{
unsigned char c, *buf = m->_buf, *bufEnd = m->_bufEnd;
m->_buf = m->_packet;
m->_bufEnd = m->_packet + sizeof(m->_packet);
short2net(m->id, &(m->_buf));
if (m->header.qr)
m->_buf[0] |= 0x80;
if ((c = (unsigned char)m->header.opcode))
m->_buf[0] |= (unsigned char)(c << 3);
if (m->header.aa)
m->_buf[0] |= 0x04;
if (m->header.tc)
m->_buf[0] |= 0x02;
if (m->header.rd)
m->_buf[0] |= 0x01;
if (m->header.ra)
m->_buf[1] |= 0x80;
if ((c = (unsigned char)m->header.z))
m->_buf[1] |= (unsigned char)(c << 4);
if (m->header.rcode)
m->_buf[1] = (unsigned char)(m->_buf[1] | m->header.rcode);
m->_buf += 2;
short2net(m->qdcount, &(m->_buf));
short2net(m->ancount, &(m->_buf));
short2net(m->nscount, &(m->_buf));
short2net(m->arcount, &(m->_buf));
m->_buf = buf; /* Restore, so packet_len works */
m->_bufEnd = bufEnd;
return m->_packet;
}
int message_packet_len(struct message *m)
{
if (m->_buf == 0)
return 12;
return (int)((unsigned char *)m->_buf - m->_packet);
}

188
deps/mdnsd/mdnsd_back/libmdnsd/1035.h vendored Normal file
View File

@ -0,0 +1,188 @@
/* Familiarize yourself with RFC1035 if you want to know what all the
* variable names mean. This file hides most of the dirty work all of
* this code depends on the buffer space a packet is in being 4096 and
* zero'd before the packet is copied in also conveniently decodes srv
* rr's, type 33, see RFC2782
*/
#ifndef MDNS_1035_H_
#define MDNS_1035_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
#ifdef _WIN32
/* Backup definition of SLIST_ENTRY on mingw winnt.h */
#ifdef SLIST_ENTRY
# pragma push_macro("SLIST_ENTRY")
# undef SLIST_ENTRY
# define POP_SLIST_ENTRY
#endif
/* winnt.h redefines SLIST_ENTRY */
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* inet_ntoa is deprecated on MSVC but used for compatibility */
# include <winsock2.h>
# include <ws2tcpip.h>
#ifndef in_addr_t
#define in_addr_t unsigned __int32
#endif
/* restore definition */
#ifdef POP_SLIST_ENTRY
# undef SLIST_ENTRY
# undef POP_SLIST_ENTRY
# pragma pop_macro("SLIST_ENTRY")
#endif
#else
# include <arpa/inet.h>
#endif
#if !defined(__bool_true_false_are_defined) && defined(_MSC_VER) && _MSC_VER < 1600
// VS 2008 has no stdbool.h
#define bool short
#define true 1
#define false 0
#else
#include <stdbool.h>
#endif
#ifdef _MSC_VER
#include "ms_stdint.h" /* Includes stdint.h or workaround for older Visual Studios */
#else
#include <stdint.h>
#endif
/* Should be reasonably large, for UDP */
#define MAX_PACKET_LEN 10000
#define MAX_NUM_LABELS 20
struct question {
char *name;
unsigned short type, clazz;
};
#define QTYPE_A 1
#define QTYPE_NS 2
#define QTYPE_CNAME 5
#define QTYPE_PTR 12
#define QTYPE_TXT 16
#define QTYPE_SRV 33
struct resource {
char *name;
unsigned short type, clazz;
unsigned long int ttl;
unsigned short int rdlength;
unsigned char *rdata;
union {
struct {
struct in_addr ip;
//cppcheck-suppress unusedStructMember
char *name;
} a;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} ns;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} cname;
struct {
//cppcheck-suppress unusedStructMember
char *name;
} ptr;
struct {
//cppcheck-suppress unusedStructMember
unsigned short int priority, weight, port;
//cppcheck-suppress unusedStructMember
char *name;
} srv;
} known;
};
struct message {
/* External data */
unsigned short int id;
struct {
//it would be better to use unsigned short, but gcc < 5 complaints when using pedantic
//cppcheck-suppress unusedStructMember
unsigned int qr:1, opcode:4, aa:1, tc:1, rd:1, ra:1, z:3, rcode:4;
} header;
unsigned short int qdcount, ancount, nscount, arcount;
struct question *qd;
struct resource *an, *ns, *ar;
/* Internal variables */
unsigned char *_buf;
unsigned char *_bufEnd;
char *_labels[MAX_NUM_LABELS];
size_t _len;
int _label;
/* Packet acts as padding, easier mem management */
unsigned char _packet[MAX_PACKET_LEN];
};
/**
* Returns the next short/long off the buffer (and advances it)
*/
uint16_t net2short(const unsigned char **bufp);
uint32_t net2long (const unsigned char **bufp);
/**
* copies the short/long into the buffer (and advances it)
*/
void MDNSD_EXPORT short2net(uint16_t i, unsigned char **bufp);
void MDNSD_EXPORT long2net (uint32_t l, unsigned char **bufp);
/**
* parse packet into message, packet must be at least MAX_PACKET_LEN and
* message must be zero'd for safety
*/
bool MDNSD_EXPORT message_parse(struct message *m, unsigned char *packet, size_t packetLen);
/**
* create a message for sending out on the wire
*/
struct message *message_wire(void);
/**
* append a question to the wire message
*/
void MDNSD_EXPORT message_qd(struct message *m, char *name, unsigned short int type, unsigned short int clazz);
/**
* append a resource record to the message, all called in order!
*/
void MDNSD_EXPORT message_an(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
void MDNSD_EXPORT message_ns(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
void MDNSD_EXPORT message_ar(struct message *m, char *name, unsigned short int type, unsigned short int clazz, unsigned long ttl);
/**
* Append various special types of resource data blocks
*/
void MDNSD_EXPORT message_rdata_long (struct message *m, struct in_addr l);
void MDNSD_EXPORT message_rdata_name (struct message *m, char *name);
void MDNSD_EXPORT message_rdata_srv (struct message *m, unsigned short int priority, unsigned short int weight,
unsigned short int port, char *name);
void MDNSD_EXPORT message_rdata_raw (struct message *m, unsigned char *rdata, unsigned short int rdlength);
/**
* Return the wire format (and length) of the message, just free message
* when done
*/
unsigned char MDNSD_EXPORT * message_packet (struct message *m);
int MDNSD_EXPORT message_packet_len (struct message *m);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_1035_H_ */

View File

@ -0,0 +1,120 @@
cmake_minimum_required(VERSION 2.8)
project(libmdnsd C)
include(GenerateExportHeader)
set(MDNSD_LOGLEVEL 300 CACHE STRING "Level at which logs shall be reported")
# Force compilation with as C++
option(MDNSD_COMPILE_AS_CXX "Force compilation with a C++ compiler" OFF)
mark_as_advanced(MDNSD_COMPILE_AS_CXX)
option(CMAKE_POSITION_INDEPENDENT_CODE "Build mdnsd using -fPIC" ON)
if(NOT MDNSD_COMPILE_AS_CXX AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang"))
add_definitions(-std=c99 -pipe
-Wall -Wextra -Werror
-Wno-unused-parameter # some methods may require unused arguments to cast to a method pointer
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
-Wformat -Wformat-security -Wformat-nonliteral
-Wuninitialized -Winit-self
-Wcast-qual -Wcast-align
-Wstrict-overflow
-Wnested-externs
-Wmultichar
-Wundef
-Wc++-compat)
if(NOT MINGW AND NOT MSYS AND NOT MSVC)
add_definitions(-Wpedantic)
endif()
if(NOT WIN32 AND NOT CYGWIN)
add_definitions(-Wshadow -Wconversion)
endif()
endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
option(MDNSD_ENABLE_COVERAGE "Enable gcov coverage" OFF)
if(MDNSD_ENABLE_COVERAGE)
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
# Building shared libs (dll, so)
set(MDNSD_DYNAMIC_LINKING OFF)
if(BUILD_SHARED_LIBS)
set(MDNSD_DYNAMIC_LINKING ON)
endif()
configure_file("mdnsd_config_extra.in" "${PROJECT_BINARY_DIR}/mdnsd_config_extra")
include_directories(${PROJECT_BINARY_DIR})
set(PUBLIC_INCLUDES mdnsd.h 1035.h sdtxt.h xht.h "${PROJECT_BINARY_DIR}/mdnsd_config.h")
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
list(APPEND PUBLIC_INCLUDES ms_stdint.h)
endif()
set(LIBRARY_FILES mdnsd.c 1035.c xht.c sdtxt.c)
if (MDNSD_BUILD_FUZZING_CORPUS)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_definitions(-DMDNSD_CORPUS_OUTPUT_DIR="${PROJECT_BINARY_DIR}/corpus/custom")
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/corpus/custom)
list(APPEND LIBRARY_FILES mdnsd_debug_dump_pkgs_file.c)
endif()
if(MDNSD_COMPILE_AS_CXX)
set_source_files_properties(${LIBRARY_FILES} PROPERTIES LANGUAGE CXX)
enable_language(CXX)
endif()
add_library(libmdnsd ${LIBRARY_FILES} ${PUBLIC_INCLUDES})
target_include_directories(libmdnsd PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/..>"
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
set_target_properties(libmdnsd PROPERTIES
OUTPUT_NAME "mdnsd"
DEFINE_SYMBOL "MDNSD_DYNAMIC_LINKING_EXPORT"
)
target_compile_definitions(libmdnsd PUBLIC
$<$<STREQUAL:$<TARGET_PROPERTY:libmdnsd,TYPE>,STATIC_LIBRARY>:MDNSD_STATIC_DEFINE>
)
file(READ "${PROJECT_BINARY_DIR}/mdnsd_config_extra" MDNSD_CONFIG_EXTRA)
generate_export_header(libmdnsd
EXPORT_FILE_NAME "${PROJECT_BINARY_DIR}/mdnsd_config.h"
BASE_NAME MDNSD
DEFINE_NO_DEPRECATED
CUSTOM_CONTENT_FROM_VARIABLE MDNSD_CONFIG_EXTRA
)
if(WIN32)
target_link_libraries(libmdnsd PUBLIC wsock32 ws2_32)
endif()
install(
TARGETS libmdnsd
EXPORT mdnsd
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
install(
FILES ${PUBLIC_INCLUDES}
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}"
)
install(
FILES ${PROJECT_BINARY_DIR}/mdnsd_config.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}"
)

1277
deps/mdnsd/mdnsd_back/libmdnsd/mdnsd.c vendored Normal file

File diff suppressed because it is too large Load Diff

234
deps/mdnsd/mdnsd_back/libmdnsd/mdnsd.h vendored Normal file
View File

@ -0,0 +1,234 @@
#ifndef MDNSD_H_
#define MDNSD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
#include "1035.h"
#if !defined(__bool_true_false_are_defined) && defined(_MSC_VER) && _MSC_VER < 1600
// VS 2008 has no stdbool.h
#define bool short
#define true 1
#define false 0
#else
#include <stdbool.h>
#endif
#include <stdio.h>
#define QCLASS_IN (1)
#if MDNSD_LOGLEVEL <= 100
#define MDNSD_LOG_TRACE(...) do { \
printf("mdnsd: TRACE - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_TRACE(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 200
#define MDNSD_LOG_DEBUG(...) do { \
printf("mdnsd: DEBUG - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_DEBUG(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 300
#define MDNSD_LOG_INFO(...) do { \
printf("mdnsd: INFO - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_INFO(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 400
#define MDNSD_LOG_WARNING(...) do { \
printf("mdnsd: WARN - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_WARNING(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 500
#define MDNSD_LOG_ERROR(...) do { \
printf("mdnsd: ERROR - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_ERROR(...) do {} while(0)
#endif
#if MDNSD_LOGLEVEL <= 600
#define MDNSD_LOG_FATAL(...) do { \
printf("mdnsd: FATAL - "); printf(__VA_ARGS__); printf("\n"); } while(0)
#else
#define MDNSD_LOG_FATAL(...) do {} while(0)
#endif
/* Main daemon data */
typedef struct mdns_daemon mdns_daemon_t;
/* Record entry */
typedef struct mdns_record mdns_record_t;
/* Callback for received record. Data is passed from the register call */
typedef void (*mdnsd_record_received_callback)(const struct resource* r, void* data);
/* Answer data */
typedef struct mdns_answer {
char *name;
unsigned short type;
unsigned long ttl;
unsigned short rdlen;
unsigned char *rdata;
struct in_addr ip; /* A */
char *rdname; /* NS/CNAME/PTR/SRV */
struct {
//cppcheck-suppress unusedStructMember
unsigned short int priority, weight, port;
} srv; /* SRV */
} mdns_answer_t;
/**
* Global functions
*/
/**
* Create a new mdns daemon for the given class of names (usually 1) and
* maximum frame size
*/
mdns_daemon_t MDNSD_EXPORT * mdnsd_new(int clazz, int frame);
/**
* Gracefully shutdown the daemon, use mdnsd_out() to get the last
* packets
*/
void MDNSD_EXPORT mdnsd_shutdown(mdns_daemon_t *d);
/**
* Flush all cached records (network/interface changed)
*/
void MDNSD_EXPORT mdnsd_flush(mdns_daemon_t *d);
/**
* Free given mdns_daemon_t *(should have used mdnsd_shutdown() first!)
*/
void MDNSD_EXPORT mdnsd_free(mdns_daemon_t *d);
/**
* Register callback which is called when a record is received. The data parameter is passed to the callback.
* Calling this multiple times overwrites the previous register.
*/
void MDNSD_EXPORT mdnsd_register_receive_callback(mdns_daemon_t *d, mdnsd_record_received_callback cb, void* data);
/**
* I/O functions
*/
/**
* Oncoming message from host (to be cached/processed)
*/
int MDNSD_EXPORT mdnsd_in(mdns_daemon_t *d, struct message *m, in_addr_t ip, unsigned short int port);
/**
* Outgoing messge to be delivered to host, returns >0 if one was
* returned and m/ip/port set
*/
int MDNSD_EXPORT mdnsd_out(mdns_daemon_t *d, struct message *m, struct in_addr *ip, unsigned short int *port);
/**
* returns the max wait-time until mdnsd_out() needs to be called again
*/
struct timeval MDNSD_EXPORT * mdnsd_sleep(mdns_daemon_t *d);
/**
* Q/A functions
*/
/**
* Register a new query
*
* The answer() callback is called whenever one is found/changes/expires
* (immediate or anytime after, mdns_answer_t valid until ->ttl==0)
* either answer returns -1, or another mdnsd_query() with a %NULL answer
* will remove/unregister this query
*/
void MDNSD_EXPORT mdnsd_query(mdns_daemon_t *d, const char *host, int type, int (*answer)(mdns_answer_t *a, void *arg), void *arg);
/**
* Returns the first (if last == NULL) or next answer after last from
* the cache mdns_answer_t only valid until an I/O function is called
*/
mdns_answer_t MDNSD_EXPORT *mdnsd_list(mdns_daemon_t *d, const char *host, int type, mdns_answer_t *last);
/**
* Returns the next record of the given record, i.e. the value of next field.
* @param r the base record
* @return r->next
*/
mdns_record_t MDNSD_EXPORT *mdnsd_record_next(const mdns_record_t* r) ;
/**
* Gets the record data
*/
const mdns_answer_t MDNSD_EXPORT *mdnsd_record_data(const mdns_record_t* r) ;
/**
* Publishing functions
*/
/**
* Create a new unique record
*
* Call mdnsd_list() first to make sure the record is not used yet.
*
* The conflict() callback is called at any point when one is detected
* and unable to recover after the first data is set_*(), any future
* changes effectively expire the old one and attempt to create a new
* unique record
*/
mdns_record_t MDNSD_EXPORT * mdnsd_unique(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl, void (*conflict)(char *host, int type, void *arg), void *arg);
/**
* Create a new shared record
*/
mdns_record_t MDNSD_EXPORT * mdnsd_shared(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl);
/**
* Get a previously created record based on the host name. NULL if not found. Does not return records for other hosts.
* If multiple records are found, use record->next to iterate over all the results.
*/
mdns_record_t MDNSD_EXPORT * mdnsd_get_published(const mdns_daemon_t *d, const char *host);
/**
* Check if there is already a query for the given host
*/
int MDNSD_EXPORT mdnsd_has_query(const mdns_daemon_t *d, const char *host);
/**
* de-list the given record
*/
void MDNSD_EXPORT mdnsd_done(mdns_daemon_t *d, mdns_record_t *r);
/**
* These all set/update the data for the given record, nothing is
* published until they are called
*/
void MDNSD_EXPORT mdnsd_set_raw(mdns_daemon_t *d, mdns_record_t *r, const char *data, unsigned short int len);
void MDNSD_EXPORT mdnsd_set_host(mdns_daemon_t *d, mdns_record_t *r, const char *name);
void MDNSD_EXPORT mdnsd_set_ip(mdns_daemon_t *d, mdns_record_t *r, struct in_addr ip);
void MDNSD_EXPORT mdnsd_set_srv(mdns_daemon_t *d, mdns_record_t *r, unsigned short int priority, unsigned short int weight, unsigned short int port, char *name);
/**
* Process input queue and output queue. Should be called at least the time which is returned in nextSleep.
* Returns 0 on success, 1 on read error, 2 on write error
*/
unsigned short int MDNSD_EXPORT mdnsd_step(mdns_daemon_t *d, int mdns_socket, bool processIn, bool processOut, struct timeval *nextSleep);
#ifdef MDNSD_DEBUG_DUMP_PKGS_FILE
void mdnsd_debug_dumpCompleteChunk(mdns_daemon_t *d, const char* data, size_t len);
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNSD_H_ */

View File

@ -0,0 +1,27 @@
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 500
#endif
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
#endif
#if defined __APPLE__
// required for ip_mreq
#define _DARWIN_C_SOURCE 1
#endif
#define MDNSD_free(ptr) free(ptr)
#define MDNSD_malloc(size) malloc(size)
#define MDNSD_calloc(num, size) calloc(num, size)
#define MDNSD_realloc(ptr, size) realloc(ptr, size)
#define MDNSD_LOGLEVEL ${MDNSD_LOGLEVEL}
/**
* Inline Functions
* ---------------- */
#ifdef _MSC_VER
# define MDNSD_INLINE __inline
#else
# define MDNSD_INLINE inline
#endif

View File

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This code is used to generate a binary file for every request type
* which can be sent from a client to the server.
* These files form the basic corpus for fuzzing the server.
*/
#ifndef MDNSD_DEBUG_DUMP_PKGS_FILE
#error MDNSD_DEBUG_DUMP_PKGS_FILE must be defined
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "mdnsd.h"
unsigned int mdnsd_dump_chunkCount = 0;
void mdnsd_debug_dumpCompleteChunk(mdns_daemon_t *d, const char* data, size_t len) {
char fileName[250];
struct timeval t;
gettimeofday(&t, 0);
snprintf(fileName, sizeof(fileName), "%s/%05u_%ld", MDNSD_CORPUS_OUTPUT_DIR, ++mdnsd_dump_chunkCount, t.tv_sec);
char dumpOutputFile[266];
snprintf(dumpOutputFile, 255, "%s.bin", fileName);
// check if file exists and if yes create a counting filename to avoid overwriting
unsigned cnt = 1;
while ( access( dumpOutputFile, F_OK ) != -1 ) {
snprintf(dumpOutputFile, 266, "%s_%u.bin", fileName, cnt);
cnt++;
}
FILE *write_ptr = fopen(dumpOutputFile, "ab");
fwrite(data, len, 1, write_ptr); // write 10 bytes from our buffer
fclose(write_ptr);
}

View File

@ -0,0 +1,257 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2013 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the product nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(_MSC_VER) || _MSC_VER >= 1600 // [
#include <stdint.h>
#else
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifndef UNDER_CE
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
#endif // !defined(_MSC_VER) || _MSC_VER >= 1600 ]

93
deps/mdnsd/mdnsd_back/libmdnsd/sdtxt.c vendored Normal file
View File

@ -0,0 +1,93 @@
#include "sdtxt.h"
#include <stdlib.h>
#include <string.h>
static size_t _sd2txt_len(const char *key, char *val)
{
size_t ret = strlen(key);
if (!*val)
return ret;
ret += strlen(val);
ret++;
return ret;
}
static void _sd2txt_count(xht_t *h, char *key, void *val, void *arg)
{
int *count = (int *)arg;
*count += (int)_sd2txt_len(key, (char *)val) + 1;
}
static void _sd2txt_write(xht_t *h, char *key, void *val, void *arg)
{
unsigned char **txtp = (unsigned char **)arg;
char *cval = (char *)val;
/* Copy in lengths, then strings */
**txtp = (unsigned char)_sd2txt_len(key, (char *)val);
(*txtp)++;
memcpy(*txtp, key, strlen(key));
*txtp += strlen(key);
if (!*cval)
return;
**txtp = '=';
(*txtp)++;
memcpy(*txtp, cval, strlen(cval));
*txtp += strlen(cval);
}
unsigned char *sd2txt(xht_t *h, int *len)
{
unsigned char *buf, *raw;
*len = 0;
xht_walk(h, _sd2txt_count, (void *)len);
if (!*len) {
*len = 1;
buf = (unsigned char *)MDNSD_malloc(1);
*buf = 0;
return buf;
}
raw = buf = (unsigned char *)MDNSD_malloc((size_t)(*len));
xht_walk(h, _sd2txt_write, &buf);
return raw;
}
xht_t *txt2sd(const unsigned char *txt, int len)
{
char key[256];
xht_t *h = NULL;
if (txt == 0 || len == 0 || *txt == 0)
return NULL;
h = xht_new(23);
/* Loop through data breaking out each block, storing into hashtable */
for (; len > 0 && *txt <= len; len -= *txt, txt += *txt + 1) {
char* val;
if (*txt == 0)
break;
memcpy(key, txt + 1, *txt);
key[*txt] = 0;
if ((val = strchr(key, '=')) != 0) {
*val = 0;
val++;
}
if (val != NULL)
xht_store(h, key, (int)strlen(key), val, (int)strlen(val));
if (*txt +1 > len)
break;
}
return h;
}

24
deps/mdnsd/mdnsd_back/libmdnsd/sdtxt.h vendored Normal file
View File

@ -0,0 +1,24 @@
#ifndef MDNS_SDTXT_H_
#define MDNS_SDTXT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xht.h"
/**
* returns hashtable of strings from the SD TXT record rdata
*/
xht_t MDNSD_EXPORT *txt2sd(const unsigned char *txt, int len);
/**
* returns a raw block that can be sent with a SD TXT record, sets length
*/
unsigned char MDNSD_EXPORT *sd2txt(xht_t *h, int *len);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_SDTXT_H_ */

182
deps/mdnsd/mdnsd_back/libmdnsd/xht.c vendored Normal file
View File

@ -0,0 +1,182 @@
#include "xht.h"
#include <string.h>
#include <stdlib.h>
typedef struct xhn {
char flag;
struct xhn *next;
char *key;
void *val;
} xhn_t;
struct xht {
int prime;
xhn_t *zen;
};
/* Generates a hash code for a string.
* This function uses the ELF hashing algorithm as reprinted in
* Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
*/
static int _xhter(const char *s)
{
/* ELF hash uses unsigned chars and unsigned arithmetic for portability */
const unsigned char *name = (const unsigned char *)s;
unsigned long int h = 0;
while (*name) { /* do some fancy bitwanking on the string */
unsigned long int g;
h = (h << 4) + (unsigned long int)(*name++);
if ((g = (h & 0xF0000000UL)) != 0)
h ^= (g >> 24);
h &= ~g;
}
return (int)h;
}
static xhn_t *_xht_node_find(xhn_t *n, const char *key)
{
for (; n != 0; n = n->next)
if (n->key != 0 && strcmp(key, n->key) == 0)
return n;
return 0;
}
xht_t *xht_new(int prime)
{
xht_t *xnew;
xnew = (xht_t *)MDNSD_malloc(sizeof(struct xht));
xnew->prime = prime;
xnew->zen = (xhn_t *)MDNSD_calloc(1, (sizeof(struct xhn) * (size_t)prime)); /* array of xhn_t size of prime */
return xnew;
}
/* does the set work, used by xht_set and xht_store */
static xhn_t *_xht_set(xht_t *h, char *key, void *val, char flag)
{
int i;
xhn_t *n;
/* get our index for this key */
i = _xhter(key) % h->prime;
/* check for existing key first, or find an empty one */
if ((n = _xht_node_find(&h->zen[i], key)) == 0) {
for (n = &h->zen[i]; n != 0; n = n->next) {
if (n->val == 0)
break;
}
}
/* if none, make a new one, link into this index */
if (n == NULL) {
if (h->zen != NULL) {
n = (xhn_t *)MDNSD_malloc(sizeof(struct xhn));
n->next = NULL;
n->next = h->zen[i].next;
h->zen[i].next = n;
}
} else if (n->flag) {
/* When flag is set, we manage their mem and free em first */
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
if (n != NULL) {
n->flag = flag;
n->key = key;
n->val = val;
} else {
MDNSD_free(key);
MDNSD_free(val);
}
return n;
}
void xht_set(xht_t *h, char *key, void *val)
{
if (h == 0 || key == 0)
return;
_xht_set(h, key, val, 0);
}
void xht_store(xht_t *h, char *key, int klen, void *val, int vlen)
{
char *ckey, *cval;
if (h == 0 || key == 0 || klen == 0)
return;
ckey = (char *)MDNSD_malloc((size_t)klen + 1);
memcpy(ckey, key, (size_t)klen);
ckey[klen] = '\0';
cval = (char *)MDNSD_malloc((size_t)vlen + 1);
memcpy(cval, val, (size_t)vlen);
cval[vlen] = '\0'; /* convenience, in case it was a string too */
_xht_set(h, ckey, cval, 1);
}
void *xht_get(xht_t *h, char *key)
{
xhn_t *n;
if (h == 0 || key == 0 || (n = _xht_node_find(&h->zen[_xhter(key) % h->prime], key)) == 0)
return 0;
return n->val;
}
void xht_free(xht_t *h)
{
int i;
xhn_t *n, *f;
if (h == 0)
return;
for (i = 0; i < h->prime; i++) {
if ((n = (&h->zen[i])) == NULL)
continue;
if (n->flag) {
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
for (n = (&h->zen[i])->next; n != 0;) {
f = n->next;
if (n->flag) {
MDNSD_free((void *)n->key);
MDNSD_free(n->val);
}
MDNSD_free(n);
n = f;
}
}
MDNSD_free(h->zen);
MDNSD_free(h);
}
void xht_walk(xht_t *h, xht_walker w, void *arg)
{
int i;
xhn_t *n;
if (h == 0 || w == 0)
return;
for (i = 0; i < h->prime; i++) {
for (n = &h->zen[i]; n != 0; n = n->next) {
if (n->key != 0 && n->val != 0)
(*w)(h, n->key, n->val, arg);
}
}
}

53
deps/mdnsd/mdnsd_back/libmdnsd/xht.h vendored Normal file
View File

@ -0,0 +1,53 @@
/* Simple string->void* hashtable, very static and bare minimal, but efficient */
#ifndef MDNS_XHT_H_
#define MDNS_XHT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "mdnsd_config.h"
typedef struct xht xht_t;
/**
* must pass a prime#
*/
xht_t MDNSD_EXPORT *xht_new(int prime);
/**
* caller responsible for key storage, no copies made
*
* set val to NULL to clear an entry, memory is reused but never free'd
* (# of keys only grows to peak usage)
*
* Note: don't free it b4 xht_free()!
*/
void MDNSD_EXPORT xht_set(xht_t *h, char *key, void *val);
/**
* Unlike xht_set() where key/val is in caller's mem, here they are
* copied into xht and free'd when val is 0 or xht_free()
*/
void MDNSD_EXPORT xht_store(xht_t *h, char *key, int klen, void *val, int vlen);
/**
* returns value of val if found, or NULL
*/
void MDNSD_EXPORT *xht_get(xht_t *h, char *key);
/**
* free the hashtable and all entries
*/
void MDNSD_EXPORT xht_free(xht_t *h);
/**
* pass a function that is called for every key that has a value set
*/
typedef void (*xht_walker)(xht_t *h, char *key, void *val, void *arg);
void xht_walk(xht_t *h, xht_walker w, void *arg);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* MDNS_XHT_H_ */

282
deps/mdnsd/mdnsd_back/mdnsd.c vendored Normal file
View File

@ -0,0 +1,282 @@
#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501)
/* Assume the target is newer than Windows XP */
# undef WINVER
# undef _WIN32_WINDOWS
# undef _WIN32_WINNT
# define WINVER _WIN32_WINNT_VISTA
# define _WIN32_WINDOWS _WIN32_WINNT_VISTA
# define _WIN32_WINNT _WIN32_WINNT_VISTA
#endif
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <sys/types.h>
#ifdef _WIN32
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* inet_ntoa is deprecated on MSVC but used for compatibility */
# include <winsock2.h>
# include <ws2tcpip.h>
static int my_inet_pton(int af, const char *src, void *dst)
{
struct sockaddr_storage ss;
int size = sizeof(ss);
char src_copy[INET6_ADDRSTRLEN+1];
ZeroMemory(&ss, sizeof(ss));
/* stupid non-const API */
strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
src_copy[INET6_ADDRSTRLEN] = 0;
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
switch(af) {
case AF_INET:
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
return 1;
case AF_INET6:
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
return 1;
}
}
return 0;
}
#define INET_PTON my_inet_pton
#else
# include <arpa/inet.h>
# include <netinet/in.h>
# include <sys/select.h>
# include <sys/ioctl.h>
#define INET_PTON inet_pton
#endif
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
# define CLOSESOCKET(S) closesocket((SOCKET)S)
# define ssize_t int
#else
# include <unistd.h> // read, write, close
# define CLOSESOCKET(S) close(S)
#endif
#include <libmdnsd/mdnsd.h>
#include <libmdnsd/sdtxt.h>
int _shutdown = 0;
mdns_daemon_t *_d;
int daemon_socket = 0;
void conflict(char *name, int type, void *arg)
{
printf("conflicting name detected %s for type %d\n", name, type);
exit(1);
}
void record_received(const struct resource* r, void* data) {
#ifndef _WIN32
char ipinput[INET_ADDRSTRLEN];
#endif
switch(r->type) {
case QTYPE_A:
#ifndef _WIN32
inet_ntop(AF_INET, &(r->known.a.ip), ipinput, INET_ADDRSTRLEN);
printf("Got %s: A %s->%s\n", r->name,r->known.a.name, ipinput);
#else
printf("Got %s: A %s\n", r->name,r->known.a.name);
#endif
break;
case QTYPE_NS:
printf("Got %s: NS %s\n", r->name,r->known.ns.name);
break;
case QTYPE_CNAME:
printf("Got %s: CNAME %s\n", r->name,r->known.cname.name);
break;
case QTYPE_PTR:
printf("Got %s: PTR %s\n", r->name,r->known.ptr.name);
break;
case QTYPE_TXT:
printf("Got %s: TXT %s\n", r->name,r->rdata);
break;
case QTYPE_SRV:
printf("Got %s: SRV %d %d %d %s\n", r->name,r->known.srv.priority,r->known.srv.weight,r->known.srv.port,r->known.srv.name);
break;
default:
printf("Got %s: unknown\n", r->name);
}
}
void done(int sig)
{
_shutdown = 1;
mdnsd_shutdown(_d);
// wake up select
if (write(daemon_socket, "\0", 1) == -1) {
printf("Could not write zero byte to socket\n");
}
}
static void socket_set_nonblocking(int sockfd) {
#ifdef _WIN32
u_long iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);
#else
int opts = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, opts|O_NONBLOCK);
#endif
}
/* Create multicast 224.0.0.251:5353 socket */
int msock(void)
{
int s, flag = 1, ittl = 255;
struct sockaddr_in in;
struct ip_mreq mc;
unsigned char ttl = 255; // send to any reachable net, not only the subnet
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
in.sin_port = htons(5353);
in.sin_addr.s_addr = 0;
if ((s = (int)socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 0;
#ifdef SO_REUSEPORT
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
#endif
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
if (bind(s, (struct sockaddr *)&in, sizeof(in))) {
CLOSESOCKET(s);
return 0;
}
mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
mc.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mc, sizeof(mc));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ttl, sizeof(ttl));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ittl, sizeof(ittl));
socket_set_nonblocking(s);
return s;
}
int main(int argc, char *argv[])
{
mdns_daemon_t *d;
mdns_record_t *r;
struct in_addr ip;
unsigned short int port;
fd_set fds;
int s;
char hlocal[256], nlocal[256];
unsigned char *packet;
int len = 0;
xht_t *h;
char *path = NULL;
if (argc < 4) {
printf("usage: mhttp 'unique name' 12.34.56.78 80 '/optionalpath'\n");
return 1;
}
INET_PTON(AF_INET,argv[2], &ip);
port = atoi(argv[3]);
if (argc == 5)
path = argv[4];
printf("Announcing .local site named '%s' to %s:%d and extra path '%s'\n", argv[1], inet_ntoa(ip), port, argv[4]);
signal(SIGINT, done);
#ifdef SIGHUP
signal(SIGHUP, done);
#endif
#ifdef SIGQUIT
signal(SIGQUIT, done);
#endif
signal(SIGTERM, done);
_d = d = mdnsd_new(QCLASS_IN, 1000);
if ((s = msock()) == 0) {
printf("can't create socket: %s\n", strerror(errno));
return 1;
}
mdnsd_register_receive_callback(d, record_received, NULL);
sprintf(hlocal, "%s._http._tcp.local.", argv[1]);
sprintf(nlocal, "http-%s.local.", argv[1]);
// Announce that we have a _http._tcp service
r = mdnsd_shared(d, "_services._dns-sd._udp.local.", QTYPE_PTR, 120);
mdnsd_set_host(d, r, "_http._tcp.local.");
r = mdnsd_shared(d, "_http._tcp.local.", QTYPE_PTR, 120);
mdnsd_set_host(d, r, hlocal);
r = mdnsd_unique(d, hlocal, QTYPE_SRV, 600, conflict, 0);
mdnsd_set_srv(d, r, 0, 0, port, nlocal);
r = mdnsd_unique(d, nlocal, QTYPE_A, 600, conflict, 0);
mdnsd_set_raw(d, r, (char *)&ip.s_addr, 4);
r = mdnsd_unique(d, hlocal, QTYPE_TXT, 600, conflict, 0);
h = xht_new(11);
if (path && strlen(path))
xht_set(h, "path", path);
packet = sd2txt(h, &len);
xht_free(h);
mdnsd_set_raw(d, r, (char *)packet, len);
MDNSD_free(packet);
// example for getting a previously published record:
{
mdns_record_t *get_r = mdnsd_get_published(d, "_http._tcp.local.");
while(get_r) {
const mdns_answer_t *data = mdnsd_record_data(get_r);
printf("Found record of type %d\n", data->type);
get_r = mdnsd_record_next(get_r);
}
}
{
struct timeval next_sleep;
next_sleep.tv_sec = 0;
next_sleep.tv_usec = 0;
while (1) {
FD_ZERO(&fds);
FD_SET(s, &fds);
select(s + 1, &fds, 0, 0, &next_sleep);
if (_shutdown)
break;
{
unsigned short retVal = mdnsd_step(d, s, FD_ISSET(s, &fds), true, &next_sleep);
if (retVal == 1) {
printf("can't read from socket %d: %s\n", errno, strerror(errno));
break;
} else if (retVal == 2) {
printf("can't write to socket: %s\n", strerror(errno));
break;
}
}
if (_shutdown)
break;
}
}
mdnsd_shutdown(d);
mdnsd_free(d);
return 0;
}

View File

@ -0,0 +1,3 @@
include("${CMAKE_CURRENT_LIST_DIR}/mdnsdTargets.cmake")
@PACKAGE_INIT@

166
deps/mdnsd/mdnsd_back/mquery.c vendored Normal file
View File

@ -0,0 +1,166 @@
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <libmdnsd/mdnsd.h>
#ifdef _WIN32
# define CLOSESOCKET(S) closesocket((SOCKET)S)
# define ssize_t int
#else
# include <unistd.h> // read, write, close
# define CLOSESOCKET(S) close(S)
#endif
/* Print an answer */
int ans(mdns_answer_t *a, void *arg)
{
int now;
if (a->ttl == 0)
now = 0;
else
now = (int)(a->ttl - (unsigned long)time(0));
switch (a->type) {
case QTYPE_A:
printf("A %s for %d seconds to ip %s\n", a->name, now, inet_ntoa(a->ip));
break;
case QTYPE_PTR:
printf("PTR %s for %d seconds to %s\n", a->name, now, a->rdname);
break;
case QTYPE_SRV:
printf("SRV %s for %d seconds to %s:%hu\n", a->name, now, a->rdname, a->srv.port);
break;
default:
printf("%hu %s for %d seconds with %hu data\n", a->type, a->name, now, a->rdlen);
}
return 0;
}
static void socket_set_nonblocking(int sockfd) {
#ifdef _WIN32
u_long iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);
#else
int opts = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, opts|O_NONBLOCK);
#endif
}
/* Create multicast 224.0.0.251:5353 socket */
int msock(void)
{
int s, flag = 1, ittl = 255;
struct sockaddr_in in;
struct ip_mreq mc;
char ttl = (char) 255;
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
in.sin_port = htons(5353);
in.sin_addr.s_addr = 0;
if ((s = (int)socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 0;
#ifdef SO_REUSEPORT
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
#endif
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
if (bind(s, (struct sockaddr *)&in, sizeof(in))) {
CLOSESOCKET(s);
return 0;
}
mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
mc.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mc, sizeof(mc));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ttl, sizeof(ttl));
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&ittl, sizeof(ittl));
socket_set_nonblocking(s);
return s;
}
int main(int argc, char *argv[])
{
mdns_daemon_t *d;
struct message m;
struct in_addr ip;
unsigned short int port;
ssize_t bsize;
socklen_t ssize;
unsigned char buf[MAX_PACKET_LEN];
struct sockaddr_in from, to;
fd_set fds;
int s;
if (argc != 3) {
printf("usage: mquery 12 _http._tcp.local.\n");
return 1;
}
d = mdnsd_new(1, 1000);
if ((s = msock()) == 0) {
printf("can't create socket: %s\n", strerror(errno));
return 1;
}
mdnsd_query(d, argv[2], atoi(argv[1]), ans, 0);
while (1) {
struct timeval *tv = mdnsd_sleep(d);
FD_ZERO(&fds);
FD_SET(s, &fds);
select(s + 1, &fds, 0, 0, tv);
if (FD_ISSET(s, &fds)) {
ssize = sizeof(struct sockaddr_in);
while ((bsize = recvfrom(s, buf, MAX_PACKET_LEN, 0, (struct sockaddr *)&from, &ssize)) > 0) {
memset(&m, 0, sizeof(struct message));
if (!message_parse(&m, buf, bsize))
continue;
mdnsd_in(d, &m, (unsigned long int)from.sin_addr.s_addr, from.sin_port);
}
if (bsize < 0 && errno != EAGAIN) {
printf("can't read from socket %d: %s\n", errno, strerror(errno));
return 1;
}
}
while (mdnsd_out(d, &m, &ip, &port)) {
memset(&to, 0, sizeof(to));
to.sin_family = AF_INET;
to.sin_port = port;
to.sin_addr.s_addr = ip.s_addr;
if (sendto(s, message_packet(&m), message_packet_len(&m), 0, (struct sockaddr *)&to,
sizeof(struct sockaddr_in)) != message_packet_len(&m)) {
printf("can't write to socket: %s\n", strerror(errno));
return 1;
}
}
}
mdnsd_shutdown(d);
mdnsd_free(d);
return 0;
}

View File

@ -0,0 +1,50 @@
if (NOT MDNSD_BUILD_OSS_FUZZ)
if(NOT "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
MESSAGE(FATAL_ERROR "To build fuzzing, you need to use Clang as the compiler")
endif()
# oss-fuzz builds already include these flags
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1 -fsanitize=address")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
endif()
set(LIBS Fuzzer)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
else()
set(LIBS $ENV{LIB_FUZZING_ENGINE})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $ENV{OUT})
endif()
list(APPEND LIBS libmdnsd)
set(FUZZER_TARGETS)
macro(add_fuzzer FUZZER_NAME FUZZER_SOURCE)
add_executable(${FUZZER_NAME} ${FUZZER_SOURCE} ${ARGN})
target_link_libraries(${FUZZER_NAME} ${LIBS})
list(APPEND FUZZER_TARGETS ${FUZZER_NAME})
endmacro()
# Add new fuzzers here
add_fuzzer(fuzz_mdns_message fuzz_mdns_message.cc)
# We cannot run this fuzzer on oss-fuzz, since its coverage is too small
if (NOT MDNSD_BUILD_OSS_FUZZ)
add_fuzzer(fuzz_mdns_xht fuzz_mdns_xht.cc)
endif()
SET(CORPUS_CMDS "")
FOREACH(f ${CORPUS_FILES})
LIST(APPEND CORPUS_CMDS COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/fuzz_mdns_message "${f}")
ENDFOREACH(f)
add_custom_target(run_fuzzer ${CORPUS_CMDS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${FUZZER_TARGETS}
${MAYBE_USES_TERMINAL})

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e
git clone https://github.com/Pro/oss-fuzz -bmdnsd $HOME/oss-fuzz
python $HOME/oss-fuzz/infra/helper.py build_fuzzers --sanitizer address mdnsd $TRAVIS_BUILD_DIR && python $HOME/oss-fuzz/infra/helper.py check_build --sanitizer address mdnsd

View File

@ -0,0 +1,65 @@
/* This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> */
#include <cstdint>
#include <cstdio>
#include <libmdnsd/mdnsd.h>
#include <cstring>
#include <cstdlib>
/*
** Main entry point. The fuzzer invokes this function with each
** fuzzed input.
*/
extern "C" int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
struct message m;
memset(&m, 0, sizeof(struct message));
unsigned char *dataCopy = (unsigned char *)malloc(size);
if (!dataCopy) {
return 0;
}
memcpy(dataCopy, data, size);
bool success = message_parse(&m, dataCopy, size);
free(dataCopy);
if (!success)
return 0;
mdns_daemon_t *d = mdnsd_new(QCLASS_IN, 1000);
in_addr_t addr = 0;
mdnsd_in(d, &m, addr, 2000);
mdnsd_free(d);
return 0;
}

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